New ZoneMinder API

@wjbeckett I agree, pyzm will not make it easier to get the desired notifications out of zoneminder/zmeventnotification-server (ES). Given I recently went through this effort, I found the main areas to focus are on how you invoke dlandon’s docker image (I just set it up to install all the image processing libraries) and properly configuring ES via the .ini files located in /etc/zm internal to the running container. If you are running docker-hassio on the same host as zoneminder, you will need to adjust the exposed listening ports via this same command line.
Debugging iterated through the following steps:

I must say I like the MQTT events as a simple/clean way to push these notifications into HA. I was attempting to use these events to trigger an automation to message/text the notes/info text inside the ES notification plus the objectdetect image associated with the notification event. This is available via the old URL based zoneminder API but have not found it yet in the pyzm API.

Thus far, pyzm is a piece of cake to set and pull info from zoneminder. However, I have yet to find a way to easily pull an event image e.g. objectdetect, snapshot, or explicit fid? I am looking for a method on the Event object or ZMApi and don’t see one. Perhaps @pliablepixels can comment?

That is correct. Pulling an image isn’t actually part of the ZM API per se. It uses https://portal/zm/index.php?view=image (not /zm/api) so as of now pyzm does the api wrapper part but I’m not averse to adding wrappers for direct media access too. Of course, PRs are very welcome - these days I’m context switching so much between zmNinja, zmMagik, zmES and mlapi, I’ve come to a stage where I completely forget what I did a week ago in any of these projects and have to relearn…

Understood, I prototyped a child class of ZMApi with a get_event_image(…) method using that URL template (you provided in your documentation… thanks). I was able to retrieve a local copy of the alarm, snapshot, or objectdetect frame. However, your _make_request(…) method returns the r.json() version of the response which caused problems when trying to pull a raw copy.

Specifying this uri for sending text message was the area I was unhappy with in HA. Trying to code via HA yaml and feed the uri to notify caused me some grief (very cryptic error messages).Using the python requests api (emulating what you did) combined with the token based auth was rock solid in retrieving these image files (beat the heck out of it).

Happy to post a PR to your zmeventnotification github project. I will do that this weekend. LMK if you prefer a different avenue. Thanks again for the fast response.

A PR would be nice. It might be a good idea to extend pyzm.helpers.Event.Event (ref) with functions to return the associated:

  • video
  • arbitrary image at an index (fid, snapshot, objdetect, alarm)

That way we can chain APIs easily.

I do have my docker setup correctly and currently feeding MQTT events into HA. That’s not the problem I have.
The problem I have is that this is the output ZoneMinder is sending to over MQTT:

{"hookvalue":"0","eventtype":"event_start","monitor":"1","state":"alarm","name":"Front Door:(1037) [a] detected:person:52% Motion Driveway","eventid":"1037"}

What I am trying to do is use some of the data from that in my automations.
For example, I currently use Deepstack to process my images and notify if a person is at the front door. However, lately ZoneMinder has been more accurate. So I’d like to be able to use the MQTT data from ZoneMinder but not send all of the above text. I’d like to be able to have a notification just send:
“Person or Car detected at the front door”

However I’m having a hard time extracting just the “Person” or “Car” from the above MQTT data and use that in a HA notify action.

For example, my current deepstack automation looks like this:

- id: person_detection
  alias: Notify when person detected
  initial_state: 'on'
  hide_entity: true
  condition:
  - condition: state
    entity_id: input_boolean.options_notifications_push
    state: 'on'
  trigger:
    platform: event
    event_type: image_processing.object_detected
    event_data:
      object: person
  action:
    - delay: 00:00:02
    - service: notify.telegram
      data_template:
        message: '{{ trigger.event.data.object }} detected at the front door'
        data:
          photo: 
            - file: '{{ states.camera.deepstack_latest_person.attributes.file_path }}'
              caption: Person Detected

Deepstack gives me the object as “person” or “car” so I can easily use that. I would like to find a way to do it with ZoneMinder. And if I can have the detection image from ZoneMinder included as well, then that would be perfect.

Any suggestion on how I can grab the “person” or “car” plus the detected image from ZoneMinder to use in HA?

1 Like

Ha! You are much more advanced than I :blush:
Yep, I have struggled with parsing the MQTT notification data also.

I did get as far as parsing out the name field using sensor/mqtt yaml descriptions such as this for my garage camera with zoneminder monitor id 1. This breaks out the eventid and the name/description string containing the message from yolo3?

sensor:
  - platform: mqtt
    name: "garage alert id"
    state_topic: "zoneminder/1"
    value_template: "{{ value_json.eventid }}"
  - platform: mqtt
    name: "garage alert desc"
    state_topic: "zoneminder/1"
    value_template: "{{ value_json.name }}"

I used the eventid to build a url (zoneminder api) to include the image as part of the text message sent via hangouts. I used the *garage alert desc" as the body of the text message. However, once I tightened up the authentication on zoneminder, the url building became too cumbersome for me. The only way I came up with is to write python code to do the fine grain parsing you are suggesting. I suspect you could do it via function nodes in node red but I elected to use the appdaemon approach and write an app to implement the automation script in python.

BTW, in case you didn’t see it, I provided a link to this blog article which provides the code he wrote for his appdaemon script/app. Note the image at the top of the article is his alert message via pushover. I was trying to duplicate that via hangups.

