Page 1 of 1

Execute Program 30s After Creation of Event

Posted: Sat Dec 18, 2010 9:29 pm
by Dreded
I Have a door that nobody should ever walk in front of but the odd time(once a week maybe) car headlights will fly past the area.. so I would like to externally trigger a program to play a siren when there is motion in that area for more than 30seconds(that way someone is actually there)... so either trigger an event immediately on motion and I can setup some sort of timer and then send another event when the motion stops

or zoneminder executes an program after 30s when motion is created...

the current issue is the filters only get executed after the person damages whatever it is they are damaging and leaves the area and zone minder closes the event

Posted: Sun Dec 19, 2010 7:31 am
by CoYoTe
you can use a shell script in the event...

Code: Select all

ALARM event (play some sound on the audio out)
...
sleep 30
...
ALARM disable (stop playing)

Posted: Sun Dec 19, 2010 8:59 pm
by Dreded
Can you perhaps explain that a little more? what would cause the shell script to run? I need zoneminder to call up a script

Posted: Mon Dec 20, 2010 5:18 am
by Dreded
Ok well I made a solution myself with a bit of help from this post:
http://www.zoneminder.com/forums/viewtopic.php?t=13598

Code: Select all

#!/usr/bin/perl -w

#What Camera Do you want to Monitor?
my $mymonitor = 4;


use strict;
use ZoneMinder;
$mymonitor--;

$| = 1;

zmDbgInit( "myscript", level=>0, to_log=>0, to_syslog=>0, to_term=>1 );

my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS );

my $sql = "select M.*, max(E.Id) as LastEventId from Monitors as M left join Events as E on M.Id = E.MonitorId where M.Function != 'None' group by (M.Id)";
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 @monitors;
while ( my $monitor = $sth->fetchrow_hashref() )
{
push( @monitors, $monitor );
}

my $i = 0;
my $x = 0;
my $localstate = 0;
while (1) {
if ( zmMemVerify( $monitors[$mymonitor] ) ) {
        my $state = zmGetMonitorState( $monitors[$mymonitor] );
        my $event_id = zmGetLastEvent ( $monitors[$mymonitor] );
        my $name = $monitors[$mymonitor]->{Name};
        if (( $state == STATE_ALARM ) || ( $state == STATE_ALERT )) {
                $i++;
                system('clear');
                print "Monitor Name: " .$name. "       Event-ID: " .$event_id. "\n\n\n";
                print "Motion Actively Detected For: " .$x. "s\n";
                print "Currently On Alert For: " .$i. "s\n";
                $localstate = 1;
        }
        if (( $state == STATE_ALARM ) && ( $localstate == 1  )) {
                $x++;
        }

        if (( $state == STATE_IDLE ) && ( $localstate == 1  )) {
                system('killall mplayer');
                system('clear');
                print "Alarm stopped after " .$i. "s Event was: " .$event_id. "\n";
                $i = 0;
                $localstate = 0;
                $x = 0;
        }
        if (( $i == 60 ) || ( $x == 30  )) {
                system('mplayer -loop 0 alarm.mp3 </dev> /dev/null &');
        }
}
        sleep (1);
}
I included the audio playing bit so its more useful to the general user(i recommend finding a wav/mp3 of "Red Alert" from star trek) but my plan is to use a X10 Appliance module to play a 110v Fire Hall Siren(think WWII Bomb Siren)

Now I just need a way to reliably notify a cell phone :p

Posted: Mon Dec 20, 2010 6:42 am
by Flash_
Just a thought, keeping it simple;

Avoid zoneminder entirely. Add a PIR sensor (or old PIR light with the light bit removed) that activates a siren or lights as well.

If lights, that will trigger an event, so you have a record of what goes on.

Of course, will need some careful aiming to ensure cats don't trigger it...

Posted: Mon Dec 20, 2010 6:59 pm
by Dreded
The only issue with that is my intended purpose is to set off an alarm... notify my iPhone reliably(not e-mail) and with an alert loud enough to wake me up... I also need to be sure its constant motion if its going to wake me up :p not some dudes headlights swinging by

I did get all of this working last night... works flawlessly.. I saw ZoneMinder events created 2x for lights but I wasn't woken up at all :p and my system logged the event but not enough constant motion to trigger an alarm also wrote in a alarm clock for 8am to make sure that everything would work 10hours after I set it up :p

