Event
Publish discrete events from your device. Events represent moments that happen — a door opening, a device booting up, a threshold being crossed, a user pressing a button. The App SDK can subscribe to these events in real time.
Telemetry vs Events
Telemetry and events are both fire-and-forget, but they serve different purposes:
| Telemetry | Events | |
|---|---|---|
| What it captures | Continuous measurements (temperature, humidity, pressure) | Discrete moments (door opened, error detected, boot complete) |
| Frequency | Regular intervals (e.g., every 5 seconds) | Whenever something happens |
| Schema | Validated against device schema | No schema — you define the event name and payload |
| Timestamps | Auto-added by the SDK via NTP | Auto-added by the SDK via NTP |
Rule of thumb: if you're measuring something continuously, use telemetry. If something just happened, use an event.
Overview
Events are user-defined — the name and payload are entirely up to you and your use case. When you send an event, it's delivered to any App SDK instance subscribed to that event name. Events are buffered offline and flushed on reconnect.
Access via device.event.
API
send()
Publish a named event with a payload to RelayX.
- JavaScript
- Python
await device.event.send(name, data)await device.event.send(name, data)| Parameter | Type | Description |
|---|---|---|
name | string | The event name |
data | any | The event payload (any serializable value) |
Returns true if sent, false if buffered (offline)
Names can only contain letters, numbers, hyphens, and underscores (A-Z, a-z, 0-9, -, _).
Send an Event
- JavaScript
- Python
await device.event.send("door_opened", {
door: "front",
method: "keycard",
});
await device.event.send("boot_complete", {
firmware: "1.2.0",
bootTime: 3200,
});
await device.event.send("door_opened", {
"door": "front",
"method": "keycard",
})
await device.event.send("boot_complete", {
"firmware": "1.2.0",
"bootTime": 3200,
})
Example Use Cases
Events are flexible — here are some common patterns:
- JavaScript
- Python
// geofence
if (crossedBoundary(lat, lng)) {
await device.event.send("geofence_entered", {
zone: "warehouse-A",
lat,
lng,
});
}
// user interaction
button.on("press", async () => {
await device.event.send("button_pressed", { button: "power" });
});
// error reporting
try {
await riskyOperation();
} catch (err) {
await device.event.send("error_detected", {
operation: "riskyOperation",
message: err.message,
});
}
# geofence
if crossed_boundary(lat, lng):
await device.event.send("geofence_entered", {
"zone": "warehouse-A",
"lat": lat,
"lng": lng,
})
# state change
if new_state != previous_state:
await device.event.send("state_changed", {
"from": previous_state,
"to": new_state,
})
# error reporting
try:
await risky_operation()
except Exception as err:
await device.event.send("error_detected", {
"operation": "risky_operation",
"message": str(err),
})
Offline Buffering
When the device is disconnected, send() buffers the event in memory and returns false. Once the connection is restored, all buffered events are flushed in order.
- JavaScript
- Python
const sent = await device.event.send("door_opened", { door: "front" });
if (!sent) {
console.log("Device is offline — event buffered");
}
sent = await device.event.send("door_opened", {"door": "front"})
if not sent:
print("Device is offline — event buffered")
Buffered events are stored in memory only. If the device process restarts while offline, buffered events are lost.