Merge pull request #815 from onlyjob/PBP

last batch of POD and readability conversions for *.pl scripts
This commit is contained in:
Isaac Connor 2015-04-16 11:53:19 -04:00
commit e69fee1c94
8 changed files with 1381 additions and 1102 deletions

View File

@ -2,7 +2,7 @@
# #
# ========================================================================== # ==========================================================================
# #
# ZoneMinder Update Script, $Date$, $Revision$ # ZoneMinder systemctl wrapper, $Date$, $Revision$
# Copyright (C) 2001-2008 Philip Coombes # Copyright (C) 2001-2008 Philip Coombes
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
@ -20,25 +20,39 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This is a wrapper script that allows zoneminder to start and stop itself =head1 NAME
# in a manner that keeps it in-sync with systemd. This script is intended
# to be called internally by zoneminder and may not give the desired results zmsystemctl.pl - ZoneMinder systemctl wrapper
# if run from the command line.
# =head1 SYNOPSIS
zmsystemctl.pl {start|stop|restart|version}
=head1 DESCRIPTION
This is a wrapper script that allows zoneminder to start and stop itself
in a manner that keeps it in-sync with systemd. This script is intended
to be called internally by zoneminder and may not give the desired results
if run from the command line.
=cut
use warnings; use warnings;
use strict; use strict;
use bytes; use bytes;
use autouse 'Pod::Usage'=>qw(pod2usage);
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
use ZoneMinder::Logger qw(:all); use ZoneMinder::Logger qw(:all);
my $command = $ARGV[0]; my $command = $ARGV[0];
if ( (scalar(@ARGV) == 1) && ($command =~ /^(start|stop|restart|version)$/ )) { if ( (scalar(@ARGV) == 1)
&& ($command =~ /^(start|stop|restart|version)$/ )
){
$command = $1; $command = $1;
} else { } else {
die(" USAGE: zmsystemctl.pl <start|stop|restart|version>\n"); pod2usage(-exitstatus => -1);
} }
my $path = qx(which systemctl); my $path = qx(which systemctl);

View File

