Zoneminder and Home Assistant

I’ve got the excellent zmEventNotification configured but I’m not using it to send notifications directly. Here’s why…

Home Assistant knows when I’m home and I already have push notifications set up using Pushover so that I can get notifications if one of my door sensors triggers when I’m out. I do this via the alarm control panel, so that it’s not just controlled by presence – I can also set the alarm at night and turn it on or off manually. I find that’s much more flexible than tying the notifications directly to presence.
 

This is done through a series of automations:

  • When HA detects that I’m out, it sets the alarm panel to “armed away”
  • When HA detects that I’ve arrived home, it sets the alarm panel to “disarmed”
  • At night, between 1am and 7am, HA sets the alarm panel to “armed home”
  • When a door opens AND the alarm panel is armed (home or away), HA sends a notification.

The last one was a bit tricky, and couldn’t be done through the automation GUI as that doesn’t yet support the “OR” condition. My YAML for it looks like this:

- alias: 'Alarm trigger'
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.side_door_access, sensor.front_door_access, sensor.back_door_access
      to: 'open'     
  condition:
    condition: or
    conditions:
      - condition: state
        entity_id: alarm_control_panel.ha_alarm
        state: armed_away
      - condition: state
        entity_id: alarm_control_panel.ha_alarm
        state: armed_home        
  action:
    - service: alarm_control_panel.alarm_trigger
      entity_id: alarm_control_panel.ha_alarm
    - service: notify.pushover
      data_template:
        message: '{{ trigger.to_state.attributes.friendly_name }} opened'
      data:
        title: 'Alarm'

With that setup, it’s easy to integrate Zoneminder so that I only get motion alerts when the alarm panel is armed. First of all I added Zoneminder to HA in my configuration.yaml:

zoneminder:
  host: !secret zm_host
  path: /zm/
  path_zms: /cgi-bin-zm/nph-zms
  username: !secret zm_user
  password: !secret zm_password

I’m using the IP address of the host to bypass basic authentication, as discussed in my Zoneminder setup post. I then configured Zoneminder switches so that the cameras were set to “Monitor” when switched off and “Modect” when switched on:

switch:
  - platform: zoneminder
    command_on: Modect
    command_off: Monitor

I started with a setup that controlled the actual motion detection within Zoneminder itself – turning the motion detection off when the alarm was disarmed and vice versa. I then decided that I didn’t want to suppress the motion detection altogether, but only the notifications. If I was at home, with the alarm disarmed, I still wanted to be able to review motion events on the cameras – I just didn’t need to get the notifications.

To achieve that, I added a switch for each camera as an input_boolean:

input_boolean:
  front_garden_notify:
    name: Front Garden
  back_garden_notify:
    name: Back Garden
  side_gate_notify:
    name: Side Gate

I could then manage whether I got the notifications based on the switches. The alarm panel state automates turning the notifications on and off:

- id: '1563700555162'
  alias: Alarm armed away
  trigger:
  - entity_id: alarm_control_panel.ha_alarm
    platform: state
    to: armed_away
  condition: []
  action:
  - data:
      entity_id: input_boolean.back_garden_notify
    service: homeassistant.turn_on

I can also expose the switches to the front end and control them manually:

This set up gives me complete flexibility to manage motion detection and notifications separately. For the full setup:

  • Back garden camera: turn motion detection off altogether when the alarm is disarmed – there’s no point in capturing endless clips of myself in the garden.
  • Side gate camera: leave both motion detection and notifications on all the time – I rarely use the side gate, so I don’t get many notifications.
  • Front garden camera: leave motion detection on but never send notifications – I don’t really need to know every time someone walks up my drive to put junk mail through the door, but it’s good to have the events to review.

Finally, to get the actual motion events into HA, I used MQTT from zmEventNotificaton and set up sensors in HA to subscribe to the events. The topic names used the ID of the Zoneminder monitor and I mapped them to a meaningful sensor name:

- platform: mqtt
  state_topic: "zoneminder/3"
  name: "back_garden_alerts"

- platform: mqtt
  state_topic: "zoneminder/1"
  name: "front_garden_alerts"
  
- platform: mqtt
  state_topic: "zoneminder/2"
  name: "side_gate_alerts"

For the purposes of testing, I made the states visible in the front end. Every time motion is detected, the state changes:

To get notifications I simply needed to set up an automation that was triggered by the state change and sent a notification if the corresponding notify switch was turned on. I configured it in the GUI, but the corresponding YAML looks like this:

- id: '1565518521456'
  alias: Test alarm
  trigger:
  - entity_id: sensor.back_garden_alerts
    platform: state
  condition:
  - condition: state
    entity_id: input_boolean.back_garden_notify
    state: 'on'
  action:
  - data:
      message: Motion detected in back garden
      service: persistent_notification.create

I used the persistent notification for testing, but aimed to switch to Pushover when I was happy with it.

So far so good, but it has a limitation. Motion events tend to come in batches. If someone moves into range and is detected, a motion event will be fired. If they stop for a second or two and then move again, another motion event is detected. This can mean several notifications for what is, essentially, a single event.

I only really wanted a single notification. As soon as I got the first notification I’d be checking the cameras anyway, so the repeats would just be unnecessary and irritating. I needed a way to throttle the notifications so that I only got one for each camera within a certain time period.

I considered timers and trying to store the last time a camera triggered motion using an input_text box but the YAML was starting to get complicated. This was definitely an example of an automation that needed a proper programming language…

Luckily that’s possible with Home Assistant coupled with AppDaemon, and in the next instalment I’ll describe how I used AppDaemon to throttle the notifications.

in Home Automation

Related Posts