Spaces:
Paused
Download README.md from secutorpro/dispatch-console: direct link, hf CLI and curl.
- Browser
- Download file 3.81 kB
-
https://huggingface.co/spaces/secutorpro/dispatch-console/resolve/main/README.md
- Command line
-
hf download hf://spaces/secutorpro/dispatch-console/README.md
-
curl -L -o README.md https://huggingface.co/spaces/secutorpro/dispatch-console/resolve/main/README.md
title: Dispatch Console
emoji: πΊοΈ
colorFrom: blue
colorTo: green
sdk: docker
app_port: 8080
pinned: false
Dispatch Console
A self-hostable PoC-style fleet dispatch console β in the spirit of platforms like Global-PTT's dispatch: a live map of members, SOS alert handling, group push-to-talk, and member/talkgroup management. One process, one SQLite file, no external services.
Features
- Live map + GPS β Leaflet/OpenStreetMap map, member markers colored by talkgroup, online/offline styling, SOS pulse, popup with battery and coordinates; devices push positions over WebSocket, every ping is stored for trails (
GET /api/members/:id/trail) - SOS alerts β devices raise SOS, console shows a queue with Ack β Resolve flow and an audio alarm; state is broadcast to all consoles instantly
- Intercom / PTT β talkgroups with floor control (one speaker per group); dispatcher holds a button to talk, mic is captured at 16 kHz via AudioWorklet and relayed as PCM over the same WebSocket; floor indicator shows who is talking; call log recorded
- Member management β add/edit/remove members, assign talkgroups, see status/battery/last-seen; talkgroup list with colors
Architecture
browser / devices
β HTTPS (REST: members, groups, SOS, trails)
β WSS /ws (GPS, SOS, PTT control, PCM audio frames)
βΌ
Node + Express ββ better-sqlite3 (dispatch.db)
ββ ws Hub: auth, floor control per talkgroup, audio relay
React + Vite + Leaflet frontend (served statically by the same process)
Binary audio frame on the WebSocket:
[1B type=0x01][4B groupId BE][4B memberId BE][Int16LE PCM @ 16 kHz]
Only the current floor holder of a talkgroup may transmit; the server drops audio from anyone else.
Quickstart (Docker)
docker compose up --build
# open http://localhost:8080 β log in with admin / admin (change it)
Quickstart (dev)
cd server && npm install && npm run dev # API + WS on :8080
cd web && npm install && npm run dev # Vite on :5173, proxied to :8080
Simulated fleet
With the server running, drive a fake fleet so you can see the console come alive:
cd server && npm run sim
# 5 units driving around Paris, one SOS after ~25 s, rotating PTT floor requests
Device integration
A device (or backend integration) authenticates with a dispatcher JWT and identifies as a member:
{"type": "auth", "token": "<jwt>", "memberId": 12}
Then, per message: {"type":"gps","lat":48.85,"lng":2.35,"speed":34,"battery":80},
{"type":"sos"}, {"type":"ptt_start"}, {"type":"ptt_stop"},
and raw binary frames for audio (format above).
Configuration
| Env | Meaning |
|---|---|
PORT |
HTTP/WS port (default 8080) |
DATA_DIR |
where dispatch.db and the JWT secret live (default server/data) |
JWT_SECRET |
signing secret; generated and persisted on first run if unset |
ADMIN_PASSWORD |
password for the first-run admin dispatcher |
Limitations & next steps
- Device auth is trusted-by-JWT: any valid token can claim any
memberId. Production needs per-device credentials and revocation. - Audio is uncompressed 16 kHz PCM relayed over WebSocket β fine for small fleets on good links; swap in Opus + an SFU (LiveKit, mediasoup) for larger ones and lossy networks.
- Single-node SQLite; horizontal scale would need Postgres and a Redis pub/sub fan-out.
- Map tiles come from public OpenStreetMap servers β self-host tiles for production privacy.
- No TLS in the container β terminate TLS at your reverse proxy (devices require WSS/HTTPS for mic access anyway).
- On HF Spaces, storage is ephemeral: the SQLite file resets on rebuild (fine for demos; use a mounted volume or external DB for real data).