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
#
# 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.
#
# ==========================================================================
#
# 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.
#
=head1 NAME
zmsystemctl.pl - ZoneMinder systemctl wrapper
=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 strict;
use bytes;
use autouse 'Pod::Usage'=>qw(pod2usage);
@EXTRA_PERL_LIB@
use ZoneMinder::Logger qw(:all);
my $command = $ARGV[0];
if ( (scalar(@ARGV) == 1) && ($command =~ /^(start|stop|restart|version)$/ )) {
if ( (scalar(@ARGV) == 1)
&& ($command =~ /^(start|stop|restart|version)$/ )
){
$command = $1;
} else {
die(" USAGE: zmsystemctl.pl <start|stop|restart|version>\n");
pod2usage(-exitstatus => -1);
}
my $path = qx(which systemctl);

View File

@ -20,10 +20,26 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This script is used to trigger and cancel alarms from external sources
# using an arbitrary text based format
#
=head1 NAME
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 bytes;
@ -45,8 +61,9 @@ use constant SLEEP_TIME => 10000; # In microseconds
use ZoneMinder;
use DBI;
use POSIX;
use Data::Dumper;
use autouse 'Data::Dumper'=>qw(Dumper);
use Getopt::Long;
use autouse 'Pod::Usage'=>qw(pod2usage);
use Time::HiRes qw( usleep );
$| = 1;
@ -57,20 +74,8 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my $mid = 0;
sub Usage
{
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();
}
GetOptions( 'monitor=s'=>\$mid )
or pod2usage(-exitstatus => -1);
logInit();
logSetSignal();
@ -78,14 +83,22 @@ logSetSignal();
my ( $detaint_mid ) = $mid =~ /^(\d+)$/;
$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 $sql = "select C.*,M.* from Monitors as M 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 $sql = "SELECT C.*,M.* FROM Monitors as M
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();
if ( !$monitor )
@ -141,8 +154,16 @@ sub Track
my ( $detaint_x ) = $x =~ /^(\d+)$/; $x = $detaint_x;
my ( $detaint_y ) = $y =~ /^(\d+)$/; $y = $detaint_y;
my $ctrlCommand = $Config{ZM_PATH_BIN}."/zmcontrol.pl -i ".$monitor->{Id};
$ctrlCommand .= " --command=".($monitor->{CanMoveMap}?"moveMap":"movePseudoMap")." --xcoord=$x --ycoord=$y";
my $ctrlCommand = $Config{ZM_PATH_BIN}
."/zmcontrol.pl -i "
.$monitor->{Id}
;
$ctrlCommand .= " --command="
.( $monitor->{CanMoveMap} ? "moveMap"
: "movePseudoMap"
)
." --xcoord=$x --ycoord=$y"
;
executeShellCommand( $ctrlCommand );
}
@ -150,10 +171,15 @@ sub Return
{
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 )
{
$ctrlCommand .= " --command=presetGoto --preset=".$monitor->{ReturnLocation};
$ctrlCommand .= " --command=presetGoto --preset="
.$monitor->{ReturnLocation}
;
}
else
{
@ -193,7 +219,10 @@ while( 1 )
print( "Left alarm state\n" );
$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" );
Suspend( $monitor );

View File

@ -20,11 +20,17 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This script is used to trigger and cancel alarms from external connections
# using an arbitrary text based format
#
# ==========================================================================
=head1 NAME
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 bytes;
@ -52,8 +58,22 @@ use ZoneMinder::Trigger::Channel::Serial;
use ZoneMinder::Trigger::Connection;
my @connections;
push( @connections, 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=>"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=>"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 Socket;
use Data::Dumper;
use autouse 'Data::Dumper'=>qw(Dumper);
use POSIX qw( EINTR );
use Time::HiRes qw( usleep );
@ -126,12 +146,22 @@ while( 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() )
{
my $new_connection = $connection->accept();
$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
{
@ -150,7 +180,12 @@ while( 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();
if ( defined($messages) )
{
@ -162,7 +197,12 @@ while( 1 )
else
{
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();
}
}
@ -197,13 +237,22 @@ while( 1 )
my @out_messages;
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}: 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 );
}
@ -212,11 +261,19 @@ while( 1 )
# 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 );
}
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}."|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();
foreach my $action_time ( sort( grep { $_ < $now } keys( %actions ) ) )
{
@ -299,9 +357,13 @@ sub loadMonitors
my %new_monitors = ();
my $sql = "select * from Monitors where find_in_set( Function, 'Modect,Mocord,Nodect' )";
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 $sql = "SELECT * FROM Monitors
WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )"
;
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() )
{
next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok
@ -332,7 +394,8 @@ sub handleMessage
my $connection = 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) );
$cause = "" if ( !defined($cause) );
$text = "" if ( !defined($text) );
@ -366,13 +429,20 @@ sub handleMessage
if ( $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};
if ( !$action_array )
{
$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" );
}
}
@ -396,7 +466,9 @@ sub handleMessage
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
Info( "Trigger '$trigger'\n" );
# Wait til it's finished
while( zmInAlarm( $monitor ) && ($last_event == zmGetLastEvent( $monitor )) )
while( zmInAlarm( $monitor )
&& ($last_event == zmGetLastEvent( $monitor ))
)
{
# Tenth of a second
usleep( 100000 );
@ -418,7 +490,10 @@ sub handleMessage
{
$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" );
}
}