@ -20,10 +20,26 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This script is used to trigger and cancel alarms from external sources =head1 NAME
# using an arbitrary text based format
# zmtrack.pl - ZoneMinder Experimental PTZ Tracking Script
=head1 SYNOPSIS
zmtrack.pl -m <monitor>
zmtrack.pl --monitor=<monitor>
=head1 OPTIONS
-m<monitor>, --monitor=<monitor> - Id of the monitor to track
=head1 DESCRIPTION
This script is used to trigger and cancel alarms from external sources
using an arbitrary text based format.
=cut
use strict; use strict;
use bytes; use bytes;
@ -45,8 +61,9 @@ use constant SLEEP_TIME => 10000; # In microseconds
use ZoneMinder; use ZoneMinder;
use DBI; use DBI;
use POSIX; use POSIX;
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
use Getopt::Long; use Getopt::Long;
use autouse 'Pod::Usage'=>qw(pod2usage);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
$| = 1; $| = 1;
@ -57,20 +74,8 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my $mid = 0; my $mid = 0;
sub Usage GetOptions( 'monitor=s'=>\$mid )
{ or pod2usage(-exitstatus => -1);
print( "
Usage: zmtrack.pl -m <monitor>,--monitor=<monitor>]
Parameters are :-
-m<monitor>, --monitor=<monitor> - Id of the monitor to track
");
exit( -1 );
}
if ( !GetOptions( 'monitor=s'=>\$mid ) )
{
Usage();
}
logInit(); logInit();
logSetSignal(); logSetSignal();
@ -78,14 +83,22 @@ logSetSignal();
my ( $detaint_mid ) = $mid =~ /^(\d+)$/; my ( $detaint_mid ) = $mid =~ /^(\d+)$/;
$mid = $detaint_mid; $mid = $detaint_mid;
print( "Tracker daemon $mid (experimental) starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); print( "Tracker daemon $mid (experimental) starting at "
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
."\n"
);
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
my $sql = "select C.*,M.* from Monitors as M left join Controls as C on M.ControlId = C.Id where M.Id = ?"; my $sql = "SELECT C.*,M.* FROM Monitors as M
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); LEFT JOIN Controls as C on M.ControlId = C.Id
WHERE M.Id = ?"
;
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $mid ) or Fatal( "Can't execute '$sql': ".$sth->errstr() ); my $res = $sth->execute( $mid )
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
my $monitor = $sth->fetchrow_hashref(); my $monitor = $sth->fetchrow_hashref();
if ( !$monitor ) if ( !$monitor )
@ -141,8 +154,16 @@ sub Track
my ( $detaint_x ) = $x =~ /^(\d+)$/; $x = $detaint_x; my ( $detaint_x ) = $x =~ /^(\d+)$/; $x = $detaint_x;
my ( $detaint_y ) = $y =~ /^(\d+)$/; $y = $detaint_y; my ( $detaint_y ) = $y =~ /^(\d+)$/; $y = $detaint_y;
my $ctrlCommand = $Config{ZM_PATH_BIN}."/zmcontrol.pl -i ".$monitor->{Id}; my $ctrlCommand = $Config{ZM_PATH_BIN}
$ctrlCommand .= " --command=".($monitor->{CanMoveMap}?"moveMap":"movePseudoMap")." --xcoord=$x --ycoord=$y"; ."/zmcontrol.pl -i "
.$monitor->{Id}
;
$ctrlCommand .= " --command="
.( $monitor->{CanMoveMap} ? "moveMap"
: "movePseudoMap"
)
." --xcoord=$x --ycoord=$y"
;
executeShellCommand( $ctrlCommand ); executeShellCommand( $ctrlCommand );
} }
@ -150,10 +171,15 @@ sub Return
{ {
my $monitor = shift; my $monitor = shift;
my $ctrlCommand = $Config{ZM_PATH_BIN}."/zmcontrol.pl -i ".$monitor->{Id}; my $ctrlCommand = $Config{ZM_PATH_BIN}
."/zmcontrol.pl -i "
.$monitor->{Id}
;
if ( $monitor->{ReturnLocation} > 0 ) if ( $monitor->{ReturnLocation} > 0 )
{ {
$ctrlCommand .= " --command=presetGoto --preset=".$monitor->{ReturnLocation}; $ctrlCommand .= " --command=presetGoto --preset="
.$monitor->{ReturnLocation}
;
} }
else else
{ {
@ -193,7 +219,10 @@ while( 1 )
print( "Left alarm state\n" ); print( "Left alarm state\n" );
$alarmed = undef; $alarmed = undef;
} }
if ( ($monitor->{ReturnLocation} >= 0) && ($last_alarm > 0) && ((time()-$last_alarm) > $monitor->{ReturnDelay}) ) if ( ($monitor->{ReturnLocation} >= 0)
&& ($last_alarm > 0)
&& ((time()-$last_alarm) > $monitor->{ReturnDelay})
)
{ {
Debug( "Returning to location ".$monitor->{ReturnLocation}."\n" ); Debug( "Returning to location ".$monitor->{ReturnLocation}."\n" );
Suspend( $monitor ); Suspend( $monitor );

View File

@ -20,11 +20,17 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This script is used to trigger and cancel alarms from external connections =head1 NAME
# using an arbitrary text based format
# zmtrigger.pl - ZoneMinder External Trigger Script
# ==========================================================================
=head1 DESCRIPTION
This script is used to trigger and cancel alarms from external connections
using an arbitrary text based format
=cut
use strict; use strict;
use bytes; use bytes;
@ -52,8 +58,22 @@ use ZoneMinder::Trigger::Channel::Serial;
use ZoneMinder::Trigger::Connection; use ZoneMinder::Trigger::Connection;
my @connections; my @connections;
push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan1", channel=>ZoneMinder::Trigger::Channel::Inet->new( port=>6802 ), mode=>"rw" ) ); push( @connections,
push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan2", channel=>ZoneMinder::Trigger::Channel::Unix->new( path=>$Config{ZM_PATH_SOCKS}.'/zmtrigger.sock' ), mode=>"rw" ) ); ZoneMinder::Trigger::Connection->new(
name=>"Chan1",
channel=>ZoneMinder::Trigger::Channel::Inet->new( port=>6802 ),
mode=>"rw"
)
);
push( @connections,
ZoneMinder::Trigger::Connection->new(
name=>"Chan2",
channel=>ZoneMinder::Trigger::Channel::Unix->new(
path=>$Config{ZM_PATH_SOCKS}.'/zmtrigger.sock'
),
mode=>"rw"
)
);
#push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan3", channel=>ZoneMinder::Trigger::Channel::File->new( path=>'/tmp/zmtrigger.out' ), mode=>"w" ) ); #push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan3", channel=>ZoneMinder::Trigger::Channel::File->new( path=>'/tmp/zmtrigger.out' ), mode=>"w" ) );
#push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan4", channel=>ZoneMinder::Trigger::Channel::Serial->new( path=>'/dev/ttyS0' ), mode=>"rw" ) ); #push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan4", channel=>ZoneMinder::Trigger::Channel::Serial->new( path=>'/dev/ttyS0' ), mode=>"rw" ) );
@ -65,7 +85,7 @@ push( @connections, ZoneMinder::Trigger::Connection->new( name=>"Chan2", channel
use DBI; use DBI;
#use Socket; #use Socket;
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
use POSIX qw( EINTR ); use POSIX qw( EINTR );
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
@ -126,12 +146,22 @@ while( 1 )
{ {
if ( vec( $rout, $connection->fileno(), 1 ) ) if ( vec( $rout, $connection->fileno(), 1 ) )
{ {
Debug( "Got input from connection ".$connection->name()." (".$connection->fileno().")\n" ); Debug( "Got input from connection "
.$connection->name()
." ("
.$connection->fileno()
.")\n"
);
if ( $connection->spawns() ) if ( $connection->spawns() )
{ {
my $new_connection = $connection->accept(); my $new_connection = $connection->accept();
$spawned_connections{$new_connection->fileno()} = $new_connection; $spawned_connections{$new_connection->fileno()} = $new_connection;
Debug( "Added new spawned connection (".$new_connection->fileno()."), ".int(keys(%spawned_connections))." spawned connections\n" ); Debug( "Added new spawned connection ("
.$new_connection->fileno()
."), "
.int(keys(%spawned_connections))
." spawned connections\n"
);
} }
else else
{ {
@ -150,7 +180,12 @@ while( 1 )
{ {
if ( vec( $rout, $connection->fileno(), 1 ) ) if ( vec( $rout, $connection->fileno(), 1 ) )
{ {
Debug( "Got input from spawned connection ".$connection->name()." (".$connection->fileno().")\n" ); Debug( "Got input from spawned connection "
.$connection->name()
." ("
.$connection->fileno()
.")\n"
);
my $messages = $connection->getMessages(); my $messages = $connection->getMessages();
if ( defined($messages) ) if ( defined($messages) )
{ {
@ -162,7 +197,12 @@ while( 1 )
else else
{ {
delete( $spawned_connections{$connection->fileno()} ); delete( $spawned_connections{$connection->fileno()} );
Debug( "Removed spawned connection (".$connection->fileno()."), ".int(keys(%spawned_connections))." spawned connections\n" ); Debug( "Removed spawned connection ("
.$connection->fileno()
."), "
.int(keys(%spawned_connections))
." spawned connections\n"
);
$connection->close(); $connection->close();
} }
} }
@ -197,13 +237,22 @@ while( 1 )
my @out_messages; my @out_messages;
foreach my $monitor ( values(%monitors) ) foreach my $monitor ( values(%monitors) )
{ {
my ( $state, $last_event ) = zmMemRead( $monitor, [ "shared_data:state", "shared_data:last_event" ] ); my ( $state, $last_event )
= zmMemRead( $monitor,
[ "shared_data:state",
"shared_data:last_event"
]
);
#print( "$monitor->{Id}: S:$state, LE:$last_event\n" ); #print( "$monitor->{Id}: S:$state, LE:$last_event\n" );
#print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" ); #print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" );
if ( $state == STATE_ALARM || $state == STATE_ALERT ) # In alarm state if ( $state == STATE_ALARM
|| $state == STATE_ALERT
) # In alarm state
{ {
if ( !defined($monitor->{LastEvent}) || ($last_event != $monitor->{LastEvent}) ) # A new event if ( !defined($monitor->{LastEvent})
|| ($last_event != $monitor->{LastEvent})
) # A new event
{ {
push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event ); push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event );
} }
@ -212,11 +261,19 @@ while( 1 )
# Do nothing # Do nothing
} }
} }
elsif ( ($state == STATE_IDLE && $monitor->{LastState} != STATE_IDLE) || ($state == STATE_TAPE && $monitor->{LastState} != STATE_TAPE) ) # Out of alarm state elsif ( ($state == STATE_IDLE
&& $monitor->{LastState} != STATE_IDLE
)
|| ($state == STATE_TAPE
&& $monitor->{LastState} != STATE_TAPE
)
) # Out of alarm state
{ {
push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event );
} }
elsif ( defined($monitor->{LastEvent}) && ($last_event != $monitor->{LastEvent}) ) # We've missed a whole event elsif ( defined($monitor->{LastEvent})
&& ($last_event != $monitor->{LastEvent})
) # We've missed a whole event
{ {
push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event ); push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event );
push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event );
@ -239,7 +296,8 @@ while( 1 )
} }
} }
Debug( "Checking for timed actions\n" ) if ( int(keys(%actions)) ); Debug( "Checking for timed actions\n" )
if ( int(keys(%actions)) );
my $now = time(); my $now = time();
foreach my $action_time ( sort( grep { $_ < $now } keys( %actions ) ) ) foreach my $action_time ( sort( grep { $_ < $now } keys( %actions ) ) )
{ {
@ -299,9 +357,13 @@ sub loadMonitors
my %new_monitors = (); my %new_monitors = ();
my $sql = "select * from Monitors where find_in_set( Function, 'Modect,Mocord,Nodect' )"; my $sql = "SELECT * FROM Monitors
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )"
my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); ;
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute()
or Fatal( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) while( my $monitor = $sth->fetchrow_hashref() )
{ {
next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok
@ -332,7 +394,8 @@ sub handleMessage
my $connection = shift; my $connection = shift;
my $message = shift; my $message = shift;
my ( $id, $action, $score, $cause, $text, $showtext ) = split( /\|/, $message ); my ( $id, $action, $score, $cause, $text, $showtext )
= split( /\|/, $message );
$score = 0 if ( !defined($score) ); $score = 0 if ( !defined($score) );
$cause = "" if ( !defined($cause) ); $cause = "" if ( !defined($cause) );
$text = "" if ( !defined($text) ); $text = "" if ( !defined($text) );
@ -366,13 +429,20 @@ sub handleMessage
if ( $delay ) if ( $delay )
{ {
my $action_time = time()+$delay; my $action_time = time()+$delay;
my $action_text = $id."|".(($state eq "enable")?"disable":"enable"); my $action_text = $id."|".( ($state eq "enable")
? "disable"
: "enable"
)
;
my $action_array = $actions{$action_time}; my $action_array = $actions{$action_time};
if ( !$action_array ) if ( !$action_array )
{ {
$action_array = $actions{$action_time} = []; $action_array = $actions{$action_time} = [];
} }
push( @$action_array, { connection=>$connection, message=>$action_text } ); push( @$action_array, { connection=>$connection,
message=>$action_text
}
);
Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" ); Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" );
} }
} }
@ -396,7 +466,9 @@ sub handleMessage
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext); zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
Info( "Trigger '$trigger'\n" ); Info( "Trigger '$trigger'\n" );
# Wait til it's finished # Wait til it's finished
while( zmInAlarm( $monitor ) && ($last_event == zmGetLastEvent( $monitor )) ) while( zmInAlarm( $monitor )
&& ($last_event == zmGetLastEvent( $monitor ))
)
{ {
# Tenth of a second # Tenth of a second
usleep( 100000 ); usleep( 100000 );
@ -418,7 +490,10 @@ sub handleMessage
{ {
$action_array = $actions{$action_time} = []; $action_array = $actions{$action_time} = [];
} }
push( @$action_array, { connection=>$connection, message=>$action_text } ); push( @$action_array, { connection=>$connection,
message=>$action_text
}
);
Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" ); Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" );
} }
} }

