LG ThinQ API control devices
I’m fortunate enough to have air conditioning units installed at my house. It was one of the first things I had
installed when I moved in, as coming from my previous super-warm flat, it was pretty horrible in summer just relying
on fans to blow some hot air around.
When I think of air conditioners, I think of cooling a room, not heating it. However, the great thing about these air
conditioners is that they also blow hot air.
During the recent cold spell in the UK, my heating bill has been extortionate, as it’s currently heated by gas. Even keeping the house at 18 degrees maximum in the morning has cost me a fair bit. So when I’ve been working in my office, I’ve kept my door closed and have been putting the air conditioning on to get it up to a reasonable temperature. However, one of the issues I’ve found is that no matter what temperature I set it on, for example, 21 degrees, the air conditioner keeps heating until I turn it off. I’ve been manually doing this via the remote control or the LG App on my phone. But, as an engineer, I know there must be a better way to do this.
Enter the LG API!
There are two different places I’ve found for LG ThinQ documentation
- https://smartsolution.developer.lge.com/en/apiManage/thinq_connect
- https://thinq.developer.lge.com/en/cloud/docs/thinq-connect/api-reference/device-api/
I’ve found that the 1st one is the more accurate and up-to-date documentation - and even that isn’t particularly helpful or easy to understand. I think the 2nd link must be old documentation.
My objectives
- To turn on the air con, when the temperature is below 20 degrees
- To turn off the air con, when the temperature is above 20 degrees
- To retain control of the script, so only when I run it, the above will work
So, what did I end up with? (click here to see full script and skip breakdown)
The breakdown
First off, lets setup some basic variables
1
2
3
4
5
6
7
8
9
import requests
import time
ACCESS_TOKEN = "your_pat_here"
DEVICE_ID = "1234"
API_BASE_URL = "https://api-eic.lgthinq.com/" # You may need to change this - see the API docs
TEMP_THRESHOLD = 20 # Celsius
CHECK_INTERVAL = 300 # 5 minutes in seconds
- ACCESS_TOKEN: can be generated from here - there’s also a link on the API documentation
- DEVICE_ID: this is the device we’ll be controlling - but we can leave that as is for now, as we’ll be calling the API first to get the ID
- API_BASE_URL: I’m in the UK, so my base URL is the Europe one. See the docs for other base URLs
Now we have that, let’s get the list of available devices (note: the x-api-key, x-message-id etc I don’t think are used, so anything is ok here? I’ve taken these values straight from the documentation.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def headers():
return {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"x-api-key": "v6GFvkweNo7DK7yD3ylIZ9w52aKBU0eJ7wLXkSR3",
"x-country": "GB",
"x-message-id": "fNvdZ1brTn-wWKUlWGoSVw",
"x-client-id": "test-client-123456"
}
def list_devices():
url = f"{API_BASE_URL}devices"
response = requests.get(url, headers=headers())
response.raise_for_status()
print(response.status_code)
print(response.json())
devices = response.json().get("response", [])
print("Available Devices:")
for device in devices:
print(f"ID: {device.get('deviceId')}, Name: {device.get('deviceInfo')['alias']}, Type: {device.get('deviceInfo')['deviceType']}")
return devices
Once you have found the device ID you want to control, you can update the DEVICE_ID
above.
The script below is for heating a room, so if you wanted to cool a room instead, you’d have to flip the logic around
the current_temp
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def get_device_status(device_id):
url = f"{API_BASE_URL}devices/{device_id}/state"
response = requests.get(url, headers=headers())
response.raise_for_status()
return response.json()['response']
def set_device_operation(device_id, operation_mode):
url = f"{API_BASE_URL}devices/{device_id}/control"
payload = {
"operation": {'airConOperationMode': operation_mode } # "on" or "off"
}
response = requests.post(url, headers=headers(), json=payload)
response.raise_for_status()
return response.json()
def control_aircon():
while True:
try:
# Get the current status of the air conditioner
status = get_device_status(DEVICE_ID)
# print(status)
# exit(1)
current_temp = status.get("temperature")['currentTemperature']
ac_power_state = status.get("operation")['airConOperationMode']
print(f"Current room temperature: {current_temp}°C")
print(f"AC power state: {ac_power_state}")
print(f"Threshold: {TEMP_THRESHOLD}")
if current_temp > TEMP_THRESHOLD and ac_power_state == "POWER_ON":
print("Temperature is above the threshold. Turning off the air conditioner.")
set_device_operation(DEVICE_ID, "POWER_OFF")
elif current_temp < TEMP_THRESHOLD and ac_power_state == "POWER_OFF":
print("Temperature is below the threshold. Turning on the air conditioner.")
set_device_operation(DEVICE_ID, "POWER_ON")
for remaining in range(CHECK_INTERVAL, 0, -1):
print(f"\rWaiting {remaining} seconds...", end="")
time.sleep(1)
except Exception as e:
print(f"An error occurred: {e}")
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
control_aircon()
# list_devices()
Full script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import requests
import time
# LG ThinQ API credentials
ACCESS_TOKEN = "your_pat_here"
DEVICE_ID = "1234"
API_BASE_URL = "https://api-eic.lgthinq.com/" # You may need to change this - see the API docs
# Threshold temperature
TEMP_THRESHOLD = 20 # Celsius
CHECK_INTERVAL = 300 # 5 minutes in seconds
def headers():
return {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"x-api-key": "v6GFvkweNo7DK7yD3ylIZ9w52aKBU0eJ7wLXkSR3",
"x-country": "GB",
"x-message-id": "fNvdZ1brTn-wWKUlWGoSVw",
"x-client-id": "test-client-123456"
}
def list_devices():
url = f"{API_BASE_URL}devices"
response = requests.get(url, headers=headers())
response.raise_for_status()
print(response.status_code)
print(response.json())
devices = response.json().get("response", [])
print("Available Devices:")
for device in devices:
print(f"ID: {device.get('deviceId')}, Name: {device.get('deviceInfo')['alias']}, Type: {device.get('deviceInfo')['deviceType']}")
return devices
def get_device_status(device_id):
url = f"{API_BASE_URL}devices/{device_id}/state"
response = requests.get(url, headers=headers())
response.raise_for_status()
return response.json()['response']
def set_device_operation(device_id, operation_mode):
url = f"{API_BASE_URL}devices/{device_id}/control"
payload = {
"operation": {'airConOperationMode': operation_mode } # "on" or "off"
}
response = requests.post(url, headers=headers(), json=payload)
response.raise_for_status()
return response.json()
def control_aircon():
while True:
try:
# Get the current status of the air conditioner
status = get_device_status(DEVICE_ID)
# print(status)
# exit(1)
current_temp = status.get("temperature")['currentTemperature']
ac_power_state = status.get("operation")['airConOperationMode']
print(f"Current room temperature: {current_temp}°C")
print(f"AC power state: {ac_power_state}")
print(f"Threshold: {TEMP_THRESHOLD}")
if current_temp > TEMP_THRESHOLD and ac_power_state == "POWER_ON":
print("Temperature is above the threshold. Turning off the air conditioner.")
set_device_operation(DEVICE_ID, "POWER_OFF")
elif current_temp < TEMP_THRESHOLD and ac_power_state == "POWER_OFF":
print("Temperature is below the threshold. Turning on the air conditioner.")
set_device_operation(DEVICE_ID, "POWER_ON")
for remaining in range(CHECK_INTERVAL, 0, -1):
print(f"\rWaiting {remaining} seconds...", end="")
time.sleep(1)
except Exception as e:
print(f"An error occurred: {e}")
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
control_aircon()
# list_devices()