Stream Player
:::info Status
Implemented — registry side per the unified Device Management module; a legacy self-service path (devices.py, below) still exists pending the approval-queue cutover described there.
:::
A stream player is a member-owned speaker unit that plays broadcasts — and can also work as a plain Bluetooth speaker, entirely independent of Azan360. It's the one device kind with an owner, and the one whose authorization chain includes a membership check.
Bluetooth first, always
A stream player is a speaker the member bought. Bluetooth playback is never gated by lifecycle, membership, inventory, or backend reachability — and it survives
deauthorize.
See Device Architecture — Bluetooth is outside the perimeter for the full reasoning. This is the single most important thing to understand about this device kind before touching any of its code: wiping Azan360 credentials must never disable the speaker.
Authorization — the one branch that differs from a transmitter
A stream player needs everything a transmitter needs (registry, ACTIVE,
inventory-bound, mosque-assigned) plus the current owner's membership at
the bound mosque must be approved. See
Device Authorization — step 8 for the exact
query, and Playback Entitlement for how
this composes with the entitlement lease when the unit is offline.
Two registration paths today
| Unified registry (current) | Legacy self-service (devices.py) | |
|---|---|---|
| Table | devices (device_kind='stream_player') | pre-existing member-facing table, per device_registry.py's own module docstring |
| Approval | Super Admin, via Device Management | None — self-registered, per docs/device-management-architecture-summary.md's "Biggest Operational Risk" |
| Router | /api/v1/device-registry/*, /api/v1/my-devices/* | /api/v1/devices/* |
The legacy path is exactly the population caught by the approval-queue cutover risk described on the Device Management module page — every existing self-registered unit lands in the Super Admin queue and stops streaming until reviewed, at cutover.
Legacy API (devices.py)
| Method | Path | Purpose |
|---|---|---|
GET/POST | /api/v1/devices | List / self-register |
GET/PATCH/DELETE | /api/v1/devices/{device_id} | Detail / edit / remove |
POST | /api/v1/devices/{device_id}/connectivity-test · /connectivity-client | Connectivity diagnostics |
Owner-facing binding API (current)
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/my-devices | Caller's units with effective_playback_state |
GET | /api/v1/my-devices/{id}/rebind-targets | Mosques the caller has approved membership at |
POST | /api/v1/my-devices/{id}/rebind · /unbind | See Mosque Binding |
Full lifecycle/registry API: Device Management module.
Wire protocol
Topic structure, commands, events, retained config, and the Bluetooth arbitration config block: MQTT Protocol.
Roadmap
Sequencing for closing the legacy-path gap and the rest of the stream player rollout: Roadmap — Stream Player / User Device.