IoT Pipeline

IoT Pipeline

DashboardDevicesOnboardingCompareErrorsLogsTest Plan⚙️ Test SettingsDecoding GuideGuide
Logout
Dashboard / Decoding guide

How to check a decoded packet by hand

  1. Download the decoder config(s) below (one file per packet type and schema, or all in one file) and decode_frame.py.
  2. Take the raw frame of a packet (hex string) from the Packet page, or from the device.
  3. Run python3 decode_frame.py --config all-decoder-configs.json --hex "<hex>". The script reads the header, picks the config the same way the pipeline does, and prints every byte range with its decoded value.
  4. Change a field in the config file (offset, length, type, factor) and run again to see the effect. The pipeline itself only changes when the config is updated in the backend.
  5. To compare with what the dashboard decoded, pass --expect event.json (the event's data JSON).
⬇ decode_frame.py

1. Frame layout (what the first bytes mean)

All multi-byte numbers are little-endian. Offsets are from the first byte of the frame (byte 0).
Header · 20 bytes
Payload · N bytes (decoded by config)
CRC · 4
HMAC · 32
ByteSizeFieldMeaning
01protocolVersionSupported: 1 or 13
11headerVersionAlways 1
21schemaVersionChooses the config version (1 → v1, 2 → v2, 5 → v5)
31packetTypeCodeChooses the config packet type (list below)
41deviceTypeCodeDevice family
5–84deviceNumericIdu32, the device id (IMEI number)
9–124sequenceNou32, increases per packet
13–164timestampu32, event time (epoch seconds)
171firmwareVersionBuild number
18–192reservedNot used
20 …NpayloadN = frame length − 56. Config field index counts from byte 20.
last 36 bytes, first 44CRC32IEEE CRC of header + payload (0 = not checked)
last 3232HMACSignature slot (not verified by the decoder)
Packet type codes: 1 heartbeat · 2 location · 3 battery_summary · 4 vehicle_telemetry · 5 cell_detail · 6 fault_event · 7 diagnostic · 8 config_ack · 20 batch_location · 21 batch_telemetry · 22 combined_telemetry · 30 can_frame_bundle · 31 realtime_telemetry_bundle · 32 extended_data_bundle · 33 full_snapshot_bundle · 34 accident_snapshot_bundle · 35 logfile_meta.
The frame can arrive as raw bytes or as an ASCII hex string; the script takes the hex form.

2. How the config turns payload bytes into values

Each entry in fields describes one value:
KeyMeaning
name / normalizedNameName in the raw decoded output / in the normalized output. A dotted name such as battery.soc becomes a nested object when expandDotPaths is true.
indexStart byte inside the payload (frame byte = 20 + index).
lengthNumber of bytes. Must match the type (uint16 = 2, uint32 = 4 …).
typeuint8/16/32/64, int8/16/32/64, ascii, bytes, flags (bit map), or array (with subLength per element).
conversionFactorRaw number is multiplied by this (e.g. 0.1 for a value sent in tenths).
min / maxAllowed range. Outside it a warning is added (WARN) or the packet is rejected (STRICT).
flagsFor type flags: bit number → name.
Top level: endianness (little by default), expectedPayloadLength (payload must have exactly this many bytes, 0 = not checked), validationMode (WARN keeps the packet and lists problems, STRICT rejects it).
Config lookup: device type + packet type + protocol version + schema version from the header, newest active config wins. If none exists, schema v2 is tried as a fallback (--fallback-schema v2 in the script).

3. Decoder configs (active)

⬇ decode_frame.py
Packet typeSchemaProtocolPayload bytesFieldsModeUpdated
Loading...

4. Script examples

python3 decode_frame.py --config all-decoder-configs.json --hex "01010205..."
python3 decode_frame.py --config decoder-realtime_telemetry_bundle-v5.json --hex-file frame.hex
python3 decode_frame.py --config all-decoder-configs.json --list
python3 decode_frame.py --config all-decoder-configs.json --hex "..." --json
python3 decode_frame.py --config all-decoder-configs.json --hex "..." --expect event.json
The script needs only Python 3 (no packages). It exits with code 1 when the pipeline would reject the frame (bad length, CRC, no matching config) or when --expect finds a difference.