Skip to content

Devices and telemetry

Device identity

FieldWhat it is
deviceIdMAC of the network interface, lowercase and without separators (a4cf12bb73d2). Unique identifier of the device.
partNumberSerial of the model (device-type catalog): resolves the device type.
deviceTypeFamily: UDR (paint), UTA (tanks), UDO (dosing), UNE (transactions/stock). It never travels in the topic or the payload: the platform resolves it.

List the fleet

Terminal window
curl "https://api.linter-iot-stg.icent.digital/v1/devices?limit=50" \
-H "Authorization: Bearer lit_…"

Useful parameters: deviceType=UDR,UTA, status=ACTIVE, search=<text>, clientId=…, pagination with limit/offset (max. 500 per page).

Besides its identity, each item includes:

  • connectivity: online / offline (10-minute window since the last reading).
  • alertSeverity: critical / warning when the device has active alerts.
  • location: { lat, lng, source } when the device has a SIM — the position is resolved server-side (deterministically simulated today; tomorrow, the operator’s API with the same contract).

Detail and readings

Terminal window
curl https://api.linter-iot-stg.icent.digital/v1/devices/<id> \
-H "Authorization: Bearer lit_…"
curl "https://api.linter-iot-stg.icent.digital/v1/devices/<id>/telemetry?limit=20" \
-H "Authorization: Bearer lit_…"

Raw telemetry for a time range (for charts) lives at GET /v1/telemetry?deviceId=<mac>&from=<iso>&to=<iso>, and the aggregated volume for the last 24 h at GET /v1/telemetry/count24h.

Device-type catalog

Models (part number → type, commercial name, photo, videos, view configuration and alert rules) are managed at /v1/device-models (ROOT). Adding a new model lets its devices enter the system on their own.

UNE tanks and transactions

UNE devices report a nested payload (setup + a tanks[] list of variable length). Each tank’s identity is tanks[].deviceId when it is a non-empty string, falling back to dir:<direction> and then pos:<id> — the same rule the ingest, the API and the web apply, so a tank keeps its history even if its position in the array changes between messages.

Each payload’s tanks[].transactions[] holds only the transactions new since the last message (a sequential id per device); the ingest upserts them keyed by device + epoch + id, so a retransmission that only updates status does not create a duplicate. The epoch is a counter the ingest bumps when the device restarts its id sequence, so the ids of the new run do not collide with the old ones.

Because the ingest keeps one MQTT subscription with a fixed client id, it can only ever run as a single replica — UNE devices must publish with QoS 1 so Mosquitto queues messages while the ingest is briefly unavailable (a restart, a deploy) instead of dropping them.