View File

@ -76,7 +76,7 @@ use POSIX;
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
use autouse 'Pod::Usage'=>qw(pod2usage); use autouse 'Pod::Usage'=>qw(pod2usage);
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}); use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS});

View File

@ -20,10 +20,37 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This script is used to create MPEG videos of events for the web pages =head1 NAME
# or as email attachments.
# zmvideo.pl - ZoneMinder Video Creation Script
=head1 SYNOPSIS
zmvideo.pl -e <event_id>,--event=<event_id> [--format <format>]
[--rate=<rate>]
[--scale=<scale>]
[--fps=<fps>]
[--size=<size>]
[--overwrite]
=head1 DESCRIPTION
This script is used to create MPEG videos of events for the web pages
or as email attachments.
=head1 OPTIONS
-e<event_id>, --event=<event_id> - What event to create the video for
-f<format>, --format=<format> - What format to create the video in, default is mpg. For ffmpeg only.
-r<rate>, --rate=<rate> - Relative rate, 1 = realtime, 2 = double speed, 0.5 = half speed etc.
-s<scale>, --scale=<scale> - Scale, 1 = normal, 2 = double size, 0.5 = half size etc.
-F<fps>, --fps=<fps> - Absolute frame rate, in frames per second
-S<size>, --size=<size> - Absolute video size, WxH or other specification supported by ffmpeg
-o, --overwrite - Whether to overwrite an existing file, off by default.
-v, --version - Outputs the currently installed version of ZoneMinder
=cut
use strict; use strict;
use bytes; use bytes;
@ -36,9 +63,10 @@ use bytes;
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
use ZoneMinder; use ZoneMinder;
use DBI; use DBI;
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
use POSIX qw(strftime); use POSIX qw(strftime);
use Getopt::Long qw(:config no_ignore_case ); use Getopt::Long qw(:config no_ignore_case );
use autouse 'Pod::Usage'=>qw(pod2usage);
$| = 1; $| = 1;
@ -66,27 +94,16 @@ for ( my $i = 0; $i < @formats; $i++ )
} }
} }
sub Usage GetOptions(
{ 'event=i' =>\$event_id,
print( " 'format|f=s' =>\$format,
Usage: zmvideo.pl -e <event_id>,--event=<event_id> [--format <format>] [--rate=<rate>] [--scale=<scale>] [--fps=<fps>] [--size=<size>] [--overwrite] 'rate|r=f' =>\$rate,
Parameters are :- 'scale|s=f' =>\$scale,
-e<event_id>, --event=<event_id> - What event to create the video for 'fps|F=f' =>\$fps,
-f<format>, --format=<format> - What format to create the video in, default is mpg. For ffmpeg only. 'size|S=s' =>\$size,
-r<rate>, --rate=<rate> - Relative rate , 1 = realtime, 2 = double speed , 0.5 = half speed etc 'overwrite' =>\$overwrite,
-s<scale>, --scale=<scale> - Scale, 1 = normal, 2 = double size, 0.5 = half size etc 'version' =>\$version
-F<fps>, --fps=<fps> - Absolute frame rate, in frames per second ) or pod2usage(-exitstatus => -1);
-S<size>, --size=<size> - Absolute video size, WxH or other specification supported by ffmpeg
-o, --overwrite - Whether to overwrite an existing file, off by default.
-v, --version - Outputs the currently installed version of ZoneMinder
");
exit( -1 );
}
if ( !GetOptions( 'event=i'=>\$event_id, 'format|f=s'=>\$format, 'rate|r=f'=>\$rate, 'scale|s=f'=>\$scale, 'fps|F=f'=>\$fps, 'size|S=s'=>\$size, 'overwrite'=>\$overwrite, version=>\$version ) )
{
Usage();
}
if ( $version ) { if ( $version ) {
print ZoneMinder::Base::ZM_VERSION . "\n"; print ZoneMinder::Base::ZM_VERSION . "\n";
@ -96,7 +113,7 @@ if ( $version ) {
if ( !$event_id || $event_id < 0 ) if ( !$event_id || $event_id < 0 )
{ {
print( STDERR "Please give a valid event id\n" ); print( STDERR "Please give a valid event id\n" );
Usage(); pod2usage(-exitstatus => -1);
} }
if ( ! $Config{ZM_OPT_FFMPEG} ) if ( ! $Config{ZM_OPT_FFMPEG} )
@ -118,19 +135,19 @@ if ( !$scale && !$size )
if ( $rate && ($rate < 0.25 || $rate > 100) ) if ( $rate && ($rate < 0.25 || $rate > 100) )
{ {
print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" ); print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" );
Usage(); pod2usage(-exitstatus => -1);
} }
if ( $scale && ($scale < 0.25 || $scale > 4) ) if ( $scale && ($scale < 0.25 || $scale > 4) )
{ {
print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" ); print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" );
Usage(); pod2usage(-exitstatus => -1);
} }
if ( $fps && ($fps > 30) ) if ( $fps && ($fps > 30) )
{ {
print( STDERR "FPS is out of range, <= 30\n" ); print( STDERR "FPS is out of range, <= 30\n" );
Usage(); pod2usage(-exitstatus => -1);
} }
my ( $detaint_format ) = $format =~ /^(\w+)$/; my ( $detaint_format ) = $format =~ /^(\w+)$/;
@ -148,9 +165,23 @@ $size = $detaint_size;
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
my @filters; my @filters;
my $sql = "select max(F.Delta)-min(F.Delta) as FullLength, E.*, unix_timestamp(E.StartTime) as Time, M.Name as MonitorName, M.Width as MonitorWidth, M.Height as MonitorHeight, M.Palette from Frames as F inner join Events as E on F.EventId = E.Id inner join Monitors as M on E.MonitorId = M.Id where EventId = '$event_id' group by F.EventId"; my $sql = " SELECT max(F.Delta)-min(F.Delta) as FullLength,
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); E.*,
my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); unix_timestamp(E.StartTime) as Time,
M.Name as MonitorName,
M.Width as MonitorWidth,
M.Height as MonitorHeight,
M.Palette
FROM Frames as F
INNER JOIN Events as E on F.EventId = E.Id
INNER JOIN Monitors as M on E.MonitorId = M.Id
WHERE EventId = '$event_id'
GROUP BY F.EventId"
;
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute()
or Fatal( "Can't execute: ".$sth->errstr() );
my $event = $sth->fetchrow_hashref(); my $event = $sth->fetchrow_hashref();
$sth->finish(); $sth->finish();
my $event_path = getEventPath( $event ); my $event_path = getEventPath( $event );
@ -228,14 +259,24 @@ if ( $overwrite || !-s $video_file )
$video_size = $size; $video_size = $size;
} }
my $command = $Config{ZM_PATH_FFMPEG}." -y -r $frame_rate ".$Config{ZM_FFMPEG_INPUT_OPTIONS}." -i %0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg -s $video_size ".$Config{ZM_FFMPEG_OUTPUT_OPTIONS}." '$video_file' > ffmpeg.log 2>&1"; my $command = $Config{ZM_PATH_FFMPEG}
." -y -r $frame_rate "
.$Config{ZM_FFMPEG_INPUT_OPTIONS}
." -i %0"
.$Config{ZM_EVENT_IMAGE_DIGITS}
."d-capture.jpg -s $video_size "
.$Config{ZM_FFMPEG_OUTPUT_OPTIONS}
." '$video_file' > ffmpeg.log 2>&1"
;
Debug( $command."\n" ); Debug( $command."\n" );
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status ) if ( $status )
{ {
Error( "Unable to generate video, check ".$event_path."/ffmpeg.log for details" ); Error( "Unable to generate video, check "
.$event_path."/ffmpeg.log for details"
);
exit( -1 ); exit( -1 );
} }

