Skip to content

Device State Changed Event

device.state.changed is sent when device IO state changes.

Topic

text
device.state.changed

Event — Triggered by Remote Control

When triggered by an API command, reason is remoteControl and correlationId is the request requestId that caused the change.

json
{
  "type": "event",
  "topic": "device.state.changed",
  "data": {
    "deviceId": "abc123456789",
    "occurredAt": "2026-04-03T00:41:44Z",
    "reason": "remoteControl",
    "correlationId": "req_op_001",
    "peripherals": {
      "relays": [
        {
          "index": 1,
          "on": true
        },
        {
          "index": 2,
          "on": false
        },
        {
          "index": 3,
          "on": false
        },
        {
          "index": 4,
          "on": false
        }
      ],
      "digitalInputs": [
        {
          "index": 1,
          "active": false
        },
        {
          "index": 2,
          "active": false
        },
        {
          "index": 3,
          "active": false
        },
        {
          "index": 4,
          "active": false
        }
      ],
      "sensors": [
        {
          "index": 1,
          "type": "TEMP",
          "value": 30.4,
          "unit": "C",
          "status": "ONLINE"
        },
        {
          "index": 2,
          "type": "TEMP",
          "value": 32.6,
          "unit": "C",
          "status": "ONLINE"
        },
        {
          "index": 2,
          "type": "HUMI",
          "value": 54,
          "unit": "%",
          "status": "ONLINE"
        }
      ]
    },
    "stateUpdatedAt": "2026-04-03T00:41:44Z"
  }
}

Event — Triggered on the Device Side

When triggered locally by the device, reason is localChange and correlationId is not included.

json
{
  "type": "event",
  "topic": "device.state.changed",
  "data": {
    "deviceId": "abc123456789",
    "occurredAt": "2026-04-03T00:41:44Z",
    "reason": "localChange",
    "peripherals": {
      "relays": [
        {
          "index": 1,
          "on": false
        },
        {
          "index": 2,
          "on": false
        },
        {
          "index": 3,
          "on": false
        },
        {
          "index": 4,
          "on": false
        }
      ],
      "digitalInputs": [
        {
          "index": 1,
          "active": false
        },
        {
          "index": 2,
          "active": false
        },
        {
          "index": 3,
          "active": false
        },
        {
          "index": 4,
          "active": false
        }
      ],
      "sensors": [
        {
          "index": 1,
          "type": "TEMP",
          "value": 30.4,
          "unit": "C",
          "status": "ONLINE"
        },
        {
          "index": 2,
          "type": "TEMP",
          "value": 32.6,
          "unit": "C",
          "status": "ONLINE"
        },
        {
          "index": 2,
          "type": "HUMI",
          "value": 54,
          "unit": "%",
          "status": "ONLINE"
        }
      ]
    },
    "stateUpdatedAt": "2026-04-03T00:41:44Z"
  }
}

data Schema

FieldTypeRequiredDescription
deviceIdstringYesUnique device identifier
occurredAtstringYesEvent time in RFC3339 UTC
reasonstringNoReason for the state change. See the table below
correlationIdstringNoRelated request ID. Present only when reason=remoteControl
peripheralsobjectYesComplete peripheral state data
stateUpdatedAtstringYesDevice state update time in RFC3339 UTC

reason Enum

ValueTrigger ScenariocorrelationId
remoteControlTriggered by an API command (device.operation.execute or a REST relay command)The corresponding request requestId
localChangeTriggered on the device side. Due to firmware limitations, the precise local source is unknown; it may be a panel button, a digital input, or another local hardware eventNot present

Rules

  • data.peripherals reuses the peripherals schema from REST device detail responses
  • data.peripherals is complete peripheral state data, not an incremental diff
  • Clients should replace the current device hardware state with the full block from the event
  • The reason field may be missing. If it is missing, clients should not assume a trigger source
Docs buildVersion v1.2.19-20260602-174859-60
Copyright © 2026 WLTE