Zoneminder – a love/hate relationship

I have something of a love/hate relationship with Zoneminder. On the plus side, it’s probably the most comprehensive and full featured open source CCTV system for Linux. The downside is that it’s an architectural mess that can’t cope well with modern high resolution cameras.

Until recently I only had one camera at the front of the house feeding into both Zoneminder and Surveillance Station on my Synology NAS. Zoneminder was performing motion detection on the low resolution feed from the camera and I had the Synology capturing the high resolution feed 24×7. I also had Netgear Arlo, with cameras covering the side door and back garden.

The problem with the Arlo cameras was that they were sluggish in responding to motion. The cameras, being battery operated, only record once motion is detected. Unfortunately, by the time the recording started it was often too late – the triggering object having already moved out of shot. Zoneminder gets around that issue in two ways. Firstly, it starts capturing from the first frame in which motion is detected and secondly it maintains a buffer to allow the motion clip to contain a few seconds prior to the actual motion.

I decided to replace the Arlo cameras with two cheap Wifi cameras. I chose WiFi because it was much easier to get power to the right locations than run ethernet cable, otherwise PoE would’ve been a better choice. Both cameras have a maximum resolution of 1280×720, which is more than sufficient for their location. The other camera, that was already being managed by Zoneminder, runs at 1920×1080. All three have been set to run at 10fps, which is enough for reasonable clarity without generating excessive data.

Zoneminder is pretty hopeless with high resolution feeds. It works by breaking down the incoming video feed into individual jpg images for analysis and then stores them as individual frames. When you review or download videos, it has to stitch the frames back together. It’s processor and storage intensive, and simply can’t cope with multiple high resolution cameras without some fairly substantial kit to run it on.

I’d hoped that upgrading to the latest Zoneminder release would help, as it now has a video passthrough feature so that it can save direct to video files. Unfortunately it still has to break down the incoming feed for motion detection, which is the main bottleneck.

In theory you can set up the low and high resolution feeds as separate cameras in Zoneminder, perform the motion detection on the lower resolution camera and link that to the high resolution version, so that it only records the high resolution video when motion is detected on the lower resolution images. Unfortunately, that doesn’t really help. It turns out that it still breaks the high resolution stream into individual frames even if you’re not performing motion detection.

Zoneminder’s motion detection is its strength, and can be tweaked to minimise the false positives that plague most motion detection systems that only have access to images. It’s certainly far more advanced than the simple system in Surveillance Station.

That said, the PIR sensors in the Arlos were much less prone to the false positives generated by changes in the light, and it’s almost impossible to avoid false positives without also missing out on motion that you’re actually interested in. It’s not a criticism of Zoneminder as such – any system that detects motion by comparing images will suffer from the same problem, especially on sunny days – it just takes a cloud obscuring the sun for the light to change enough to trigger a motion event.

Another limitation of Zoneminder is the filter system for responding to events. Filters run in the background and execute queries against the Zoneminder database, acting on the results. By default, they run every 20s and can be used to send email alerts. They can also be configured to run arbitrary scripts if you need a different alerting mechanism.

It’s quite an inefficient way of alerting, and means that there’s always a delay of up to 20s before alerts are sent. Maybe not critical, but it amazes me that there isn’t, by default, a way to trigger alerts as soon as they occur.

Aside from all of that, Zoneminder itself is something of a mess of technologies – it’s written in a combination of C++, Perl, PHP and Javascript. It can be awkward to install and getting it set up for secure access over the internet requires intimate knowledge of configuring Apache.

So why do I persist with Zoneminder?

It turns out that there is a way to fix some of the problems by using a great add-on written by Pliable Pixels, who is also responsible for the excellent zmNinja app for Zoneminder.

zmEventNotification brings machine learning based object detection to ZoneMinder, coupled with a truly responsive notification system. The object detection features adds a layer to existing motion detection – when a motion event occurs, the results are analysed and alerts can be raised only if certain objects – such as a person or car – are detected.

The notification system in zmEventNotification is designed mainly to work with the zmNinja app, but it also supports MQTT, which makes it easy to pass events to Home Assistant. Home Assistant also has a Zoneminder integration that can control the operation of motion sensing.

That opens up a whole new level of flexibility. Home Assistant knows when I’m home, so I can use that to selectively switch motion detection off for cameras that would otherwise generate alerts when I’m home. For example, I have a camera covering my garden that is automatically switched off when I’m home during the day, but is switched back on again at night when I’m unlikely to be in the garden.

Coupling the machine learning object detection with presence detection from Home Assistant, I’ve been able to set up a system that completely eliminates false alerts while still picking up genuine events that I want to know about.

In my next post, I’ll talk about how I got it all set up.

in Home Automation

Related Posts