Page 1 of 1

Running script on alarm

Posted: Tue Dec 31, 2013 2:35 pm
by tommycw1
Hello all,

Used ZM years ago and am coming back to it again.

I want to trigger an x10 event when a ZM monitor goes into alarm, problem is that I am running heyu on the same machine so it has my x10 CM11a tied up, so I decided to try to just have ZM trigger another script where I'll run a heyu command to trigger my x10 event.

I found on the FAQ page there is a script to do exactly this:

http://www.zoneminder.com/wiki/index.ph ... n_alarm.3F

Code: Select all

#!/usr/bin/perl -w

use strict;

use ZoneMinder;

$| = 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 );
}

while( 1 )
{
    foreach my $monitor ( @monitors )
    {
        next if ( !zmMemVerify( $monitor ) );
 
        if ( my $last_event_id = zmHasAlarmed( $monitor, $monitor->{LastEventId} ) )
        {
            $monitor->{LastEventId} = $last_event_id;
            print( "Monitor ".$monitor->{Name}." has alarmed\n" );
            #
            # Do your stuff here
            #
        }
    }
    sleep( 1 );
}
I am trying to run this script but I get an error:

Code: Select all

$ ./zmtest.pl 
Undefined subroutine &main::zmDbgInit called at ./zmtest.pl line 9.
I have ZM 1.25 installed and the ZoneMinder Perl Module is installed. Anyone able to shed any light on this problem?

Tom

Re: Running script on alarm

Posted: Fri Jan 10, 2014 9:32 pm
by Gibby13
Did you ever figure this out? I am having the same issue.

Re: Running script on alarm

Posted: Fri Jan 10, 2014 9:43 pm
by Gibby13
I am using this and it works:

Code: Select all

#!/usr/bin/perl -w

use strict;

use ZoneMinder;
use warnings;
use DBI;

$| = 1;


my $driver = "mysql";
my $database = "zm";
my $user = "zmuser"; 
my $password = "zmpass";

my $dbh = DBI->connect(
"DBI:$driver:$database",
$user, $password,
) or die $DBI::errstr;

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 );
}

while( 1 ) 
{
    foreach my $monitor ( @monitors )
    {   
        next if ( !zmMemVerify( $monitor ) );
 
        if ( my $last_event_id = zmHasAlarmed( $monitor, $monitor->{LastEventId} ) ) 
        {   
            $monitor->{LastEventId} = $last_event_id;
            print( "Monitor ".$monitor->{Name}." has alarmed\n" );
            #   
            # Do your stuff here
            #   
        }   
    }   
    sleep( 1 );
}


Re: Running script on alarm

Posted: Fri Feb 14, 2014 11:25 pm
by benwa
Is is possible to obtain the zone that triggered and the score when using the perl script? It appears that zmMemRead() can get the cause/zone and score but my code below doesn't work. Any ideas why?
Thanks

Code: Select all

#!/usr/bin/perl -w

use strict;

use ZoneMinder;
use Data::Dumper;

# see bottom of /usr/share/perl5/ZoneMinder/Memory.pm for what variables can be read. Can't find a way to read Alarm frames count or duration.
# Dumper($monitor) will also show elements of the hash but these are mostly fixed settings related to the camera.

$| = 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 $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) having Name = 'Driveway'";
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 );
}

while( 1 )
{
    foreach my $monitor ( @monitors )
    {
        next if ( !zmMemVerify( $monitor ) );

        if ( my $last_event_id = zmHasAlarmed( $monitor, $monitor->{LastEventId} ) )
        {
            $monitor->{LastEventId} = $last_event_id;
            # these do not work. Only returns data when forced trigger. 
            my $cause = zmMemRead($monitor, 'trigger_data:trigger_cause');
            my $score = zmMemRead($monitor, 'trigger_data:trigger_score');
            print( "Monitor ".$monitor->{Name}." ".$monitor->{LastEventId}." has alarmed - Score:" . $score . " cause:". $cause ."\n" );
            if ($monitor->{Name} eq 'Driveway') {
              if ($cause =~ /closest/ && $score gt 40) {
                print "Wet the cat\n";
              }
            }
            while (zmInAlarm($monitor)) { }; # stops repetitively entering this "if" condition on same event.
            print ("Out of alarm state\n");
        }
    }
    sleep( 1 );
}