I got tired of missing recordings, so I built channels2mqtt

I run Channels DVR and Home Assistant. For a long time, they had nothing to say to each other. Recordings would pile up and my phone stayed silent. My dashboard knew nothing about what was sitting unwatched on my DVR.

So I built channels2mqtt.

What it does

channels2mqtt is a Python service that polls your Channels DVR server on a configurable interval and publishes recording data to an MQTT broker. Home Assistant picks up those messages via MQTT Discovery and surfaces them as native sensors.

On startup, it publishes discovery config payloads so Home Assistant automatically creates three sensors — no yaml editing required:

From there it enters a poll loop, fetching fresh data from the Channels DVR API and publishing any changes.

How I use it

The main one is push notifications. The moment a new recording lands, my phone knows about it.

I also have a Lovelace popup that shows my current recordings — title, episode, artwork. But once data is in Home Assistant, you can do whatever you want with it. Automations, dashboards, notification routing based on who in the house would care about a particular show.

A bug worth explaining

Early versions tracked the latest recording by position — whatever was at the top of the list. The problem: watch a recording, it gets removed, the next one slides up, and you'd get a notification for a show that's been in your library for a week.

The fix was to stop tracking position and start tracking identity. channels2mqtt now maintains a set of every recording ID it has ever seen. A notification only fires when an ID appears that wasn't there before. On startup, all existing recordings are seeded into that set so a restart doesn't flood you with stale notifications.

# Before
last_recording_id = None

# After
seen_recording_ids = set()
for r in get_all_recordings():
    seen_recording_ids.add(r.get("id"))

Small change. Makes it feel right instead of just functional.

Getting started

services:
  channels2mqtt:
    image: zackwag/channels2mqtt:latest
    container_name: channels2mqtt
    restart: unless-stopped
    environment:
      - CHANNELS_HOST=192.168.x.x
      - MQTT_HOST=192.168.x.x
      - MQTT_USER=your_mqtt_username
      - MQTT_PASS=your_mqtt_password

Within one poll cycle, the sensors appear in Home Assistant.

Notable optional variables: POLL_INTERVAL (default: 60 seconds), LATEST_INCLUDE_WATCHED, ALL_INCLUDE_WATCHED, and LATEST_INCLUDE_IN_PROGRESS. Full details on Docker Hub and GitHub.