-
Notifications
You must be signed in to change notification settings - Fork 1
Technical Telemetry Schema
The schema defines all DataEndpoint and DataType variants and is the source of truth for every language binding. All
nodes that exchange telemetry must use the exact same schema (including ordering), or decoding will be undefined.
Location:
telemetry_config.json (source | mirror) (
override path with SEDSPRINTF_RS_SCHEMA_PATH)
Generated outputs:
- Rust enums and metadata:
define_telemetry_schema!in src/config.rs (source | mirror) - C header: C-Headers/sedsprintf.h (source | mirror)
- Python stubs: python-files/sedsprintf_rs/sedsprintf_rs.pyi (source | mirror)
The order of items in telemetry_config.json (source | mirror) defines the enum discriminants (with built-ins inserted as noted below). Those discriminants are sent on the wire and used in endpoint bitmaps. Reordering entries without updating every deployed system will break decode compatibility.
Built-ins:
-
TelemetryErrordata type is built-in and is appended after all schema types. -
TelemetryErrorendpoint is built-in and is appended after all schema endpoints. - Do not define
TelemetryErrorin the JSON schema.
Safe changes:
- Appending new endpoints/types to the end of the list.
- Updating documentation fields (
doc).
Risky changes:
- Reordering or deleting endpoints/types.
- Changing a type's element layout (data type or count).
Top-level keys:
-
endpoints: list ofDataEndpointdefinitions. -
types: list ofDataTypedefinitions.
-
rust: Rust enum variant name. -
name: wire/display name (typically ALL_CAPS). -
doc: optional description. -
broadcast_mode:Default,Always, orNever.
broadcast_mode influences forwarding in RouterMode::Relay:
-
Always: forward even if a local handler exists. -
Never: never forward. -
Default: forward only if the endpoint is not handled locally.
-
rust: Rust enum variant name. -
name: wire/display name. -
doc: optional description. -
reliable: optional boolean (legacy).truemaps to ordered reliable delivery. -
reliable_mode: optional string (None,Ordered,Unordered). Overridesreliablewhen present. -
class:Data,Warning, orError(used for formatting and error handling). -
element: payload layout description (see below). -
endpoints: list of endpoint Rust variant names (used as metadata for defaults/validation).
-
kind:StaticorDynamic. -
data_type: primitive element type (Float32,UInt16,String,Binary, etc.). -
count: only forStatic(number of elements).
This library treats the payload as a raw byte slice. The schema tells it how to interpret that slice:
-
Static + numeric/bool: payload size must equal
count * element_width. -
Dynamic + numeric/bool: payload size must be a multiple of
element_width. - String: dynamic UTF-8 bytes; trailing NULs are ignored for validation.
- Binary: raw bytes (no UTF-8 requirements).
- NoData: zero-length payload (used for marker messages).
For static String or Binary payloads, the schema uses the compile-time limits:
STATIC_STRING_LENGTHSTATIC_HEX_LENGTH
These are configured in
src/config.rs (source | mirror)
and used by data_type_size.
The macro-generated metadata types are defined in src/lib.rs (source | mirror):
MessageMeta { name, element, endpoints, reliable }MessageElement::{Static, Dynamic}-
MessageDataType(primitive element type) -
MessageClass(Data/Warning/Error)
Helpers:
-
message_meta(ty): returns the fullMessageMeta. -
get_data_type(ty): returns the primitive element type. -
get_needed_message_size(ty): returns the static payload size (bytes). -
endpoints_from_datatype(ty): returns endpoints listed in the schema. -
is_reliable_type(ty): returns whether the type uses reliable delivery on the wire.
-
TelemetryPacket::newvalidates payload sizes againstmessage_meta. -
Router::log*uses the schema to validate payload lengths before serialization. -
TelemetryPacket::to_stringusesMessageClassandMessageDataTypeto format payloads.
{
"endpoints": [
{ "rust": "Radio", "name": "RADIO", "doc": "Downlink radio", "broadcast_mode": "Default" }
],
"types": [
{
"rust": "GpsData",
"name": "GPS_DATA",
"doc": "GPS data",
"reliable": false,
"class": "Data",
"element": { "kind": "Static", "data_type": "Float32", "count": 3 },
"endpoints": ["Radio"]
}
]
}
Before deploying a schema change: