WebSocket Protocol
Reference guide for connecting IoT devices and access control hardware.
Endpoint
ws://<your-host>/wsAll clients (devices and admin dashboards) connect to the same endpoint. The server differentiates roles based on the first message sent.
Client → Server Messages
register
// Device sends on connect to authenticate
{ "type": "register", "device_id": "<UUID>", "token": "tok_your_secret_token" }telemetry
// Device pushes sensor readings
{ "type": "telemetry", "device_id": "<UUID>", "payload": { "temperature": 23.5, "humidity": 61 } }event
// Device reports lifecycle events
{ "type": "event", "device_id": "<UUID>", "event_type": "door_opened", "payload": {} }ping
// Heartbeat — server replies with { "type": "pong" }
{ "type": "ping" }subscribe
// Admin dashboard joins broadcast group
{ "type": "subscribe", "role": "admin" }command
// Admin sends a command to a device
{ "type": "command", "device_id": "<UUID>", "command": "unlock", "payload": {} }Server → Client Messages
registeredSent to device after successful registration
pongHeartbeat reply to ping
device_statusBroadcast to admins when a device goes online/offline
telemetryBroadcast to admins when a device pushes telemetry
eventBroadcast to admins when a device emits an event
commandSent to device when an admin issues a command
errorSent when authentication fails or message is malformed
XML Protocol (Biometric / Access Control)
SmackBio/ZK-compatible biometric devices can connect using XML messages. The server auto-detects XML vs JSON.
register
<!-- Biometric device registers on connect -->
<Request>
<Operation>Register</Operation>
<DeviceSerialNo>FK628001</DeviceSerialNo>
<CloudId>cloud_001</CloudId>
</Request>
<!-- Server responds with session token -->
<Response>
<Result>success</Result>
<Session>sess_1234567890_abc123</Session>
<DeviceSerialNo>FK628001</DeviceSerialNo>
</Response>timelog
<!-- Device sends attendance punch (TimeLog_v2) -->
<Request>
<Operation>TimeLog_v2</Operation>
<LogId>LOG001</LogId>
<UserId>EMP123</UserId>
<PunchTime>2026-05-12T09:15:30</PunchTime>
<GMT>8</GMT>
<AttendStat>0</AttendStat>
<APStat>1</APStat>
<Action>FP</Action>
<JobCode>0</JobCode>
<Photo>base64_encoded_photo...</Photo>
<Latitude>40.7128</Latitude>
<Longitude>-74.0060</Longitude>
</Request>adminlog
<!-- Device sends admin action (AdminLog_v2) -->
<Request>
<Operation>AdminLog_v2</Operation>
<LogId>ADMIN001</LogId>
<AdminId>ADMIN</AdminId>
<UserId>EMP456</UserId>
<Action>EnrollFP</Action>
<Time>2026-05-12T10:30:00</Time>
</Request>keepalive
<!-- Heartbeat to keep connection alive -->
<Request>
<Operation>KeepAlive</Operation>
</Request>HTTP/HTTPS Protocol (CloudSolution 3.0)
Devices that don't support WebSocket (legacy networks, HTTP-only firmware) can use HTTP POST requests. Every request gets a JSON response. Use checklive as a heartbeat.
Endpoint
POST https://<your-host>/api/device-httpregister
// CloudSolution Protocol 3.0 — HTTP Device Registration
POST /api/device-http
Content-Type: application/json
{
"cmd": "reg",
"sn": "ZX12345678",
"cpusn": "123456789",
"devinfo": {
"modelname": "tfs30",
"usersize": 3000,
"fpsize": 3000,
"firmware": "th600wv6.1",
"mac": "00-01-A9-01-00-01"
}
}
Response:
{
"ret": "reg",
"result": true,
"cloudtime": "2026-06-12T10:30:00Z",
"nosenduser": true
}sendlog
// CloudSolution Protocol 3.0 — Send Attendance Logs
POST /api/device-http
Content-Type: application/json
{
"cmd": "sendlog",
"sn": "ZX12345678",
"count": 2,
"logindex": 10,
"record": [
{
"enrollid": 1,
"time": "2026-06-12T09:15:30",
"mode": 1,
"inout": 0,
"event": 0,
"temp": 36.5,
"image": "base64_encoded_photo"
},
{
"enrollid": 2,
"time": "2026-06-12T09:20:15",
"mode": 0,
"inout": 1,
"event": 0,
"temp": 36.8
}
]
}
Response:
{
"ret": "sendlog",
"result": true,
"count": 2,
"cloudtime": "2026-06-12T09:25:00Z",
"access": 1
}checklive
// CloudSolution Protocol 3.0 — Heartbeat (HTTP Only)
POST /api/device-http
Content-Type: application/json
{
"cmd": "checklive",
"sn": "ZX12345678",
"time": "2026-06-12T09:30:00"
}
Response:
{
"ret": "checklive",
"result": true,
"cloudtime": "2026-06-12T09:30:15Z"
}Example: Python Device
import requests
import json
import time
HOST = "https://your-host"
SN = "ZX12345678" # Device serial number
TOKEN = "your-token"
def register():
"""Register the device on startup"""
payload = {
"cmd": "reg",
"sn": SN,
"cpusn": "123456789",
"devinfo": {
"modelname": "device-1",
"usersize": 1000,
"firmware": "v1.0.0",
"mac": "00:11:22:33:44:55"
}
}
resp = requests.post(f"{HOST}/api/device-http", json=payload)
print("Register:", resp.json())
def send_logs(records):
"""Send attendance logs"""
payload = {
"cmd": "sendlog",
"sn": SN,
"count": len(records),
"logindex": 0,
"record": records
}
resp = requests.post(f"{HOST}/api/device-http", json=payload)
print("SendLog:", resp.json())
def heartbeat():
"""Send heartbeat every 60 seconds"""
payload = {
"cmd": "checklive",
"sn": SN,
"time": time.strftime("%Y-%m-%dT%H:%M:%S")
}
resp = requests.post(f"{HOST}/api/device-http", json=payload)
print("Heartbeat:", resp.json())
# Usage
if __name__ == "__main__":
register()
time.sleep(1)
# Send some logs
send_logs([{
"enrollid": 1,
"time": "2026-06-12T09:15:00",
"mode": 1, # Fingerprint
"inout": 0, # In
"event": 0
}])
# Heartbeat every minute
while True:
time.sleep(60)
heartbeat()
Example Device (Node.js / JSON)
import WebSocket from "ws"
let ws
let retries = 0
function connect() {
ws = new WebSocket("ws://your-host/ws")
ws.on("open", () => {
retries = 0
// Authenticate
ws.send(JSON.stringify({
type: "register",
device_id: process.env.DEVICE_ID,
token: process.env.DEVICE_TOKEN,
}))
})
ws.on("message", (data) => {
const msg = JSON.parse(data)
if (msg.type === "command") {
console.log("Received command:", msg.command)
// Execute command …
}
if (msg.type === "ping") {
ws.send(JSON.stringify({ type: "pong" }))
}
})
ws.on("close", () => {
// Exponential backoff reconnect
const delay = Math.min(1000 * 2 ** retries, 30000)
retries++
setTimeout(connect, delay)
})
}
connect()
// Send telemetry every 5 seconds
setInterval(() => {
if (ws?.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
type: "telemetry",
device_id: process.env.DEVICE_ID,
payload: { temperature: readTemp(), humidity: readHumidity() },
}))
}
}, 5000)Dashboard WebSocket
disconnected