Skip to main content

LG ThinQ Connect

GEM driver for LG air conditioners and heat pumps through ThinQ Connect, LG's official open API. Authentication is a Personal Access Token (PAT) issued from LG's developer portal — no OAuth redirect to complete, no LG password stored on the controller.

This closes the LG gap in GEM's HVAC coverage. LG single-zone mini-splits, Art Cool units and Multi F systems with a Wi-Fi module were previously only reachable through a third-party gateway such as Intesis; this talks to them directly.

Feature coverage:

  • Power on/off, target temperature, operating mode and fan speed on air conditioners
  • Polled read of current temperature, target temperature, mode, fan speed, humidity where reported
  • Discovery of every appliance on the LG account with its deviceId, type and alias
  • set_property passthrough so non-AC ThinQ appliances on the same account (washers, dryers, air purifiers, dehumidifiers) can still be driven from a macro
info

This is a cloud integration. LG publishes no local control path for ThinQ appliances, so the units go offline in GEM during an internet outage or an LG service incident. Where a site needs local-only climate control, an Intesis WMP gateway on the indoor unit is the alternative — see Intesis WMP.

Prerequisites

  • The appliances already registered and working in the LG ThinQ mobile app. This driver reads an existing account; it cannot onboard hardware or join a unit to Wi-Fi.
  • A Wi-Fi module fitted to each indoor unit. Many LG mini-splits ship without one — it is a separate part (PWFMDD200 or the model-specific equivalent) and on some models it must be installed by the dealer.
  • A Personal Access Token created at connect-pat.lgthinq.com, with the device scopes enabled for each appliance GEM should see.
  • Outbound HTTPS from the GEM host to api-<region>.lgthinq.com.

Setup steps

  1. Create the token. Sign in at connect-pat.lgthinq.com with the LG account that owns the appliances. Create a Personal Access Token and tick the scopes for each device you want GEM to read and control. A token issued before an appliance was added to the account will not see that appliance — regenerate it after adding hardware.

  2. Add the device. On Devices, create a device with driver lg_thinq and set:

    • token — the PAT (stored encrypted)
    • country — the two-letter country code of the LG account, not necessarily the site's country
  3. Leave region empty to start. It is derived from country: kic for Korea, aic for the Americas, eic everywhere else. Only set it explicitly if discovery comes back empty on a token you know is good.

  4. Discover the appliances. From the Script Console, run the device's get_devices command. Each entry returns a device_id, device_type, alias and model.

  5. Create zones. Add one zone per appliance with the zone address set to that device_id — the long opaque string, not the nickname you gave it in the LG app.

  6. Confirm state. Run get_status. Each zone should come back with the values the driver read; those same values land on the zone as attributes.

Attribute reference

Device attributes

AttributeRequiredDefaultPurpose
tokenyesPersonal Access Token from connect-pat.lgthinq.com. Stored encrypted.
countryyesUSTwo-letter country code of the LG account, sent as x-country. Must match the account.
regionnoderivedRegional endpoint: aic, eic or kic. Derived from country when empty.
api_basenoFull endpoint override (https://api-aic.lgthinq.com). Wins over region.
api_keynopublished keySent as x-api-key. Override only if LG rotates the published client key.
client_idnogem-<device id>Sent as x-client-id. Stable across restarts by default. Set it only to distinguish two GEM controllers on one LG account.
status_intervalno60000Poll interval in milliseconds. Do not go below 30000 on an account with several appliances — the API is rate limited.
request_timeoutno15000Per-request timeout in milliseconds.

Attributes the driver writes

On each zone: state (on/off), temperature (current), setpoint (target), system_mode, fan_mode, temperature_unit, and humidity where the appliance reports it. Values are written only when they change.

Zone address format

The zone address is the ThinQ deviceId exactly as get_devices returns it. It is an opaque identifier, not the appliance alias, and it does not change when you rename the unit in the LG app.

Commands

CommandArgumentsNotes
get_devicesLists the account's appliances. Run this first.
get_device_stateaddressRaw state document for one appliance.
get_device_profileaddressWhich resources and properties this model exposes. This is where you find names for set_property.
on / offaddressSets operation.airConOperationMode.
set_temperatureaddress, levelTarget temperature in the appliance's own unit.
set_modeaddress, modecool, heat, auto, fan, dry / air_dry, air_clean, or a raw ThinQ job mode.
set_fan_modeaddress, fan_modelow, mid, high, auto (also slow, power), or a raw ThinQ wind strength.
set_propertyaddress, resource, property, valueGeneric control write for appliance types this driver does not model.
get_statusPolls every zone now and returns what was read.

Driving a non-AC appliance

The API keys every control write by resource group, and the groups differ per appliance type. Rather than half-modelling a washer, the driver exposes the raw write. Read the group and property names from get_device_profile, then:

set_property address=<deviceId> resource=operation property=<propertyName> value=<value>

Known limitations

  • Cloud only, polled only. Push events (event/{id}/subscribe) are not wired up, so a change made at the wall unit or in the LG app takes up to one status_interval to show in GEM.
  • Only the air-conditioner surface is modelled. Power, setpoint, job mode and fan speed. Swing/vane direction, timers, sleep mode, power-save and filter life are readable through get_device_state but are not mapped onto attributes or commands.
  • Modes are per-model. A unit with no dry mode returns an API error for AIR_DRY rather than ignoring it. Check get_device_profile before wiring a mode into a macro.
  • Two-setpoint (auto) mode is not exposed. Profiles that use twoSetTemperature for a heat/cool deadband are readable but set_temperature writes the single targetTemperature only.
  • No account onboarding. Adding hardware, joining Wi-Fi and naming units all happen in the LG app.

Troubleshooting

SymptomCheck
get_devices returns an empty list on a token you know is validcountry and region disagree with the account. Confirm country matches the LG account's region, then set region explicitly (aic / eic / kic).
Every request returns 401 or 403The PAT expired or lacks scope for the device. Regenerate it and re-enable the device scopes.
One appliance is missing from get_devicesIt is not registered to this LG account, has no Wi-Fi module, or was added after the token was issued.
set_temperature returns an API errorThe unit is off, or is in a mode with no setpoint (fan, air clean). Power it on and set a heating or cooling mode first.
Commands succeed but GEM state does not moveState is polled, not pushed. Wait one status_interval, or call get_device_state to confirm the appliance actually changed.
Errors appear under load with several appliancesLG rate-limits the API. Raise status_interval; the driver paces its own polling but many zones on a short interval will still trip it.

Protocol notes

Requests go to https://api-<region>.lgthinq.com/<path> with these headers:

HeaderValue
authorizationBearer <PAT>
x-countryTwo-letter country code
x-message-idFresh base64url token per request
x-client-idStable client identifier
x-api-keyPublished ThinQ Connect client key
x-service-phaseOP
x-conditional-controltrue, on control writes only

Paths used: GET devices, GET devices/{id}/profile, GET devices/{id}/state, POST devices/{id}/control. Control bodies are {"<resource>": {"<property>": <value>}} — for example {"operation": {"airConOperationMode": "POWER_ON"}}.

Responses are wrapped as {"messageId": ..., "timestamp": ..., "response": {...}}; errors arrive as {"error": {"code": ..., "message": ...}} and are surfaced to the caller rather than retried.

The TLS certificate is fully verified on every call. GEM tolerates self-signed certificates on LAN devices, but the ThinQ endpoints are public hosts presenting a publicly-trusted chain, and every request carries the account-wide PAT — so a certificate error here is not something to work around. It means the connection is being intercepted; find the TLS-inspecting proxy or firewall instead.