Message Format
All WebSocket text messages use JSON.
Message semantics are distinguished by type and topic:
| type | Direction | Description |
|---|---|---|
request | Client to server | The client sends one request |
reply | Server to client | The server replies to one request |
event | Server to client | The server pushes an event |
Request
json
{
"type": "request",
"requestId": "req_status_001",
"topic": "device.status.get",
"data": {
"deviceId": "abc123456789"
}
}Field descriptions:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Fixed as request |
requestId | string | Yes | Client-generated request ID. It should be unique within one connection |
topic | string | Yes | Request topic |
data | object | Yes | Request data |
Success Reply
json
{
"type": "reply",
"requestId": "req_status_001",
"topic": "device.status.get",
"success": true,
"data": {
"deviceId": "abc123456789",
"name": "YourDeviceName",
"deviceType": "SM4_T_TH",
"status": "ONLINE",
"peripherals": {
"relays": [
{
"index": 1,
"on": false
},
{
"index": 2,
"on": false
},
{
"index": 3,
"on": true
},
{
"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"
}
}Error Reply
json
{
"type": "reply",
"requestId": "req_op_001",
"topic": "device.operation.execute",
"success": false,
"error": {
"code": "COMMAND_REJECTED",
"message": "Command was rejected."
}
}Field descriptions:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Fixed as reply |
requestId | string | Yes | The requestId of the original request |
topic | string | Yes | The topic of the original request |
success | boolean | Yes | Whether the request was processed successfully |
data | object | Returned on success | Response data |
error | object | Returned on failure | Error details |
error.code | string | Returned on failure | Error code |
error.message | string | Returned on failure | Human-readable description for display, logs, and troubleshooting only |
Event
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": false
},
{
"index": 2,
"on": false
},
{
"index": 3,
"on": true
},
{
"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"
}
}Field descriptions:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Fixed as event |
topic | string | Yes | Event topic |
data | object | Yes | Event data |
For detailed peripheral state field definitions, see Peripheral State Reference.
Naming Rules
typeonly usesrequest,reply, andeventtopicuses lowercase English words separated by dots, for exampledevice.status.getrequestIdis generated by the client and may use a business ID, UUID, or a short prefixed ID- Time fields use RFC3339 UTC strings
- JSON fields use camelCase
- Clients should ignore newly added fields they do not recognize yet