View File

@ -20,11 +20,22 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This does some basic setup for ZoneMinder to run and then periodically =head1 NAME
# checks the fps output of the active daemons to check they haven't
# locked up. If they have then they are killed and restarted zmwatch.pl - ZoneMinder WatchDog Script
#
=head1 SYNOPSIS
zmwatch.pl
=head1 DESCRIPTION
This does some basic setup for ZoneMinder to run and then periodically
checks the fps output of the active daemons to check they haven't
locked up. If they have then they are killed and restarted
=cut
use strict; use strict;
use bytes; use bytes;
@ -46,7 +57,7 @@ use constant START_DELAY => 30; # To give everything else time to start
use ZoneMinder; use ZoneMinder;
use POSIX; use POSIX;
use DBI; use DBI;
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
$| = 1; $| = 1;
@ -54,14 +65,6 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
sub Usage
{
print( "
Usage: zmwatch.pl
");
exit( -1 );
}
logInit(); logInit();
logSetSignal(); logSetSignal();
@ -72,30 +75,41 @@ sleep( START_DELAY );
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
my $sql = "select * from Monitors"; my $sql = "select * from Monitors";
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
while( 1 ) while( 1 )
{ {
my $now = time(); my $now = time();
my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute()
or Fatal( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) while( my $monitor = $sth->fetchrow_hashref() )
{ {
if ( $monitor->{Function} ne 'None' ) if ( $monitor->{Function} ne 'None' )
{ {
my $restart = 0; my $restart = 0;
if ( zmMemVerify( $monitor ) && zmMemRead( $monitor, "shared_data:valid" ) ) if ( zmMemVerify( $monitor )
&& zmMemRead( $monitor, "shared_data:valid" )
)
{ {
# Check we have got an image recently # Check we have got an image recently
my $image_time = zmGetLastWriteTime( $monitor ); my $image_time = zmGetLastWriteTime( $monitor );
next if ( !defined($image_time) ); # Can't read from shared data next if ( !defined($image_time) ); # Can't read from shared data
next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died.
my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY}; my $max_image_delay = ( $monitor->{MaxFPS}
&&($monitor->{MaxFPS}>0)
&&($monitor->{MaxFPS}<1)
) ? (3/$monitor->{MaxFPS})
: $Config{ZM_WATCH_MAX_DELAY}
;
my $image_delay = $now-$image_time; my $image_delay = $now-$image_time;
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" ); Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) if ( $image_delay > $max_image_delay )
{ {
Info( "Restarting capture daemon for ".$monitor->{Name}.", time since last capture $image_delay seconds ($now-$image_time)\n" ); Info( "Restarting capture daemon for "
.$monitor->{Name}.", time since last capture $image_delay seconds ($now-$image_time)\n"
);
$restart = 1; $restart = 1;
} }
} }
@ -120,19 +134,28 @@ while( 1 )
} }
elsif ( $monitor->{Function} ne 'Monitor' ) elsif ( $monitor->{Function} ne 'Monitor' )
{ {
if ( zmMemVerify( $monitor ) && zmMemRead( $monitor, "shared_data:valid" ) ) if ( zmMemVerify( $monitor )
&& zmMemRead( $monitor, "shared_data:valid" )
)
{ {
# Check we have got an image recently # Check we have got an image recently
my $image_time = zmGetLastReadTime( $monitor ); my $image_time = zmGetLastReadTime( $monitor );
next if ( !defined($image_time) ); # Can't read from shared data next if ( !defined($image_time) ); # Can't read from shared data
next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died.
my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY}; my $max_image_delay = ( $monitor->{MaxFPS}
&&($monitor->{MaxFPS}>0)
&&($monitor->{MaxFPS}<1)
) ? (3/$monitor->{MaxFPS})
: $Config{ZM_WATCH_MAX_DELAY}
;
my $image_delay = $now-$image_time; my $image_delay = $now-$image_time;
Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" ); Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) if ( $image_delay > $max_image_delay )
{ {
Info( "Restarting analysis daemon for ".$monitor->{Name}.", time since last analysis $image_delay seconds ($now-$image_time)\n" ); Info( "Restarting analysis daemon for "
.$monitor->{Name}.", time since last analysis $image_delay seconds ($now-$image_time)\n"
);
my $command = "zmdc.pl restart zma -m ".$monitor->{Id}; my $command = "zmdc.pl restart zma -m ".$monitor->{Id};
runCommand( $command ); runCommand( $command );
} }

View File

@ -20,10 +20,28 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# ========================================================================== # ==========================================================================
#
# This script controls the monitoring of the X10 interface and the consequent =head1 NAME
# management of the ZM daemons based on the receipt of X10 signals.
# zmx10.pl - ZoneMinder X10 Control Script
=head1 SYNOPSIS
zmx10.pl -c <command>,--command=<command> [-u <unit code>,--unit-code=<unit code>]
=head1 DESCRIPTION
This script controls the monitoring of the X10 interface and the consequent
management of the ZM daemons based on the receipt of X10 signals.
=head1 OPTIONS
-c <command>, --command=<command> - Command to issue, one of 'on','off','dim','bright','status','shutdown'
-u <unit code>, --unit-code=<unit code> - Unit code to act on required for all commands
except 'status' (optional) and 'shutdown'
-v, --verison - Pirnts the currently installed version of ZoneMinder
=cut
use strict; use strict;
use bytes; use bytes;
@ -46,7 +64,8 @@ use ZoneMinder;
use POSIX; use POSIX;
use Socket; use Socket;
use Getopt::Long; use Getopt::Long;
use Data::Dumper; use autouse 'Pod::Usage'=>qw(pod2usage);
use autouse 'Data::Dumper'=>qw(Dumper);
use constant SOCK_FILE => $Config{ZM_PATH_SOCKS}.'/zmx10.sock'; use constant SOCK_FILE => $Config{ZM_PATH_SOCKS}.'/zmx10.sock';
@ -56,18 +75,6 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
sub Usage
{
print( "
Usage: zmx10.pl -c <command>,--command=<command> [-u <unit code>,--unit-code=<unit code>]
Parameters are :-
-c <command>, --command=<command> - Command to issue, one of 'on','off','dim','bright','status','shutdown'
-u <unit code>, --unit-code=<unit code> - Unit code to act on required for all commands except 'status' (optional) and 'shutdown'
-v, --verison - Pirnts the currently installed version of ZoneMinder
");
exit( -1 );
}
logInit(); logInit();
logSetSignal(); logSetSignal();
@ -75,17 +82,20 @@ my $command;
my $unit_code; my $unit_code;
my $version; my $version;
if ( !GetOptions( 'command=s'=>\$command, 'unit-code=i'=>\$unit_code, version=>\$version ) ) GetOptions(
{ 'command=s' =>\$command,
Usage(); 'unit-code=i' =>\$unit_code,
} 'version' =>\$version
) or pod2usage(-exitstatus => -1);
if ( $version ) { if ( $version ) {
print ZoneMinder::Base::ZM_VERSION; print ZoneMinder::Base::ZM_VERSION;
exit(0); exit(0);
} }
die( "No command given" ) unless( $command ); die( "No command given" ) unless( $command );
die( "No unit code given" ) unless( $unit_code || ($command =~ /(?:start|status|shutdown)/) ); die( "No unit code given" )
unless( $unit_code || ($command =~ /(?:start|status|shutdown)/) );
if ( $command eq "start" ) if ( $command eq "start" )
{ {
@ -93,7 +103,8 @@ if ( $command eq "start" )
exit(); exit();
} }
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 )
or Fatal( "Can't open socket: $!" );
my $saddr = sockaddr_un( SOCK_FILE ); my $saddr = sockaddr_un( SOCK_FILE );
@ -108,8 +119,10 @@ if ( !connect( CLIENT, $saddr ) )
# Parent process just sleep and fall through # Parent process just sleep and fall through
sleep( 2 ); sleep( 2 );
logReinit(); logReinit();
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 )
connect( CLIENT, $saddr ) or Fatal( "Can't connect: $!" ); or Fatal( "Can't open socket: $!" );
connect( CLIENT, $saddr )
or Fatal( "Can't connect: $!" );
} }
elsif ( defined($cpid) ) elsif ( defined($cpid) )
{ {
@ -156,7 +169,7 @@ use POSIX;
use DBI; use DBI;
use Socket; use Socket;
use X10::ActiveHome; use X10::ActiveHome;
use Data::Dumper; use autouse 'Data::Dumper'=>qw(Dumper);
our $dbh; our $dbh;
our $x10; our $x10;
@ -169,7 +182,8 @@ sub runServer
{ {
Info( "X10 server starting\n" ); Info( "X10 server starting\n" );
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( SERVER, PF_UNIX, SOCK_STREAM, 0 )
or Fatal( "Can't open socket: $!" );
unlink( main::SOCK_FILE ); unlink( main::SOCK_FILE );
my $saddr = sockaddr_un( main::SOCK_FILE ); my $saddr = sockaddr_un( main::SOCK_FILE );
bind( SERVER, $saddr ) or Fatal( "Can't bind: $!" ); bind( SERVER, $saddr ) or Fatal( "Can't bind: $!" );
@ -218,7 +232,9 @@ sub runServer
$device = $device_hash{$unit_code}; $device = $device_hash{$unit_code};
if ( !$device ) if ( !$device )
{ {
$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' }; $device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ),
status=>'unknown'
};
} }
} }
@ -309,12 +325,16 @@ sub runServer
if ( defined( $monitor->{LastState} ) ) if ( defined( $monitor->{LastState} ) )
{ {
my $task_list; my $task_list;
if ( ($state == STATE_ALARM || $state == STATE_ALERT) && ($monitor->{LastState} == STATE_IDLE || $monitor->{LastState} == STATE_TAPE) ) # Gone into alarm state if ( ($state == STATE_ALARM || $state == STATE_ALERT)
&& ($monitor->{LastState} == STATE_IDLE || $monitor->{LastState} == STATE_TAPE)
) # Gone into alarm state
{ {
Debug( "Applying ON_list for $monitor_id\n" ); Debug( "Applying ON_list for $monitor_id\n" );
$task_list = $monitor->{"ON_list"}; $task_list = $monitor->{"ON_list"};
} }
elsif ( ($state == STATE_IDLE && $monitor->{LastState} != STATE_IDLE) || ($state == STATE_TAPE && $monitor->{LastState} != STATE_TAPE) ) # Come out of alarm state elsif ( ($state == STATE_IDLE && $monitor->{LastState} != STATE_IDLE)
|| ($state == STATE_TAPE && $monitor->{LastState} != STATE_TAPE)
) # Come out of alarm state
{ {
Debug( "Applying OFF_list for $monitor_id\n" ); Debug( "Applying OFF_list for $monitor_id\n" );
$task_list = $monitor->{"OFF_list"}; $task_list = $monitor->{"OFF_list"};
@ -363,14 +383,22 @@ sub addToDeviceList
my $function = shift; my $function = shift;
my $limit = shift; my $limit = shift;
Debug( "Adding to device list, uc:$unit_code, ev:$event, mo:".$monitor->{Id}.", fu:$function, li:$limit\n" ); Debug( "Adding to device list, uc:$unit_code, ev:$event, mo:"
.$monitor->{Id}.", fu:$function, li:$limit\n"
);
my $device = $device_hash{$unit_code}; my $device = $device_hash{$unit_code};
if ( !$device ) if ( !$device )
{ {
$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' }; $device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ),
status=>'unknown'
};
} }
my $task = { type=>"device", monitor=>$monitor, address=>$device->{appliance}->address(), function=>$function }; my $task = { type=>"device",
monitor=>$monitor,
address=>$device->{appliance}->address(),
function=>$function
};
if ( $limit ) if ( $limit )
{ {
$task->{limit} = $limit $task->{limit} = $limit
@ -392,14 +420,22 @@ sub addToMonitorList
my $function = shift; my $function = shift;
my $limit = shift; my $limit = shift;
Debug( "Adding to monitor list, uc:$unit_code, ev:$event, mo:".$monitor->{Id}.", fu:$function, li:$limit\n" ); Debug( "Adding to monitor list, uc:$unit_code, ev:$event, mo:".$monitor->{Id}
.", fu:$function, li:$limit\n"
);
my $device = $device_hash{$unit_code}; my $device = $device_hash{$unit_code};
if ( !$device ) if ( !$device )
{ {
$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' }; $device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ),
status=>'unknown'
};
} }
my $task = { type=>"monitor", device=>$device, id=>$monitor->{Id}, function=>$function }; my $task = { type=>"monitor",
device=>$device,
id=>$monitor->{Id},
function=>$function
};
if ( $limit ) if ( $limit )
{ {
$task->{limit} = $limit; $task->{limit} = $limit;
@ -426,9 +462,16 @@ sub loadTasks
$device->{OFF_list} = []; $device->{OFF_list} = [];
} }
my $sql = "select M.*,T.* from Monitors as M inner join TriggersX10 as T on (M.Id = T.MonitorId) where find_in_set( M.Function, 'Modect,Record,Mocord,Nodect' ) and M.Enabled = 1 and find_in_set( 'X10', M.Triggers )"; my $sql = "SELECT M.*,T.* from Monitors as M
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); INNER JOIN TriggersX10 as T on (M.Id = T.MonitorId)
my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); WHERE find_in_set( M.Function, 'Modect,Record,Mocord,Nodect' )
AND M.Enabled = 1
AND find_IN_set( 'X10', M.Triggers )"
;
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute()
or Fatal( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) while( my $monitor = $sth->fetchrow_hashref() )
{ {
next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok
@ -441,17 +484,30 @@ sub loadTasks
foreach my $code_string ( split( /,/, $monitor->{Activation} ) ) foreach my $code_string ( split( /,/, $monitor->{Activation} ) )
{ {
#Debug( "Code string: $code_string\n" ); #Debug( "Code string: $code_string\n" );
my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ ); my ( $invert, $unit_code, $modifier, $limit )
= ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
$limit = 0 if ( !$limit ); $limit = 0 if ( !$limit );
if ( $unit_code ) if ( $unit_code )
{ {
if ( !$modifier || $modifier eq '+' ) if ( !$modifier || $modifier eq '+' )
{ {
addToDeviceList( $unit_code, "ON", $monitor, !$invert?"start_active":"stop_active", $limit ); addToDeviceList( $unit_code,
"ON",
$monitor,
!$invert ? "start_active"
: "stop_active",
$limit
);
} }
if ( !$modifier || $modifier eq '-' ) if ( !$modifier || $modifier eq '-' )
{ {
addToDeviceList( $unit_code, "OFF", $monitor, !$invert?"stop_active":"start_active", $limit ); addToDeviceList( $unit_code,
"OFF",
$monitor,
!$invert ? "stop_active"
: "start_active",
$limit
);
} }
} }
} }
@ -462,17 +518,30 @@ sub loadTasks
foreach my $code_string ( split( /,/, $monitor->{AlarmInput} ) ) foreach my $code_string ( split( /,/, $monitor->{AlarmInput} ) )
{ {
#Debug( "Code string: $code_string\n" ); #Debug( "Code string: $code_string\n" );
my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ ); my ( $invert, $unit_code, $modifier, $limit )
= ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
$limit = 0 if ( !$limit ); $limit = 0 if ( !$limit );
if ( $unit_code ) if ( $unit_code )
{ {
if ( !$modifier || $modifier eq '+' ) if ( !$modifier || $modifier eq '+' )
{ {
addToDeviceList( $unit_code, "ON", $monitor, !$invert?"start_alarm":"stop_alarm", $limit ); addToDeviceList( $unit_code,
"ON",
$monitor,
!$invert ? "start_alarm"
: "stop_alarm",
$limit
);
} }
if ( !$modifier || $modifier eq '-' ) if ( !$modifier || $modifier eq '-' )
{ {
addToDeviceList( $unit_code, "OFF", $monitor, !$invert?"stop_alarm":"start_alarm", $limit ); addToDeviceList( $unit_code,
"OFF",
$monitor,
!$invert ? "stop_alarm"
: "start_alarm",
$limit
);
} }
} }
} }
@ -483,17 +552,30 @@ sub loadTasks
foreach my $code_string ( split( /,/, $monitor->{AlarmOutput} ) ) foreach my $code_string ( split( /,/, $monitor->{AlarmOutput} ) )
{ {
#Debug( "Code string: $code_string\n" ); #Debug( "Code string: $code_string\n" );
my ( $invert, $unit_code, $modifier, $limit ) = ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ ); my ( $invert, $unit_code, $modifier, $limit )
= ( $code_string =~ /^([!~])?(\d+)(?:([+-])(\d+)?)?$/ );
$limit = 0 if ( !$limit ); $limit = 0 if ( !$limit );
if ( $unit_code ) if ( $unit_code )
{ {
if ( !$modifier || $modifier eq '+' ) if ( !$modifier || $modifier eq '+' )
{ {
addToMonitorList( $monitor, "ON", $unit_code, !$invert?"on":"off", $limit ); addToMonitorList( $monitor,
"ON",
$unit_code,
!$invert ? "on"
: "off",
$limit
);
} }
if ( !$modifier || $modifier eq '-' ) if ( !$modifier || $modifier eq '-' )
{ {
addToMonitorList( $monitor, "OFF", $unit_code, !$invert?"off":"on", $limit ); addToMonitorList( $monitor,
"OFF",
$unit_code,
!$invert ? "off"
: "on",
$limit
);
} }
} }
} }
@ -528,8 +610,11 @@ sub addPendingTask
} }
elsif ( $task->{type} eq "monitor" ) elsif ( $task->{type} eq "monitor" )
{ {
if (( $task->{device}->{appliance}->unit_code() != $pending_task->{device}->{appliance}->unit_code() ) if (( $task->{device}->{appliance}->unit_code()
|| ( $task->{function} ne $pending_task->{function} )) != $pending_task->{device}->{appliance}->unit_code()
)
|| ( $task->{function} ne $pending_task->{function} )
)
{ {
push( @$new_pending_list, $pending_task ) push( @$new_pending_list, $pending_task )
} }
@ -554,12 +639,18 @@ sub addPendingTask
my $pending_task; my $pending_task;
if ( $task->{type} eq "device" ) if ( $task->{type} eq "device" )
{ {
$pending_task = { type=>$task->{type}, monitor=>$task->{monitor}, function=>$task->{function} }; $pending_task = { type=>$task->{type},
monitor=>$task->{monitor},
function=>$task->{function}
};
$pending_task->{function} =~ s/start/stop/; $pending_task->{function} =~ s/start/stop/;
} }
elsif ( $task->{type} eq "monitor" ) elsif ( $task->{type} eq "monitor" )
{ {
$pending_task = { type=>$task->{type}, device=>$task->{device}, function=>$task->{function} }; $pending_task = { type=>$task->{type},
device=>$task->{device},
function=>$task->{function}
};
$pending_task->{function} =~ s/on/off/; $pending_task->{function} =~ s/on/off/;
} }
push( @$pending_list, $pending_task ); push( @$pending_list, $pending_task );
@ -592,7 +683,11 @@ sub processTask
{ {
if ( $instruction eq "start" ) if ( $instruction eq "start" )
{ {
zmTriggerEventOn( $task->{monitor}, 0, main::CAUSE_STRING, $task->{address} ); zmTriggerEventOn( $task->{monitor},
0,
main::CAUSE_STRING,
$task->{address}
);
if ( $task->{limit} ) if ( $task->{limit} )
{ {
addPendingTask( $task ); addPendingTask( $task );
@ -661,7 +756,9 @@ sub x10listen
my $device = $device_hash{$unit_code}; my $device = $device_hash{$unit_code};
if ( !$device ) if ( !$device )
{ {
$device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ), status=>'unknown' }; $device = $device_hash{$unit_code} = { appliance=>$x10->Appliance( unit_code=>$unit_code ),
status=>'unknown'
};
} }
next if ( $event->func() !~ /(?:ON|OFF)/ ); next if ( $event->func() !~ /(?:ON|OFF)/ );
$device->{status} = $event->func(); $device->{status} = $event->func();