E-mail trigger filter for number of events

Forum for questions and support relating to the 1.30.x releases only.
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

E-mail trigger filter for number of events

Post by Avro125 »

I have a camera that monitors a sump pump (https://en.wikipedia.org/wiki/Sump_pump) that's located in a crawl space. The water table is high here and the pump runs regularly. Failure of the pump would be a problem, and it's in a difficult place to physically check regularly, so I have a camera do the work for me.

I've got the motion detection pretty finely tuned so that it only triggers when the sump empties. It fills slowly enough that it stays below the motion threshold. After watching things for the last few months, I've determined what a normal pump cycling rate is: 2 to 4 times per hour. I can look at the ZM main page and see how many times the pump has run in the last hour/day/week etc. to determine if things are running smoothly.

To cover off for times when I'm not able to log in to the system, I'd like to create a filter that checks how many times the pump has run in the previous hour, and e-mail me if that number is less than 1 or more than 5. Zero is bad, as it indicates a pump failure. More than five times indicates either high flow rates or something else wrong.

So far, I've got the filter set up so that it will return results from that camera for the last hour. I can't seem to figure out how to use that resulting 'number of events' to send an e-mail. The goal is that when everything is normal I'd never hear from the ZM server. However, in the event of a pump failure it would e-mail me.

Any suggestions?
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

try 2 separate filters one for 0 events (failure) and one for the case >5 (flood). This is a pretty interesting use of ZM! I will set up a similar thing using a sink to test some filters and see how to set up the filters. it comes down to if 0 events email......over 5 events email...anything else leave me alone?
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

Yeah, two filters would work well. Provided of course I can get ZM to do something with the results other than the options of displaying, archiving and deleting.

There doesn't seem to be a lot of choice. Perhaps I could 'execute command on all matches', except in this case the critical point is when zero events match the filter, in which case there are no matches to execute a command.

Does anyone have experience with a filter that's contingent on the number of returns?
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

the filter does have the option to execute a system command so you could launch an external script....maybe a script that counts and has the logic whether or not to send the email. Something in PERL or BASH?
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

Hmmm.... that level of scripting is somewhat beyond my current capabilities, however I have a guy that could probably help me out.

If I'm successful, I'll post what I/we ended up with.

Thanks!
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

I will use my bathroom sink as the sump pit and see if I can scrap together some simple script that will enhance the filters.
Question...what is the period of time to test the case of 0 events (pump failure)?
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

For zero events, perhaps 90 minutes?

It's running pretty well now at 3, almost 4 cycles per hour. Once the snow is gone and things dry up, that number will drop considerably. The trigger threshold may be something I'd need to adjust seasonally. I've only got data back to late fall last year (when the camera went in) so I've yet to see a summer with it. Maybe I'll end up setting the zero-alarm to a few hours so as not to get unnecessary false notifications. Presently though, I wouldn't want to wait much more than an hour and a half before ZM said something.

A coworker of mine suggested that this type of check could be done by an analysis of the log file. Provided I do my job and get the motion settings correct, a simple x-number of events created for that monitor in the last y-amount of time should suffice.

Not sure what colour your sink is, but if you're trying motion on it you may have to put some floating items on top, lest the camera see straight through the water. I run my pump cam in monochrome, 2FPS, 720 resolution. I've drawn the motion area around the edges of the sump, avoiding the inlet as it tends to drip and bubble, causing a touch of 'motion' when it fills. The pump is able to empty the water in a few seconds, so that causes enough of a shakeup to make it through the detection process.

I'll post a few shots of what it looks like later today.

I appreciate the help!
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

Here's a shot of the sump, with motion analysis area highlighted. I've tried to avoid the inlet bubbles and ripples, as well as the discharge pipe and the pump itself.

Image

Slightly out of focus, as the camera is perhaps 1.5 meters above the floor. Still, motion works fine.
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

I have an idea about using an example script from ZM : https://github.com/ZoneMinder/ZoneMinde ... m-alarm.pl

a simple program that monitors the monitors for changes in state. idle,alarm.alert. Download this and run it in a terminal. Try forcing and alarm/event and see how the script behaves. I think i will be possible to use this idea to record the time each monitor goes to alarm or alert, then compare the current time to the last timestamp saved from the correct monitor....if no event is recorded during (Last Event + 90 minutes) then send an email. Or if there are more then 5 events in a certain period of time send an email. the PERL program can use the above example as the base and one could add the email function and the code to count the events probably fairly simply. I will try to patch this together and see how it works.
sdi
Posts: 5
Joined: Sun Jul 17, 2016 9:27 pm

Re: E-mail trigger filter for number of events

Post by sdi »

Hi. Did you implement a solution for this? I searched this forum since I wanted something similar to count the events over night and warn me where I had spider activity on my IR cameras (prompting me to clean the cameras rather than fill up my disk)
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

No, not yet. I've also yet to try the solution offered by rockedge above. I'm not that great when it comes to programming, so I'll have to get a colleague to help me fine tune the script.

We're experiencing similar issues I'd say: ZM can take action if there are recorded events, but not necessarily the number of events (or lack of events). I have the same issue with spider webs triggering multiple short events over the night.

A filter where
IF Monitor Name matches "y" AND number of events over the last "n" hours is less than (or greater than) "x", send e-mail
would be fantastic.

A company in similar business to my employer has a motion sensor (I'm assuming...) that monitors one of their control rooms. No motion for x-amount of time and it sends an alarm to another facility. As the control room is supposed to be staffed 24/7, it stands to reason there would be regular motion of personnel. No detected motion means there's a problem. So, there is a real-world market for 'no motion' causing an alert. Similarly, excessive motion is also cause for concern.

If I get something running, I'll post it here.
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

Here is a PERL program that runs as a daemon and checks zoneminder monitor status and if there are no 'Alarm' states after 90 minutes an email will be sent.
set the email to your specs. and the timer is $setseconds = 5400 (90 minutes).
$camera_id sets which camera the no event timer is monitoring.

The second program is the controller for the daemon.
/usr/bin/zmalarm5.pl

Code: Select all

#!/usr/bin/env perl

# While this script is running, it checks out the state of each monitor on the system.
# $setseconds is the time period in seconds to check for no Alarms.
# $camera_id sets which camera the no event timer is monitoring.
# 
use POSIX qw( strftime );
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP ();
use Email::Simple ();
use Email::Simple::Creator ();
use autodie;
use Proc::Daemon;
use strict;
use warnings;
use ZoneMinder;
use Switch;

my @monitors;
my $dbh = zmDbConnect();
my $sql = "SELECT * FROM Monitors";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
my $sttime = time;
my $diff = 0;
my $continue = 1;
my $camera_id = 2;
my $setseconds = 5400;

Proc::Daemon::Init;
$SIG{TERM} = sub { $continue = 0 };

open (my $LOG, '>>', '/var/log/zm-alarm5.log');
select $LOG;

$| = 1;

print localtime()." Started zmalarm5\r\n";
while ($continue) {
while ( my $monitor = $sth->fetchrow_hashref() ) {
    push( @monitors, $monitor );
}

while ($continue) {
        foreach my $monitor (@monitors) {
                my $monitorState = zmGetMonitorState($monitor);
                printState($monitor->{Id}, $monitor->{Name}, $monitorState);
        }
        sleep 1;
}

sub printState {
        my ($monitor_id, $monitor_name, $state) = @_;
        my $time = localtime();
        switch ($state) {
                case 0 { 
					$diff = time - $sttime;
	                  if ($diff >= $setseconds and $monitor_id = $camera_id){
						   noeventemail();
                      }
					}
                case 1 { 
#					print "$time - $monitor_name:\t Prealarm!\n" 
					}
                case 2 { 
					print "$time - $monitor_name:\t Alarm!  $diff\n"; 
					if ($monitor_id = $camera_id ){$sttime = time;}
#                    $sttime = time;
					}
                case 3 { 
#					print "$time - $monitor_name:\t Alert!\n" 
					}
        }
}

sub noeventemail {
my ($monitor_id, $monitor_name, $state) = @_;
my $dt = strftime("%a %B %H:%M:%S", localtime($sttime));
my $time = localtime();
my $smtpserver = 'smtp.gmail.com';
my $smtpssl = 'SSL';
my $smtpport = 465;
my $smtpuser   = 'some.name@gmail.com';
my $smtppassword = 'somepassword';

my $transport = Email::Sender::Transport::SMTP->new({
  host => $smtpserver,
  ssl  => $smtpssl,
  port => $smtpport,
  sasl_username => $smtpuser,
  sasl_password => $smtppassword,
 });

my $email = Email::Simple->create(
  header => [
    To      => 'needs.a.name@gmail.com',
    From    => 'some.name@gmail.com',
    Subject => 'No Events occured!',
  ],
  body => "From $dt until $time Monitor- $camera_id: No Events occured during this time period.\n",
 );
 
 sendmail($email, { transport => $transport });

	$sttime = time;
	print "$time Monitor - $camera_id:\t Sent!\n";
}	
}
print localtime()." Stopped zmalarm5\r\n";
close $LOG;
controller for the daemon. /etc/init.d/zmalarm5x.sh

Code: Select all

#!/bin/sh
zmalarm5_PID=/tmp/zmalarm5.pid
function show_status {
	if [ ! -f $zmalarm5_PID ]; then
		echo -e "zmalarm5 NOTRUNNING"
		exit 3
	fi
	
	PID=`cat ${zmalarm5_PID}`

	if [ ! -d /proc/${PID} &>/dev/null ]; then
		echo -e "zmalarm5 NOTRUNNING"
		exit 1
	fi

	echo -e "zmalarm5  RUNNING"
}

case "$1" in
    start)
	if [ -f /tmp/zmalarm5.pid ]; then
		PID=$(cat /tmp/zmalarm5.pid)
		kill -0 ${PID} &>/dev/null
		if [ $? = 0 ]; then
			echo "zmalarm5 is already running."
		else
			/usr/bin/zmalarm5.pl
#			pidof zmalarm5.pl > /tmp/zmalarm5.pid
			pgrep -f zmalarm5.pl > /tmp/zmalarm5.pid
			PID=$(cat /tmp/zmalarm5.pid)
			kill -0 ${PID} &>/dev/null
			if [ $? = 0 ]; then
				echo "zmalarm5 started succesfully."
			else
				echo "Error starting zmalarm5"
			fi
		fi
	else
		/usr/bin/zmalarm5.pl
#		pidof zmalarm5.pl > /tmp/zmalarm5.pid
		pgrep -f zmalarm5.pl > /tmp/zmalarm5.pid
		PID=$(cat /tmp/zmalarm5.pid)
		kill -0 ${PID} &>/dev/null
		
		if [ $? = 0 ]; then
			echo "zmalarm5 started succesfully."
		else
			echo "Error starting zmalarm5"
		fi
        fi
        ;;
    stop)
	if [ -f /tmp/zmalarm5.pid ];then
		PID=$(cat /tmp/zmalarm5.pid)
		kill -0 ${PID} &>/dev/null
		rm -f /tmp/zmalarm5.pid
		if [ $? = 0 ]; then
			/bin/kill ${PID}
			kill -0 ${PID} &>/dev/null
			if [ $? = 0 ]; then
				echo "zmalarm5 stopped succesfully."
			else
				echo "Error stopping zmalarm5"
			fi
		else
			echo "zmalarm5 is already stopped."
		fi
	else
		echo "zmalarm5 is already stopped."
	fi
        ;;
    reload|restart)
        $0 stop
        $0 start
        ;;
    status)
		show_status
		;;
    *)
        echo "Usage: $0 start|stop|restart|reload|status"
        exit 1