Below is the automation I used with the above sensor definition. I should note the garage notify boolean is a gate that allows me to easily shut off the alerts. I gave up on it (this automation) as I indicated and am now coding an app. Within the app, I am using pyzm to login to my zoneminder server and pull the objectdetect image associated with the event id.

- id: '1580088839247'
  alias: garage security alert
  description: ''
  trigger:
  - entity_id: sensor.garage_alert_id
    platform: state
  condition:
  - condition: state
    entity_id: input_boolean.garage_notify
    state: 'on'
  action:
  - data_template:
      message: 'Alert {{ states.sensor.garage_alert_desc.state }} at {{ now().strftime(''%H:%M %A %d %B %Y'') }} '
      data:
        image_file: "https://mydomain.duckdns.org/zm/index.php?view=image&eid={{ states('sensor.garage_alert_id') }}&fid=objdetect&width=600"
      title: Garage Security Alert
    service: notify.home_hangouts

I see you are using telegram, part of my problem may be trying to use hangouts. Really would like to stick with it since I use hangouts from my desktop browser gmail app and don’t want another messaging app.

Hopefully, this info is of use to you or someone reading this discussion. Apologies for implying you might not have zoneminder set up, obviously you are farther along than me.

Cheers

1 Like

This is exactly what I needed to get the info into my notifications. Thank you so much!
Now I should be able to use some splits to pull out his the “person” or “car” text from the event name.

Thank you again.

Thanks, nice of you to comment. I am curious which part was helpful?

Cheers

https://github.com/pliablepixels/zmeventnotification/issues/206 - I’ve just made an update to send out a nice JSON structure too. Testing at the moment. It may be a few days before it shows up in dlandon’s docker as he syncs based on his free time and only after I tag the release. If you are adventurous you can manually grab the updated ES+detection modules to test or wait a few days.

@pliablepixels amazing!
If I just replace the updated files, will that be enough?
Are each of your services (zm, zmevent, ml) available as separate containers (I know zm is. But I want the zmevent and ml pieces too)? I’d rather be able to update as soon as you push features.

Honestly, it was just the value templates from the mqtt sensors you setup. And then seeing how they were used. It helped me think of how I could utilise it too.

@pliablepixels Just completed the prototype of the appdaemon app (github:zmnotify)
I wrote up a feature request like we discussed on your github:zmeventnotification.

Working great except I need to understand how to leverage the
throttling you mentioned. Looking at that now.

Here is a snapshot.
zmnotify

Cheers

1 Like

One item I forgot to mention. Adding the pyzm package required changes to config for the Appdaemon addon. The build of pyzm was failing due to build failure in psutil.

This is version 0.1.2 of AppDaemon 4.
Config

{
  "system_packages": [
    "python3-dev",
    "gcc",
    "libc-dev",
    "linux-headers"
  ],
  "python_packages": [
    "pyzm"
  ],
  "init_commands": [
    "apk update"
  ],
  "log_level": "info"
}

@pliablepixels i’m not advanced enough to write something like this, but wondered if this API could be used to create a lovelace card to list alarm events with hook detection and the links to their videos?
I know ZMNinja has an option to show only items that are detected. In theory then, knowing that its been a positive trigger from detection, with the event_id and the portal URL one could pull a list of events from a user specified time period in a lovelace card?
This with Dlandon’s docker would make for a killer HA single Lovelace page for home security

Absolutely. Super simple do with pyzm. Here is the full code that lists only events detected with objects from all monitors for the last 1 day. You can easily integrate this with a card.

import pyzm.api as zmapi

api_options = {
    'apiurl': 'https://yourserver/zm/api',
    'portalurl': 'https://yourserver/zm',
    'user': 'admin',
    'password': 'password',
    'logger': None # use none if you don't want to log to ZM
}

zmapi = zmapi.ZMApi(options=api_options)

event_filter = {
    'from': '1 day ago', # this will use localtimezone, use 'tz' for other timezones
    'object_only':True,
}
events = zmapi.events(event_filter)
for e in events.list():
  print ('Monitor:{} Event:{} Notes:{} Detected Frame URL:{}'.format(e.monitor_id(),e.id(),e.notes(), e.get_image_url(fid='objdetect')))
2 Likes

Is there an easy way of creating a sensor based on the mqtt data from zoneminder… I’m thinking a person detected sensor that simply shows the time and date the last time a person was detected… it could work like motion sensors showing no detection by default and detected when a person is seen. I’m new to mqtt so feel a bit lost here

Sure is, look at the mqtt sensor config and the mqtt payload from a zm event. I don’t have access to my exact code to share

I provided an example of a sensor that does what you request earlier in this discussion.

The mqtt topics are enabled via configuring the ES (event server). The topic is based on the monitor id e.g. 1 in my example. I break out the event id field, you can use this as a trigger given zoneminder increments the event id as it generates motion events.

HTH

1 Like

I cracked it in the end by writing an app for the app daemon. I set up a virtual pir sensor and powered it using my code so it came “on” for 30 seconds every time a person is detected… I posted about it under the configuration topic on here

Hi

I installed dlandon’s docker zomeminder yesterday and I’ve enabled mqtt in the zmeventnotification.ini

I was wondering if there is an easy way to trigger a ‘force alarm’ event on a monitor to trigger a recording in ZM from home assistant?

I’d like to use home assistant sensors to decide when to record video, rather than using the motion detection in zoneminder.

Thanks
Mike

Edit - I found this but I’d like an easier method :smiley:

Edit 2 - I think this might be the way to go. --> https://gist.github.com/swilson/89096c289d07fdf7d5d92796354a7b19