Device command queue (Codec 12)
Purpose
Outbound GPRS commands (Teltonika Codec 12) allow actions such as getinfo, getio, and configuration workflows. OmniTrack stores a durable queue in PostgreSQL, exposes an HTTP API, and the telematics-gateway service sends binary Codec 12 frames on the same TCP session as Codec 8 AVL, after each AVL batch is acknowledged (per Teltonika session rules).
Database: device_commands
| Column | Usage |
|---|---|
imei | Target device |
idempotency_key | Optional; unique with imei — same key replaces duplicate intent |
command_text | Plain text command string (e.g. getinfo) — encoded as ASCII in Codec 12 |
status | pending → sent → acked, or failed after max attempts |
attempt_count | Increments each time the gateway sends the command on the wire |
next_retry_at | When status returns to pending after timeout/disconnect/CRC error (exponential backoff) |
codec12_response_hex | Device response payload (hex) for type 0x06 packets |
error_message | Failure reason (timeout, CRC, TCP close, encode error, …) |
HTTP API (government role)
POST /api/fleet/devices/:imei/commands— enqueue{ "command": "getinfo", "idempotency_key": "optional-uuid" }GET /api/fleet/devices/:imei/commands— list recent commands
See implementation in server.ts (search for device_commands).
Gateway integration
Implemented in services/telematics-gateway/src/main.ts and codec12.ts:
- After Codec 8 records are stored and the 4-byte AVL ack is sent, the gateway claims the next
pendingrow (FOR UPDATE SKIP LOCKED), incrementsattempt_count, setssent, and writes a Codec 12 packet (preamble, data length, CRC-16/IBM footer per Teltonika). - Codec 12 responses (
type 0x06) are parsed from the same byte stream; payloads are stored incodec12_response_hex; status becomesacked. - Timeout (default 45s,
TELEM_COMMAND_TIMEOUT_MS): row returns topendingwithnext_retry_atunlessattempt_count≥TELEM_COMMAND_MAX_ATTEMPTS(default 5), thenfailed. - TCP disconnect or CRC mismatch while awaiting a response uses the same retry/backoff rules.
- One command is in flight per TCP session; the next starts after ack or retry scheduling.
Backoff: min(480, 30 * 2^(attempt_count - 1)) seconds (capped).
Idempotency and HTTP clients
- Clients should send the same
idempotency_keywhen retrying a logical command after an API timeout so duplicate rows are not created.
Safety
Always verify command strings against the device manual for your model and firmware; wrong commands can brick configuration or drain data SIMs.