Daikin Skyport (One+ Cloud)
GEM controls Daikin One+ smart thermostats — and any other thermostat that registers to the Daikin One Home / Skyport cloud — through the public api.daikinskyport.com REST endpoint. One GEM device represents one Daikin account; each registered thermostat appears as a zone underneath it.
Prerequisites
- A Daikin One Home (Skyport) account with at least one registered thermostat.
- Outbound HTTPS (port 443) from the GEM server to
api.daikinskyport.com. - The thermostat is fully commissioned in the Daikin One Home mobile app.
If you can sign into the mobile app and see the thermostat, the driver will be able to reach it.
Setup
- Add a new device of type Daikin Skyport (One+ Cloud) under System → Devices.
- Set:
- Daikin One Account Email — same email used to sign into the Daikin One Home app.
- Daikin One Account Password — same password (stored encrypted as a secure attribute).
- Save and reload. After connect, run the
get_devicescommand from System → Commands (or the Script Console) to enumerate thermostats; the response is an array of{id, name, locationId, …}. - For each thermostat, create a zone:
- Address = the Daikin device id (UUID-style string from
get_devices). - Subsystem = HVAC (or Climate).
- Address = the Daikin device id (UUID-style string from
The driver begins polling each zone every 30 seconds (configurable via status_interval) and surfaces the standard climate attributes: temperature, humidity, cool_setpoint, heat_setpoint, system_mode, fan_mode.
Attribute reference
Device attributes
| Attribute | Required | Type | Default | Notes |
|---|---|---|---|---|
username | yes | string | — | Daikin One Home account email |
password | yes | string (secure) | — | Daikin One Home account password |
status_interval | no | int | 30000 | Poll interval in ms. Blank, zero, negative or unparseable values use 30000; values below 1000 poll every 1000 ms. |
Zone attributes
| Attribute | Required | Type | Notes |
|---|---|---|---|
address | yes | string | Daikin device id from get_devices |
min | no | int | Optional lower clamp on outbound setpoints |
max | no | int | Optional upper clamp on outbound setpoints |
The driver auto-publishes system_modes and fan_modes JSON attributes onto each zone so the admin UI can render the right pickers.
Commands
| Command | Args | Notes |
|---|---|---|
setpoint | address, setpoint, mode (heat/cool) | Writes hspHome (heat) or cspHome (cool). If mode is omitted, the driver picks based on the zone's current system_mode and rejects the command if the thermostat is off/auto. The setpoint is sent as a whole number (a decimal is truncated) and is refused when it is not a number or falls outside the zone min/max. |
system_mode | address, mode (off / heat / cool / auto / emergency_heat) | Maps to Skyport mode codes 0-4. |
fan_mode | address, mode (auto / on / schedule) | Maps to Skyport fan codes 0-2. |
get_devices | — | Returns the raw /devices response for zone-address discovery. |
Auth model
Skyport issues a short-lived accessToken (TTL ~1 hour) plus a longer-lived refreshToken. The driver:
- POSTs
{email, password}to/users/auth/loginto mint both tokens. - Refreshes proactively ~60 seconds before the access token expires.
- On a
401/403mid-flight, re-logs in once and retries the request. When several requests need a new token at the same moment (a poll and a command, or several thermostats), they share a single login instead of each starting their own. - If Skyport refuses a login (wrong password, or its own rate limit), the driver waits before logging in again: 30 seconds after the first refusal, doubling up to 5 minutes. Commands sent during that wait return the login error straight away without contacting Skyport. Changing the password and reloading the device clears the wait.
Tokens are held in memory only — they are not persisted across restarts.
Connection and polling behaviour
- Connect retries. If Skyport cannot be reached or refuses the login when the device starts, the driver tries again after 30 seconds, doubling up to 5 minutes, so a site that boots during an internet outage recovers on its own.
- Connection state. The device shows connected once Skyport has answered a request with data. A refused login or a Skyport server error no longer shows the device as connected; a request that cannot reach Skyport at all marks it disconnected.
- Polling a dead cloud. When every thermostat fails to read for three polls in a row (Skyport unreachable, server errors, or a refused login), the poll interval doubles each time up to 5 minutes. The first successful read returns to the normal interval. A single thermostat that Skyport does not recognise (for example a mistyped zone address) does not slow polling for the others; its read error is logged once while it keeps failing.
- Zone addresses. Leading and trailing spaces in a zone address are ignored. A zone whose address is blank or still holds an unfilled
[@zone.address]placeholder is skipped by polling, and commands to it are refused.
Known limitations
- Cloud only. This driver does not speak the Daikin One Local API (the integrator-token API on port 30050). That is a separate driver and is not covered here.
- No schedule editing. Schedule and vacation-hold writes are not yet implemented; the thermostat will revert temporary setpoints at the next schedule edge.
- No multi-stage detail.
modeis the canonical surface; auxiliary heat strip / dehumidify-only / equipment runtime detail is not yet exposed. - Setpoint accepted but reverts. Almost always means a schedule is overriding the manual change. Either set a hold on the thermostat or disable the schedule.
Troubleshooting
| Symptom | Likely cause |
|---|---|
login failed on first connect | Bad email/password, or Skyport rate-limited the IP after repeated failures. Wait a few minutes and retry. |
Empty /devices list | Account exists but has no registered thermostats — finish onboarding in the mobile app first. |
| Setpoint accepted but reverts in minutes | An active schedule or vacation hold is overriding manual setpoints. |
| Sporadic 401 storms after server resume | Expected on long suspends; the driver will re-login on the next poll. |
Commands fail immediately with login failed | Skyport refused the last login and the driver is waiting before trying again (up to 5 minutes). Correct the password and reload the device to retry at once. |
Wire format reference
Roughly what the driver does on the wire (sensitive fields redacted):
POST /users/auth/login
{ "email": "owner@example.com", "password": "REDACTED" }
→ { "accessToken": "...", "refreshToken": "...", "accessTokenExpiresIn": "3600" }
GET /devices Authorization: Bearer <accessToken>
GET /deviceData/<device_id> Authorization: Bearer <accessToken>
PUT /deviceData/<device_id> Authorization: Bearer <accessToken>
{ "mode": 2, "cspHome": 74 }