View File

@ -76,7 +76,7 @@ use POSIX;
use DBI;
use Getopt::Long;
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});

View File

@ -20,10 +20,37 @@
# 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
# or as email attachments.
#
=head1 NAME
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 bytes;
@ -36,9 +63,10 @@ use bytes;
@EXTRA_PERL_LIB@
use ZoneMinder;
use DBI;
use Data::Dumper;
use autouse 'Data::Dumper'=>qw(Dumper);
use POSIX qw(strftime);
use Getopt::Long qw(:config no_ignore_case );
use autouse 'Pod::Usage'=>qw(pod2usage);
$| = 1;
@ -66,27 +94,16 @@ for ( my $i = 0; $i < @formats; $i++ )
}
}
sub Usage
{
print( "
Usage: zmvideo.pl -e <event_id>,--event=<event_id> [--format <format>] [--rate=<rate>] [--scale=<scale>] [--fps=<fps>] [--size=<size>] [--overwrite]
Parameters are :-
-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
");
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();
}
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
) or pod2usage(-exitstatus => -1);
if ( $version ) {
print ZoneMinder::Base::ZM_VERSION . "\n";
@ -96,7 +113,7 @@ if ( $version ) {
if ( !$event_id || $event_id < 0 )
{
print( STDERR "Please give a valid event id\n" );
Usage();
pod2usage(-exitstatus => -1);
}
if ( ! $Config{ZM_OPT_FFMPEG} )
@ -118,19 +135,19 @@ if ( !$scale && !$size )
if ( $rate && ($rate < 0.25 || $rate > 100) )
{
print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" );
Usage();
pod2usage(-exitstatus => -1);
}
if ( $scale && ($scale < 0.25 || $scale > 4) )
{
print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" );
Usage();
pod2usage(-exitstatus => -1);
}
if ( $fps && ($fps > 30) )
{
print( STDERR "FPS is out of range, <= 30\n" );
Usage();
pod2usage(-exitstatus => -1);
}
my ( $detaint_format ) = $format =~ /^(\w+)$/;
@ -148,9 +165,23 @@ $size = $detaint_size;
my $dbh = zmDbConnect();
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 $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 $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 $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();
$sth->finish();
my $event_path = getEventPath( $event );
@ -228,14 +259,24 @@ if ( $overwrite || !-s $video_file )
$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" );
my $output = qx($command);
my $status = $? >> 8;
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 );
}

View File

