Telemetry
Publish sensor readings from your device to RelayX. Telemetry is fire-and-forget — readings are delivered to your app and stored for historical queries.
Overview
The telemetry module validates readings against your device schema and publishes them with NTP-synchronized timestamps. When disconnected, readings are buffered and flushed on reconnect.
API
- JavaScript
- Python
- C++
await device.telemetry.publish(metric, reading)| Parameter | Type | Description |
|---|---|---|
metric | string | The metric name (must match your device schema) |
reading | any | The value to publish (number, string, boolean, or object) |
Returns true if sent, false if buffered (offline)
Throws ValidationError if the metric or reading type doesn't match the schema
await device.telemetry.publish(metric, reading)| Parameter | Type | Description |
|---|---|---|
metric | string | The metric name (must match your device schema) |
reading | any | The value to publish (number, string, boolean, or object) |
Returns true if sent, false if buffered (offline)
Throws ValidationError if the metric or reading type doesn't match the schema
device->telemetry.publish_number(metric, value) → relay_err_tdevice->telemetry.publish_string(metric, value) → relay_err_tdevice->telemetry.publish_bool(metric, value) → relay_err_tdevice->telemetry.publish_json(metric, json_value) → relay_err_t| Parameter | Type | Description |
|---|---|---|
metric | const char* | The metric name (must match your device schema) |
value | double, const char*, bool | The value to publish (type must match the method) |
json_value | const cJSON* | A cJSON object tree (for publish_json) |
Returns RELAY_OK if sent, RELAY_ERR_BUFFERED if offline, RELAY_ERR_VALIDATION if the metric or type doesn't match the schema
Publish a Reading
- JavaScript
- Python
- C++
const sent = await device.telemetry.publish("temperature", 22.5);
console.log(sent ? "Sent" : "Buffered (offline)");
sent = await device.telemetry.publish("temperature", 22.5)
print("Sent" if sent else "Buffered (offline)")
relay_err_t err = device->telemetry.publish_number("temperature", 22.5);
ESP_LOGI("app", "%s", err == RELAY_OK ? "Sent" : "Buffered (offline)");
Schema Validation
Every device has a schema that defines its metrics. The SDK validates each publish call against it:
- The metric name must exist in the schema
- The reading type must match the type defined for that metric
- JavaScript
- Python
- C++
If validation fails, a ValidationError is thrown. If the schema failed to load on connect, validation is skipped.
If validation fails, a ValidationError is thrown. If the schema failed to load on connect, validation is skipped.
If validation fails, RELAY_ERR_VALIDATION is returned. If the schema failed to load on connect, validation is skipped.
Supported Types
- JavaScript
- Python
- C++
| Schema Type | Accepted Values |
|---|---|
number | Any numeric value (integer or float) |
string | Any string value |
boolean | true or false |
json | Objects and arrays |
null and undefined readings bypass type checking and are accepted for any metric.
| Schema Type | Accepted Values |
|---|---|
number | Any numeric value (integer or float) |
string | Any string value |
boolean | true or false |
json | Objects and arrays |
None readings bypass type checking and are accepted for any metric.
| Schema Type | Publish Method |
|---|---|
number | publish_number(metric, double) |
string | publish_string(metric, const char*) |
boolean | publish_bool(metric, bool) |
json | publish_json(metric, const cJSON*) |
publish_json converts the cJSON tree to native msgpack — the caller owns the cJSON* and must free it.
Timestamps
Every reading is automatically timestamped using the device's NTP-synchronized time. The payload sent to RelayX looks like:
{
"value": 22.5,
"timestamp": 1711900800000
}
You don't need to add timestamps yourself — the SDK handles this.
Offline Buffering
When the device is disconnected, publish calls are buffered in memory. Once the connection is restored, all buffered messages are flushed in order.
- JavaScript
- Python
- C++
const sent = await device.telemetry.publish("temperature", 22.5);
if (!sent) {
console.log("Device is offline — reading buffered");
}
sent = await device.telemetry.publish("temperature", 22.5)
if not sent:
print("Device is offline — reading buffered")
relay_err_t err = device->telemetry.publish_number("temperature", 22.5);
if (err == RELAY_ERR_BUFFERED) {
ESP_LOGW("app", "Device is offline — reading buffered");
}
Buffered messages are stored in memory only. If the device restarts while offline, buffered messages are lost.
Error Handling
- JavaScript
- Python
- C++
try {
await device.telemetry.publish("unknown_metric", 42);
} catch (err) {
// ValidationError: metric "unknown_metric" not found in schema
console.error(err.message);
}
try:
await device.telemetry.publish("unknown_metric", 42)
except ValidationError as err:
# metric "unknown_metric" not found in schema
print(err)
relay_err_t err = device->telemetry.publish_number("unknown_metric", 42);
if (err == RELAY_ERR_VALIDATION) {
ESP_LOGE("app", "Metric not found in schema");
}