Skip to content

Topics & Payloads

Learn how to structure MQTT topics and format message payloads for SiliconWit.IO.

SiliconWit.IO uses a hierarchical topic structure:

devices/{device_id}/{message_type}
TopicDirectionPurpose
devices/{id}/telemetryDevice → CloudSensor data
devices/{id}/commandsCloud → DeviceControl commands
devices/{id}/statusBothOnline/offline status
devices/{id}/configCloud → DeviceConfiguration updates
devices/{id}/eventsDevice → CloudEvent notifications
devices/abc123/telemetry # Send sensor readings
devices/abc123/commands # Receive commands
devices/abc123/status # Online status

All payloads should be JSON:

{
"temperature": 25.5,
"humidity": 60,
"timestamp": 1704067200
}

Send sensor data to devices/{id}/telemetry:

{
"temperature": 25.5,
"humidity": 60,
"pressure": 1013.25,
"battery": 85
}

Multiple sensors:

{
"sensors": {
"indoor": {"temp": 22, "humidity": 45},
"outdoor": {"temp": 18, "humidity": 70}
}
}

For tracking devices:

{
"lat": -1.2921,
"lng": 36.8219,
"speed": 45.5,
"heading": 180,
"altitude": 1680,
"satellites": 8
}

For device status updates:

{
"online": true,
"uptime": 3600,
"rssi": -65,
"freeHeap": 45000
}

For discrete events:

{
"event": "motion_detected",
"zone": "entrance",
"timestamp": 1704067200
}
{
"event": "door_opened",
"duration": 5
}

Subscribe to devices/{id}/commands to receive:

{
"command": "restart"
}
{
"command": "set_interval",
"params": {
"seconds": 30
}
}
{
"command": "update_config",
"params": {
"report_interval": 60,
"deep_sleep": true,
"threshold": 30
}
}
void callback(char* topic, byte* payload, unsigned int length) {
// Parse JSON
StaticJsonDocument<256> doc;
deserializeJson(doc, payload, length);
const char* command = doc["command"];
if (strcmp(command, "restart") == 0) {
ESP.restart();
}
else if (strcmp(command, "set_interval") == 0) {
int interval = doc["params"]["seconds"];
reportInterval = interval * 1000;
}
else if (strcmp(command, "get_status") == 0) {
// Send status response
String status = "{\"uptime\":" + String(millis()/1000) + "}";
client.publish("devices/abc123/status", status.c_str());
}
}

For constrained devices and slow networks:

// Verbose (avoid)
{"temperature_celsius": 25.500000, "relative_humidity_percent": 60.000000}
// Compact (preferred)
{"t": 25.5, "h": 60}

Include timestamps for accurate data logging:

{
"temperature": 25.5,
"ts": 1704067200
}

Or let the server add timestamps (default behavior).

If sending frequently, batch multiple readings:

{
"readings": [
{"t": 25.5, "ts": 1704067200},
{"t": 25.6, "ts": 1704067260},
{"t": 25.4, "ts": 1704067320}
]
}

For debugging and filtering:

{
"temperature": 25.5,
"firmware": "1.2.0",
"location": "office-a"
}
Field TypeJSON ExampleNotes
Number25.5Use for all numeric values
BooleantrueFor on/off states
String"active"For status text
Array[1, 2, 3]For lists of values
Object{"a": 1}For nested data

For advanced use cases (API/dashboard only):

  • + matches one level: devices/+/telemetry
  • # matches all levels: devices/#