Expose multiple Blink cameras and events via MQTT — with native Home Assistant discovery support.
Built on blinkpy.
Based on my forked versions of amcrest2mqtt and govee2mqtt.
A few notes:
- "Rediscover" button added to service - when pressed, device discovery is re-run so HA will rediscover deleted devices
For docker-compose, use the configuration included in this repository.
Using the docker image, mount your configuration volume at /config and include a config.yaml file (see the included config.yaml.sample file as a template).
The recommended way to configure blink2mqtt is via the config.yaml file. See config.yaml.sample for a complete example with all available options.
mqtt:
host: 10.10.10.1
port: 1883
username: mqtt
password: password
qos: 0
protocol_version: "5" # MQTT protocol version: 3.1.1/3 or 5
prefix: blink2mqtt
reconnect_delay: 30
home_assistant: true
discovery_prefix: homeassistant
# TLS settings (optional)
tls_enabled: false
tls_ca_cert: /config/ca.crt
tls_cert: /config/client.crt
tls_key: /config/client.keyblink:
username: email@example.com
password: password
device_update_interval: 30 # seconds between device updates
device_rescan_interval: 3600 # seconds between device list rescans
snapshot_interval_wired_minutes: 5 # minutes between wired camera snapshot refreshes
snapshot_interval_battery_hours: 0 # hours between battery camera snapshot refreshes (0 disables timed battery snapshots)snapshot_update_interval is kept as a legacy fallback for wired cameras (values > 60 are treated as seconds and converted to minutes). Setting snapshot_interval_battery_hours: 0 disables timed snapshots for battery-powered cameras.
Optionally save captured snapshots to disk with automatic retention cleanup. Each camera gets a Save Snapshots switch in Home Assistant (defaults ON when a media path is configured).
media:
path: /media # directory to store snapshot images
retention_days: 14 # days to keep snapshots (default: 7; 0 = disabled)
max_size: 5 # max MB per snapshot image (default: 5)
media_source: media-source://media_source/local/snapshots # HA media source URL (optional)Snapshots are saved as {camera_name}-{YYYYMMDD-HHMMSS}.jpg with a {camera_name}-latest.jpg symlink pointing to the most recent image. A daily cleanup loop removes files older than retention_days.
Mount a volume at /media in your Docker container (see the docker-compose.yaml example).
timezone: America/New_York # Timezone (see TZ database list)While the config file is recommended, environment variables are also supported. See ENVIRONMENT_VARIABLES.md for the full list of available environment variables.
The camera snapshots work really well for the HomeAssistant Area cards on a dashboard - just make this MQTT camera device the only camera for an area and place an Area card for that location.
An "event snapshot" (eventshot) is separately (and specifically, by filename) collected when the camera automatically records a snapshot because of an event.
When enabled, blink2mqtt publishes motion event snapshots to MQTT for AI-powered object detection via vision2mqtt. Detection results (person, vehicle, animal, bird) are published back to MQTT and auto-discovered by Home Assistant.
This has been specifically tested with the M5Stack LLM-8850 Pi HAT kit on a Raspberry Pi 5, which provides ~8ms/frame inference via the Axera AX8850 NPU (24 TOPS).
In config.yaml:
vision_request: trueOr via environment variable:
VISION_REQUEST=true
When a motion event occurs, blink2mqtt publishes a JSON message to blink2mqtt/vision/request containing the camera snapshot as a base64-encoded image. vision2mqtt subscribes to +/vision/request, runs YOLO11 inference, and publishes detection results back to MQTT — including per-camera presence sensors that appear automatically in Home Assistant.
Vision requests are triggered by detecting new clips in the Blink cloud API. For this to work reliably, each camera's motion settings in the Blink app must be configured correctly:
| Setting | Required | Notes |
|---|---|---|
| Motion Detection | ON | Motion must be enabled for the camera to record clips |
| Early Notification | OFF (default) | Must be disabled — when ON, Blink sends notifications before the clip finishes recording, and the clip does not appear in the API within the polling window. This prevents blink2mqtt from detecting new clips. |
To check these settings: open the Blink app, tap a camera, then tap Motion Settings.
See the vision2mqtt README for full setup instructions, including the Raspberry Pi 5 + LLM-8850 hardware setup guide.
The app supports events for any Blink device supported by the blinkpy library.
The app has built-in support for Home Assistant discovery. Set home_assistant: true in the mqtt section of your config.yaml (or the MQTT_HOMEASSISTANT environment variable to true) to enable support.
If you are using a different MQTT prefix to the default, you will need to set the discovery_prefix setting (or MQTT_DISCOVERY_PREFIX environment variable).
For Docker Compose, see the included docker-compose.yaml.
The app expects the config directory to be mounted at /config:
CMD [ "python", "./app.py", "-c", "/config" ]
If 2FA is required, the container will wait up to 5 minutes for a key.txt file containing the verification code from Blink. Place this file in your /config directory when prompted. Once validated, your credentials will be stored for reuse.
Docker is the only supported way of deploying the application. The app should run directly via Python but this is not supported.
A few people have kindly requested a way to donate a small amount of money. If you feel so inclined I've set up a "Buy Me A Coffee" page where you can donate a small sum. Please do not feel obligated to donate in any way - I work on the app because it's useful to myself and others, not for any financial gain - but any token of appreciation is much appreciated :)
Home Assistant assigns an entity_id once, at first discovery, and keys its registry on
unique_id. It never reassigns that entity_id afterwards — not when the entity is renamed, and
not when discovery is cleared and republished. This was verified directly: clearing the retained
discovery topic, waiting 25 seconds, and republishing restores the identical entity_id.
Two rules follow, and breaking either one strands an entity permanently:
- Never reuse a
unique_idfor a different entity. If a component's meaning changes, mint a newunique_iddeliberately. - Every component publishes an explicit
obj_id, derived from its stable component key rather than its display name. Without it HA derives theentity_idfrom the display name, so renaming a component in a later release leaves itsentity_iddescribing the old name — and a differently-named component can end up owning it.
It cannot be fixed from this service, because no MQTT message can reassign an entity_id. Rename
it in Home Assistant under Settings → Devices & Services → Entities. If two entities have
swapped ids, rename the squatter first to free the id, then rename the correct entity into it.
The Reset discovery button clears and republishes retained discovery and sweeps orphaned
configs for devices that no longer exist. It does not reassign entity_ids.