if anyone is interested if you have a jailbroken iphone and you understand what SSH is I can walk you through the notification alarm etc.

this is my final script:

Code: Select all

#!/usr/bin/perl -w

#What Camera Do you want to Monitor?
my $mymonitor = 2;


use strict;
use ZoneMinder;
use MIME::Lite::TT::HTML;
use DateTime;
my $dt = DateTime->now(time_zone => 'America/Vancouver');

my %params;
$params{first_name} = 'Bob';
$params{last_name}  = 'Loblaw';
my %options;
$options{INCLUDE_PATH} = './';

my $msg = MIME::Lite::TT::HTML->new(
            From        =>  'ZoneMinder@icomputeonline.net',
            To          =>  'dreded@dredx.com',
            Subject     =>  'ALARM ON BACK GATE!',
            Template    =>  {
                                text    =>  'zoneminder.txt.tt',
                                html    =>  'zoneminder.html.tt',
                            },
            TmplOptions =>  \%options,
            TmplParams  =>  \%params,
 );

$mymonitor--;

$| = 1;

zmDbgInit( "myscript", level=>0, to_log=>0, to_syslog=>0, to_term=>1 );

my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS );

my $sql = "select M.*, max(E.Id) as LastEventId from Monitors as M left join Events as E on M.Id = E.MonitorId where M.Function != 'None' group by (M.Id)";
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 @monitors;
while ( my $monitor = $sth->fetchrow_hashref() )
{
push( @monitors, $monitor );
}

my $i = 0;
my $x = 0;
my $localstate = 0;
my $alarmclock = 0;
system('clear');
print "Now Monitoring:  " .$monitors[$mymonitor]->{Name}. "\n";
while (1) {
$dt = DateTime->now(time_zone => 'America/Vancouver');
if ( zmMemVerify( $monitors[$mymonitor] ) ) {
        my $state = zmGetMonitorState( $monitors[$mymonitor] );
        my $event_id = zmGetLastEvent ( $monitors[$mymonitor] );
        my $name = $monitors[$mymonitor]->{Name};

#        if (( $dt->hour == 9 ) && ( $alarmclock == 0 )) {
#          $alarmclock = 1;
#          system('curl https://www.ultimatenotifier.com/items/User/send/dreded/message=Wake-Up!/password=password/sound=redalert.aiff &');
#        }


        if (( $state == STATE_ALARM ) || ( $state == STATE_ALERT )) {
                $i++;
                system('clear');
                $params{event_id} = $event_id;
                print "Monitor Name: " .$name. "       Event-ID: " .$event_id. "\n\n\n";
                print "Motion Actively Detected For: " .$x. "s\n";
                print "Currently On Alert For: " .$i. "s\n";
                if ($localstate == 0) { $localstate = 1; }
                if ($i == 1) {
                  system('paplay -s 192.168.2.33 --volume=35536 red_alert.wav &');
                  system('curl https://www.ultimatenotifier.com/items/User/send/dreded/message=MOTION%20ON%20BACK%20GATE!/password=password/sound=alert_4.caf &');
                }
                if (( $i >= 60 ) || ( $x >= 15  )) {
                  if (( $dt->hour() >= 18 ) || ( $dt->hour <8>= 1 )) {
                $x++;
        }

        if (( $state == STATE_IDLE ) && ( $localstate >= 1 )) {
                system('killall mplayer');
                system('clear');
                print "Alarm stopped after " .$i. "s Motion for: " .$x. "s\nEvent was: " .$event_id. "\n";
                $i = 0;
                $localstate = 0;
                $x = 0;
        }
        if (( $i == 60 ) || ( $x == 15  )) {
          if ( $localstate != 2 ) {
                $localstate = 2;
                if (( $dt->hour() >= 18 ) || ( $dt->hour <11>new(
                        From        =>  'ZoneMinder',
                        To          =>  'my-email@email.com',
                        Subject     =>  'ALARM ON BACK GATE!',
                        Template    =>  {
                                text    =>  'zoneminder.txt.tt',
                                html    =>  'zoneminder.html.tt',
                            },
                        TmplOptions =>  \%options,
                        TmplParams  =>  \%params,
                );
                $msg->send;
            }
          }
        }
}
        sleep (1);
}