TAD101 universal protocol

Architecture

System topology

Device (Android/iOS/Arduino/RPi)
  └─ WebSocket ──► Soketi (Pusher-compatible)
                     └─ private-device.{imei}
                          ├─ tad101.* events ──► TAD101 driver
                          └─ tad101.cmd.* ◄────── Command bus

Channel taxonomy

ChannelPurposeAuth
tad101.device.{imei}Per-device telemetry + command busPrivate, device secret
admin.devicesFilament admin map feedPrivate, admin
tenant.{tenant_id}.devicesTenant portal feedPrivate, tenant
user.{user_id}.devicesEnd-user app feedPrivate, user
tad101.commandsAdmin observability mirrorPublic

Authentication flow

1. Device POST /api/tad101/auth  { imei, secret }
2. Server validates secret  →  issues Soketi channel auth token
3. Device subscribes to private-device.{imei}
4. Telemetry pushed as tad101.telemetry events

Soketi configuration

TAD101 reuses the same Soketi instance that powers Laravel broadcasting. Set PUSHER_* values for both Laravel and the Docker Compose soketi service — Laravel ships a config that maps to those env vars automatically.

.env
# Soketi / Pusher-compatible broadcaster
PUSHER_APP_ID=tad101
PUSHER_APP_KEY=tad101_key
PUSHER_APP_SECRET=change-in-production
PUSHER_HOST=soketi
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

# TAD101 wiring
TAD101_SERVER_HOST=fleet.yourdomain.com
TAD101_WS_URL=wss://fleet.yourdomain.com
TAD101_WEBHOOK_SECRET=<hex32>

REST fallback

Devices that cannot keep a long-lived WebSocket open may POST the same envelope to /api/tad101/inbound with the device secret as a bearer token. The envelope shape is identical — see Message Envelope.