esac
exit 0
Last edited by rockedge on Mon Apr 17, 2017 1:41 am, edited 2 times in total.
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

the working code is in the post above. Tested with ZM 1.30.2
Avro125
Posts: 21
Joined: Sun Jun 26, 2016 12:39 pm
Location: Canada

Re: E-mail trigger filter for number of events

Post by Avro125 »

This looks awesome. Thanks for the work on it!

I've loaded both files onto the computer (create the file, paste the script, save and close). I changed the mail server info to reflect the fact that I'm using port 25 SMTP (no login required). Other than that, it's line for line. For testing I set the interval to 300 seconds (5 mins), but will obviously change it back to a more reasonable number once I get this working.

I'm getting the following error:

Code: Select all

Can't locate Email/Sender/Simple.pm in @INC (you may need to install the Email::Sender::Simple module) 
(@INC contains: /home/zoneminder/perl5/lib/perl5/5.22.1/x86_64-linux-gnu-thread-multi 
/home/zoneminder/perl5/lib/perl5/5.22.1 
/home/zoneminder/perl5/lib/perl5/x86_64-linux-gnu-thread-multi 
/home/zoneminder/perl5/lib/perl5 /etc/perl 
/usr/local/lib/x86_64-linux-gnu/perl/5.22.1 
/usr/local/share/perl/5.22.1 
/usr/lib/x86_64-linux-gnu/perl5/5.22 
/usr/share/perl5 
/usr/lib/x86_64-linux-gnu/perl/5.22 
/usr/share/perl/5.22 
/usr/local/lib/site_perl 
/usr/lib/x86_64-linux-gnu/perl-base .) at zmalarm5.pl line 8.
BEGIN failed--compilation aborted at zmalarm5.pl line 8.
I'm running Ubuntu 16.04, and didn't have the mail sender installed, so I did that. I've rebooted, still getting the error.

Any ideas?
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: E-mail trigger filter for number of events

Post by rockedge »

you will need to use cpan or find the lib through the package manager. What is happening is your missing some of the needed PERL modules. Easy to fix. cpan and cpanm works best for me. First set up cpanm by typing this in a terminal.

Code: Select all

#cpan App::cpanminus
#cpanm Email::Sender::Simple
#cpanm Proc::Daemon;
try running it again and notice the error logged. If it is a PERL module missing, add it using cpanm in the same fashion as above. Repeat until all the modules are present and the daemon runs clean and sends an email.
Locked