Multi-DVR Overview
ChannelWatch v1.0 can monitor any number of Channels DVR servers from a single running instance. Each server is tracked independently — its own event stream, its own session state, its own notification routing, and its own metrics labels. Nothing bleeds across servers by default.
What “multi-DVR” means
Section titled “What “multi-DVR” means”In v0.7, ChannelWatch connected to exactly one Channels DVR server, configured via environment variables. In v1.0, that model is replaced by a list of DVR server entries managed through the web UI (or a YAML config file). You can add, remove, enable, and disable servers at runtime without restarting the container.
Each server runs in its own asyncio task group inside the ChannelWatch process. If one DVR goes offline, its task group enters exponential backoff and retries independently. The other DVRs keep running without interruption.
DVR identity: the canonical ID
Section titled “DVR identity: the canonical ID”Every DVR server in ChannelWatch has a stable, system-derived identifier computed as:
dvr_id = md5(host:port)[:8]For example, a server at 192.168.1.10:8089 gets the ID a3f2c1b4. This ID is:
- Stored in
settings.jsonalongside the server’s display name and connection details - Used as the key in all internal state maps (session tracking, alert history, dedup tables)
- Included as a label on every Prometheus metric (
dvr_id="a3f2c1b4") - Appended to per-DVR API endpoint paths (
/api/v1/dvrs/a3f2c1b4/health)
The ID is derived from the connection address, not from the display name. Renaming a server in the UI does not change its ID. Changing the host or port creates a new ID and a new independent state record.
Per-DVR state isolation
Section titled “Per-DVR state isolation”ChannelWatch keeps the following state independently for each DVR:
| State | Scope | Description |
|---|---|---|
| Event stream connection | Per-DVR | Each DVR has its own SSE connection and reconnect loop |
| Session tracking | Per-DVR | Active streams are tracked per-DVR; a session on DVR-A does not affect DVR-B |
| Alert deduplication | Per-DVR | Dedup is fully per-DVR by default; no cross-DVR suppression |
| Notification routing | Per-DVR | Each DVR can route different event types to different notification channels |
| Prometheus metrics | Per-DVR | All gauges and counters carry a dvr_id label |
| Health endpoint | Per-DVR | /api/v1/dvrs/<id>/health reports status for that server only |
This isolation means you can safely monitor a production DVR and a test DVR from the same ChannelWatch instance without their alerts or session counts interfering with each other.
Aggregate views
Section titled “Aggregate views”The dashboard defaults to an aggregate view that combines activity across all DVRs. A server switcher in the top navigation lets you filter to a single DVR. Notifications always include the server’s display name so you know which DVR triggered an alert.
Prometheus metrics expose both per-DVR series (with dvr_id label) and aggregate series (without the label) for backwards compatibility with existing dashboards.
Scale limits
Section titled “Scale limits”ChannelWatch has a soft limit of 10 DVR servers. You can override this limit in Settings > Advanced, but performance beyond 10 servers has not been benchmarked. The soft limit exists to prevent accidental runaway configurations, not as a hard technical ceiling.
Next steps
Section titled “Next steps”- Adding DVR Servers — add and manage servers through the web UI
- YAML and Env Var Config — configure servers via file or environment variables
- mDNS Auto-Discovery — let ChannelWatch find Channels DVR servers on your LAN automatically
- Per-DVR Notification Routing — send different alerts to different channels per server