@ -20,11 +20,22 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# 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
#
=head1 NAME
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 bytes;
@ -46,7 +57,7 @@ use constant START_DELAY => 30; # To give everything else time to start
use ZoneMinder;
use POSIX;
use DBI;
use Data::Dumper;
use autouse 'Data::Dumper'=>qw(Dumper);
$| = 1;
@ -54,14 +65,6 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
sub Usage
{
print( "
Usage: zmwatch.pl
");
exit( -1 );
}
logInit();
logSetSignal();
@ -72,30 +75,41 @@ sleep( START_DELAY );
my $dbh = zmDbConnect();
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 )
{
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() )
{
if ( $monitor->{Function} ne 'None' )
{
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
my $image_time = zmGetLastWriteTime( $monitor );
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.
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;
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
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;
}
}
@ -120,19 +134,28 @@ while( 1 )
}
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
my $image_time = zmGetLastReadTime( $monitor );
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.
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;
Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" );
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};
runCommand( $command );
}

View File

@ -20,10 +20,28 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# 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 NAME
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 bytes;
@ -46,7 +64,8 @@ use ZoneMinder;
use POSIX;
use Socket;
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';
@ -56,18 +75,6 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
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();
logSetSignal();
@ -75,17 +82,20 @@ my $command;
my $unit_code;
my $version;
if ( !GetOptions( 'command=s'=>\$command, 'unit-code=i'=>\$unit_code, version=>\$version ) )
{
Usage();
}
GetOptions(
'command=s' =>\$command,
'unit-code=i' =>\$unit_code,
'version' =>\$version
) or pod2usage(-exitstatus => -1);
if ( $version ) {
print ZoneMinder::Base::ZM_VERSION;
exit(0);
}
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" )
{
@ -93,7 +103,8 @@ if ( $command eq "start" )
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 );
@ -108,8 +119,10 @@ if ( !connect( CLIENT, $saddr ) )
# Parent process just sleep and fall through
sleep( 2 );
logReinit();
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
connect( CLIENT, $saddr ) or Fatal( "Can't connect: $!" );
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 )
or Fatal( "Can't open socket: $!" );
connect( CLIENT, $saddr )
or Fatal( "Can't connect: $!" );
}
elsif ( defined($cpid) )
{
@ -156,7 +169,7 @@ use POSIX;
use DBI;
use Socket;
use X10::ActiveHome;
use Data::Dumper;
use autouse 'Data::Dumper'=>qw(Dumper);
our $dbh;
our $x10;
@ -169,7 +182,8 @@ sub runServer
{
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 );
my $saddr = sockaddr_un( main::SOCK_FILE );
bind( SERVER, $saddr ) or Fatal( "Can't bind: $!" );
@ -218,7 +232,9 @@ sub runServer
$device = $device_hash{$unit_code};
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} ) )
{
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" );
$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" );
$task_list = $monitor->{"OFF_list"};
@ -363,14 +383,22 @@ sub addToDeviceList
my $function = 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};
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 )
{
$task->{limit} = $limit
@ -392,14 +420,22 @@ sub addToMonitorList
my $function = 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};
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 )
{
$task->{limit} = $limit;
@ -426,9 +462,16 @@ sub loadTasks
$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 $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 $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 $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() )
{
next if ( !zmMemVerify( $monitor ) ); # Check shared memory ok
@ -441,17 +484,30 @@ sub loadTasks
foreach my $code_string ( split( /,/, $monitor->{Activation} ) )
{
#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 );
if ( $unit_code )
{
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 '-' )
{
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} ) )
{
#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 );
if ( $unit_code )
{
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 '-' )
{
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} ) )
{
#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 );
if ( $unit_code )
{
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 '-' )
{
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" )
{
if (( $task->{device}->{appliance}->unit_code() != $pending_task->{device}->{appliance}->unit_code() )
|| ( $task->{function} ne $pending_task->{function} ))
if (( $task->{device}->{appliance}->unit_code()
!= $pending_task->{device}->{appliance}->unit_code()
)
|| ( $task->{function} ne $pending_task->{function} )
)
{
push( @$new_pending_list, $pending_task )
}
@ -554,12 +639,18 @@ sub addPendingTask
my $pending_task;
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/;
}
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/;
}
push( @$pending_list, $pending_task );
@ -592,7 +683,11 @@ sub processTask
{
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} )
{
addPendingTask( $task );
@ -661,7 +756,9 @@ sub x10listen
my $device = $device_hash{$unit_code};
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)/ );
$device->{status} = $event->func();