Sign inSign up

graystorm/amcrest2mqtt

By graystorm

•Updated 4 days ago

Expose events and snapshots from Amcrest devices to an MQTT broker, especially for HomeAssistant

Image
Internet of things
Monitoring & observability
0

10K+

graystorm/amcrest2mqtt repository overview

⁠weirdtangent/amcrest2mqtt

Expose multiple Amcrest cameras and events to an MQTT broker, primarily designed to work with Home Assistant. Also exposes a webrtc link, if you have one, so a live feed can be viewed from within Home Assistant (on a dashboard, not on the entity page for the camera)

Uses the python-amcrest⁠ library. Forked from dchesterton/amcrest2mqtt⁠

⁠Docker

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).

⁠Configuration

The recommended way to configure amcrest2mqtt is via the config.yaml file. See config.yaml.sample⁠ for a complete example with all available options.

⁠MQTT Settings
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: amcrest2mqtt
  discovery_prefix: homeassistant
  # TLS settings (optional)
  tls_enabled: false
  tls_ca_cert: filename
  tls_cert: filename
  tls_key: filename
⁠Amcrest Camera Settings
amcrest:
  hosts:
    - 10.10.10.20
    - camera2.local
  names:
    - camera.front
    - camera.patio
  port: 80  # Use 443 for HTTPS if your camera firmware supports it
  ssl_verify: true  # Set to false for self-signed camera certificates
  username: admin
  password: password
  storage_update_interval: 15  # minutes, default = 15
  snapshot_update_interval: 60  # minutes, default = 60
  # WebRTC settings (optional)
  webrtc:
    host: webrtc.local
    port: 1984
    sources:
      - FrontYard
      - Patio

Security note: The default port 80 connects to cameras over unencrypted HTTP. Camera credentials are sent using HTTP Digest Authentication (not plaintext), but all camera data — snapshots, recordings, and configuration responses — is transmitted without encryption. If your camera firmware supports HTTPS, set port: 443 and ssl_verify: false (Amcrest cameras use self-signed certificates). Otherwise, place cameras on an isolated VLAN to limit network-level exposure.

⁠Media/Recording Settings

You can optionally mount a media volume at /media to store motion recordings.

media:
  path: /media
  max_size: 25          # per recording, in MB; default is 25
  retention_days: 7     # days to keep recordings; 0 = disabled; default is 7
  media_source: media-source://media_source/local/videos  # HomeAssistant media source URL
⁠Environment Variables

While the config file is recommended, environment variables are also supported. See ENVIRONMENT_VARIABLES.md⁠ for the full list of available environment variables.

It exposes through the new 2024 HomeAssistant device discovery a service plus a camera with multiple components for each camera you specify:

  • homeassistant/device/amcrest2mqtt_service - service config
  • homeassistant/device/amcrest2mqtt_[SERIAL_NUMBER] per camera, with components:

⁠Snapshots/Eventshots plus Home Assistant Area Cards

The camera snapshots work really well for the HomeAssistant Area cards on a dashboard - just make this MQTT camera device is the only camera for an area and place an Area card for that location on a dashboard.

An "event snapshot" (eventshot) is separately (and specifically, by filename) collected IF the camera automatically records a snapshot because of an event. Note, that if the Amcrest camera is configured to record 3 or 5 snapshots on an event - each of those may be seen and updated by amcrest2mqtt and you will very quickly end up with the last snapshot.

⁠WebRTC

The WebRTC option works with the go2rtc⁠ package which is a streaming server that works very well for (my) Amcrest cameras. If you setup the WebRTC config here, there will be a camera.<name> webrtc which you can put on a dashboard with the entity card. It will show a small camera icon and likely say "Idle", but if you click on it (and give it a little time to warm up) you will see the live-streaming feed from the webrtc server.

⁠Object Detection with vision2mqtt

When enabled, amcrest2mqtt 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).

⁠Enable vision requests

In config.yaml:

vision_request: true

Or via environment variable:

VISION_REQUEST=true

When a motion event occurs, amcrest2mqtt publishes a JSON message to amcrest2mqtt/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.

See the vision2mqtt README⁠ for full setup instructions, including the Raspberry Pi 5 + LLM-8850 hardware setup guide.

⁠Device Support

The app supports events for any Amcrest device supported by python-amcrest⁠.

⁠Running the app

For Docker Compose, see the included docker-compose.yaml⁠.

The app expects the config directory to be mounted at /config:

CMD [ "python", "-m", "amcrest2mqtt", "-c", "/config" ]

⁠Healthcheck

There is a simple healthcheck that can be run, as seen in the sample docker-compose. The app simply touches a file in /tmp every 60 seconds, so while the app is functional, that file should keep getting hit. The healthcheck (python -m mqtt_helper.healthcheck) will check that and return true or false.

⁠Mounted Volume Permissions (Synology)

If you mount a host folder into /media for saving recordings, ensure the container has write access. On Synology NAS, shared folders use ACLs that can block Docker containers even when chmod 777 appears open.

To reset permissions and make the volume writable by the container’s default user (uid=1000, gid=1000), run the following via SSH (alter for your path):

sudo synoacltool -del /volume1/photo/Amcrest
sudo chmod 777 /volume1/photo/Amcrest
sudo chown 1000:1000 /volume1/photo/Amcrest

Then verify inside the container:

docker exec -it amcrest2mqtt ls -ld /media

You should see permissions like:

drwxrwxrwx 1 appuser appuser ... /media

Once configured correctly, you should see new recordings appear in your mounted folder with ownership 1000:1000 and a symlink to the latest file.

Also, make sure you have

environment:
  - TZ=America/New_York

in your docker-compose if you want the recording filenames to by local time and not UTC.

⁠Out of Scope

⁠Non-Docker Environments

Docker is the only supported way of deploying the application. The app should run directly via Python but this is not supported.

⁠See also

⁠Contributors

⁠Buy Me A Coffee

Buy Me A Coffee⁠


⁠Build & Quality Status

Build & Release Lint Docker Build Python Release Docker Image Tag Docker Pulls License

⁠Security

SBOM Provenance Signed Trivy

⁠Entity IDs and the unique_id contract

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:

  1. Never reuse a unique_id for a different entity. If a component's meaning changes, mint a new unique_id deliberately.
  2. Every component publishes an explicit obj_id, derived from its stable component key rather than its display name. Without it HA derives the entity_id from the display name, so renaming a component in a later release leaves its entity_id describing the old name — and a differently-named component can end up owning it.
⁠If an entity_id is already wrong

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.

Tag summary

Content type

Image

Digest

sha256:c981433d9…

Size

143.1 MB

Last updated

4 days ago

docker pull graystorm/amcrest2mqtt