Merge branch 'master' of github.com:ZoneMinder/zoneminder
commit
d51fdafbc0
|
@ -287,6 +287,9 @@ CREATE TABLE `Filters` (
|
||||||
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
|
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoUpload` tinyint(3) unsigned NOT NULL default '0',
|
`AutoUpload` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoEmail` tinyint(3) unsigned NOT NULL default '0',
|
`AutoEmail` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`EmailTo` TEXT,
|
||||||
|
`EmailSubject` TEXT,
|
||||||
|
`EmailBody` TEXT,
|
||||||
`AutoMessage` tinyint(3) unsigned NOT NULL default '0',
|
`AutoMessage` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
|
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoExecuteCmd` tinytext,
|
`AutoExecuteCmd` tinytext,
|
||||||
|
@ -808,6 +811,7 @@ INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-423','Ffmpeg','Reolink',0,0,1,0
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-411','Ffmpeg','Reolink',0,0,1,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-411','Ffmpeg','Reolink',0,0,1,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-420','Ffmpeg','Reolink',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-420','Ffmpeg','Reolink',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'D-LINK DCS-3415','Remote','DCS3415',0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'D-LINK DCS-3415','Remote','DCS3415',0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
|
INSERT INTO `Controls` VALUES (NULL,'D-Link DCS-5020L','Remote','DCS5020L',1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,24,1,0,1,1,1,0,1,0,1,0,0,1,30,0,0,0,0,0,1,0,0,1,30,0,0,0,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'IOS Camera','Ffmpeg','IPCAMIOS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'IOS Camera','Ffmpeg','IPCAMIOS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Dericam P2','Ffmpeg','DericamP2',0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,1,1,1,0,0,0,1,1,0,0,0,0,1,1,45,0,0,1,0,0,0,0,1,1,45,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Dericam P2','Ffmpeg','DericamP2',0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,1,1,1,0,0,0,1,1,0,0,0,0,1,1,45,0,0,1,0,0,0,0,1,1,45,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Trendnet','Remote','Trendnet',1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Trendnet','Remote','Trendnet',1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
|
@ -842,6 +846,7 @@ INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rt
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
|
INSERT INTO MonitorPresets VALUES (NULL,'D-Link DCS-5020L, 640x480, mjpeg','Remote','http',0,0,'http','simple','<username>:<pwd>@<ip-address>','80','/video.cgi',NULL,640,480,0,NULL,1,'34',NULL,'<username>:<pwd>@<ip-address>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
--
|
||||||
|
-- This updates a 1.34.2 database to 1.34.3
|
||||||
|
--
|
||||||
|
-- No changes required
|
||||||
|
--
|
|
@ -0,0 +1,41 @@
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Filters'
|
||||||
|
AND column_name = 'EmailTo'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column EmailTo already exists in Filters'",
|
||||||
|
"ALTER TABLE `Filters` ADD `EmailTo` TEXT AFTER `AutoEmail`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
UPDATE Filters SET EmailTo=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_ADDRESS') WHERE AutoEmail=1;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Filters'
|
||||||
|
AND column_name = 'EmailSubject'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column EmailSubject already exists in Filters'",
|
||||||
|
"ALTER TABLE `Filters` ADD `EmailSubject` TEXT AFTER `EmailTo`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
UPDATE Filters SET EmailSubject=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_SUBJECT') WHERE AutoEmail=1;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Filters'
|
||||||
|
AND column_name = 'EmailBody'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column EmailBody already exists in Filters'",
|
||||||
|
"ALTER TABLE `Filters` ADD `EmailBody` TEXT AFTER `EmailSubject`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
UPDATE Filters SET EmailBody=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_BODY') WHERE AutoEmail=1;
|
|
@ -28,7 +28,7 @@
|
||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
|
|
||||||
Name: zoneminder
|
Name: zoneminder
|
||||||
Version: 1.34.2
|
Version: 1.35.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A camera monitoring and analysis tool
|
Summary: A camera monitoring and analysis tool
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
|
|
|
@ -68,9 +68,13 @@ Here is what the filter window looks like
|
||||||
* %ESM% Maximum score of the event
|
* %ESM% Maximum score of the event
|
||||||
* %EP% Path to the event
|
* %EP% Path to the event
|
||||||
* %EPS% Path to the event stream
|
* %EPS% Path to the event stream
|
||||||
|
* %EPF1% Path to the frame view for the first alarmed event image
|
||||||
|
* %EPFM% Path to the frame view for the (first) event image with the highest score
|
||||||
|
* %EFMOD% Path to image containing object detection, in frame view
|
||||||
* %EPI% Path to the event images
|
* %EPI% Path to the event images
|
||||||
* %EPI1% Path to the first alarmed event image
|
* %EPI1% Path to the first alarmed event image, suitable for use in img tags
|
||||||
* %EPIM% Path to the (first) event image with the highest score
|
* %EPIM% Path to the (first) event image with the highest score, suitable for use in img tags
|
||||||
|
* %EIMOD% Path to image containing object detection, suitable for use in img tags
|
||||||
* %EI1% Attach first alarmed event image
|
* %EI1% Attach first alarmed event image
|
||||||
* %EIM% Attach (first) event image with the highest score
|
* %EIM% Attach (first) event image with the highest score
|
||||||
* %EV% Attach event mpeg video
|
* %EV% Attach event mpeg video
|
||||||
|
@ -81,7 +85,6 @@ Here is what the filter window looks like
|
||||||
* %MEW% Number of events for the monitor in the last week
|
* %MEW% Number of events for the monitor in the last week
|
||||||
* %MEM% Number of events for the monitor in the last month
|
* %MEM% Number of events for the monitor in the last month
|
||||||
* %MEA% Number of archived events for the monitor
|
* %MEA% Number of archived events for the monitor
|
||||||
* %MOD% Path to image containing object detection
|
|
||||||
* %MP% Path to the monitor window
|
* %MP% Path to the monitor window
|
||||||
* %MPS% Path to the monitor stream
|
* %MPS% Path to the monitor stream
|
||||||
* %MPI% Path to the monitor recent image
|
* %MPI% Path to the monitor recent image
|
||||||
|
|
|
@ -43,7 +43,7 @@ my %message_of :ATTR(:name<message> :default<()>);
|
||||||
my %is_success_of :ATTR(:name<is_success> :default<()>);
|
my %is_success_of :ATTR(:name<is_success> :default<()>);
|
||||||
|
|
||||||
my %local_addr_of :ATTR(:name<local_addr> :init_arg<local_addr> :default<()>);
|
my %local_addr_of :ATTR(:name<local_addr> :init_arg<local_addr> :default<()>);
|
||||||
|
my $net_interface;
|
||||||
|
|
||||||
# create methods normally inherited from SOAP::Client
|
# create methods normally inherited from SOAP::Client
|
||||||
SUBFACTORY: {
|
SUBFACTORY: {
|
||||||
|
@ -60,14 +60,22 @@ sub _notify_response
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub set_net_interface {
|
||||||
|
my $self = shift;
|
||||||
|
$net_interface = shift;
|
||||||
|
}
|
||||||
|
|
||||||
sub send_multi() {
|
sub send_multi() {
|
||||||
my ($self, $address, $port, $utf8_string) = @_;
|
my ($self, $address, $port, $utf8_string) = @_;
|
||||||
|
|
||||||
my $destination = $address . ':' . $port;
|
my $destination = $address . ':' . $port;
|
||||||
my $socket = IO::Socket::Multicast->new(PROTO => 'udp',
|
my $socket = IO::Socket::Multicast->new(
|
||||||
LocalPort=>$port, PeerAddr=>$destination, ReuseAddr=>1)
|
PROTO => 'udp',
|
||||||
|
LocalPort=>$port,
|
||||||
or die 'Cannot open multicast socket to ' . ${address} . ':' . ${port};
|
PeerAddr=>$destination,
|
||||||
|
ReuseAddr=>1
|
||||||
|
) or die 'Cannot open multicast socket to ' . ${address} . ':' . ${port};
|
||||||
|
$_ = $socket->mcast_if($net_interface) if $net_interface;
|
||||||
|
|
||||||
my $bytes = $utf8_string;
|
my $bytes = $utf8_string;
|
||||||
utf8::encode($bytes);
|
utf8::encode($bytes);
|
||||||
|
@ -80,14 +88,16 @@ sub receive_multi() {
|
||||||
my ($self, $address, $port) = @_;
|
my ($self, $address, $port) = @_;
|
||||||
my $data = undef;
|
my $data = undef;
|
||||||
|
|
||||||
my $socket = IO::Socket::Multicast->new(PROTO => 'udp',
|
my $socket = IO::Socket::Multicast->new(
|
||||||
LocalPort=>$port, ReuseAddr=>1);
|
PROTO => 'udp',
|
||||||
$socket->mcast_add($address);
|
LocalPort=>$port,
|
||||||
|
ReuseAddr=>1);
|
||||||
|
$socket->mcast_add($address, $net_interface);
|
||||||
|
|
||||||
my $readbits = '';
|
my $readbits = '';
|
||||||
vec($readbits, $socket->fileno, 1) = 1;
|
vec($readbits, $socket->fileno, 1) = 1;
|
||||||
|
|
||||||
if(select($readbits, undef, undef, WAIT_TIME/1000)) {
|
if ( select($readbits, undef, undef, WAIT_TIME/1000) ) {
|
||||||
$socket->recv($data, 9999);
|
$socket->recv($data, 9999);
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -98,15 +108,19 @@ sub receive_uni() {
|
||||||
my ($self, $address, $port, $localaddr) = @_;
|
my ($self, $address, $port, $localaddr) = @_;
|
||||||
my $data = undef;
|
my $data = undef;
|
||||||
|
|
||||||
my $socket = IO::Socket::Multicast->new(PROTO => 'udp',
|
my $socket = IO::Socket::Multicast->new(
|
||||||
LocalAddr => $localaddr, LocalPort=>$port, ReuseAddr=>1);
|
PROTO => 'udp',
|
||||||
|
LocalAddr => $localaddr,
|
||||||
|
LocalPort=>$port,
|
||||||
|
ReuseAddr=>1
|
||||||
|
);
|
||||||
|
|
||||||
$socket->mcast_add($address);
|
$socket->mcast_add($address, $net_interface);
|
||||||
|
|
||||||
my $readbits = '';
|
my $readbits = '';
|
||||||
vec($readbits, $socket->fileno, 1) = 1;
|
vec($readbits, $socket->fileno, 1) = 1;
|
||||||
|
|
||||||
if(select($readbits, undef, undef, WAIT_TIME/1000)) {
|
if ( select($readbits, undef, undef, WAIT_TIME/1000) ) {
|
||||||
$socket->recv($data, 9999);
|
$socket->recv($data, 9999);
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -120,39 +134,39 @@ sub send_receive {
|
||||||
|
|
||||||
my ($address,$port) = ($endpoint =~ /([^:\/]+):([0-9]+)/);
|
my ($address,$port) = ($endpoint =~ /([^:\/]+):([0-9]+)/);
|
||||||
|
|
||||||
#warn "address = ${address}";
|
#warn "address = ${address}";
|
||||||
#warn "port = ${port}";
|
#warn "port = ${port}";
|
||||||
|
|
||||||
$self->send_multi($address, $port, $envelope);
|
$self->send_multi($address, $port, $envelope);
|
||||||
|
|
||||||
my $localaddr = $self->get_local_addr();
|
my $localaddr = $self->get_local_addr();
|
||||||
|
#warn "localddr $localaddr";
|
||||||
|
|
||||||
my ($response, $last_response);
|
my ($response, $last_response);
|
||||||
my $wait = WAIT_COUNT;
|
my $wait = WAIT_COUNT;
|
||||||
while ( $wait >= 0 ) {
|
while ( $wait >= 0 ) {
|
||||||
if($localaddr) {
|
if ( $localaddr ) {
|
||||||
if($response = $self->receive_uni($address, $port, $localaddr)) {
|
if ( $response = $self->receive_uni($address, $port, $localaddr) ) {
|
||||||
$last_response = $response;
|
$last_response = $response;
|
||||||
$self->_notify_response($response);
|
$self->_notify_response($response);
|
||||||
}
|
}
|
||||||
$wait --;
|
$wait --;
|
||||||
}
|
}
|
||||||
if($response = $self->receive_multi($address, $port)) {
|
if ( $response = $self->receive_multi($address, $port) ) {
|
||||||
$last_response = $response;
|
$last_response = $response;
|
||||||
$self->_notify_response($response);
|
$self->_notify_response($response);
|
||||||
}
|
}
|
||||||
$wait --;
|
$wait --;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($last_response) {
|
if ( $last_response ) {
|
||||||
$self->set_code();
|
$self->set_code();
|
||||||
$self->set_message("");
|
$self->set_message('');
|
||||||
$self->set_is_success(1);
|
$self->set_is_success(1);
|
||||||
$self->set_status('OK');
|
$self->set_status('OK');
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$self->set_code();
|
$self->set_code();
|
||||||
$self->set_message("Timed out waiting for response");
|
$self->set_message('Timed out waiting for response');
|
||||||
$self->set_is_success(0);
|
$self->set_is_success(0);
|
||||||
$self->set_status('TIMEOUT');
|
$self->set_status('TIMEOUT');
|
||||||
}
|
}
|
||||||
|
@ -161,3 +175,4 @@ sub send_receive {
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
__END__
|
||||||
|
|
|
@ -2213,7 +2213,7 @@ our @options = (
|
||||||
that match the appropriate filters will be sent to.
|
that match the appropriate filters will be sent to.
|
||||||
`,
|
`,
|
||||||
type => $types{email},
|
type => $types{email},
|
||||||
category => 'mail',
|
category => 'hidden',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => 'ZM_EMAIL_TEXT',
|
name => 'ZM_EMAIL_TEXT',
|
||||||
|
@ -2253,7 +2253,7 @@ our @options = (
|
||||||
sent for any events that match the appropriate filters.
|
sent for any events that match the appropriate filters.
|
||||||
`,
|
`,
|
||||||
type => $types{string},
|
type => $types{string},
|
||||||
category => 'mail',
|
category => 'hidden',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => 'ZM_EMAIL_BODY',
|
name => 'ZM_EMAIL_BODY',
|
||||||
|
@ -2280,7 +2280,7 @@ our @options = (
|
||||||
sent for any events that match the appropriate filters.
|
sent for any events that match the appropriate filters.
|
||||||
`,
|
`,
|
||||||
type => $types{text},
|
type => $types{text},
|
||||||
category => 'mail',
|
category => 'hidden',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => 'ZM_OPT_MESSAGE',
|
name => 'ZM_OPT_MESSAGE',
|
||||||
|
|
|
@ -0,0 +1,356 @@
|
||||||
|
# =========================================================================r
|
||||||
|
#
|
||||||
|
# ZoneMinder D-Link DCS-5020L IP Control Protocol Module, $Date: $, $Revision: $
|
||||||
|
# Copyright (C) 2013 Art Scheel
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
#
|
||||||
|
# This module contains the implementation of the D-Link DCS-5020L IP camera control
|
||||||
|
# protocol.
|
||||||
|
#
|
||||||
|
package ZoneMinder::Control::DCS5020L;
|
||||||
|
|
||||||
|
use 5.006;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
require ZoneMinder::Base;
|
||||||
|
require ZoneMinder::Control;
|
||||||
|
|
||||||
|
our @ISA = qw(ZoneMinder::Control);
|
||||||
|
|
||||||
|
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
#
|
||||||
|
# D-Link DCS-5020L Control Protocol
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
use ZoneMinder::Logger qw(:all);
|
||||||
|
use ZoneMinder::Config qw(:all);
|
||||||
|
|
||||||
|
use Time::HiRes qw( usleep );
|
||||||
|
|
||||||
|
sub new
|
||||||
|
{
|
||||||
|
my $class = shift;
|
||||||
|
my $id = shift;
|
||||||
|
my $self = ZoneMinder::Control->new( $id );
|
||||||
|
bless( $self, $class );
|
||||||
|
srand( time() );
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
our $AUTOLOAD;
|
||||||
|
|
||||||
|
sub AUTOLOAD
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $class = ref($self) || croak( "$self not object" );
|
||||||
|
my $name = $AUTOLOAD;
|
||||||
|
$name =~ s/.*://;
|
||||||
|
if ( exists($self->{$name}) )
|
||||||
|
{
|
||||||
|
return( $self->{$name} );
|
||||||
|
}
|
||||||
|
Fatal( "Can't access $name member of object of class $class" );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub open
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
$self->loadMonitor();
|
||||||
|
|
||||||
|
use LWP::UserAgent;
|
||||||
|
$self->{ua} = LWP::UserAgent->new;
|
||||||
|
$self->{ua}->agent( "ZoneMinder Control Agent/" . ZoneMinder::Base::ZM_VERSION );
|
||||||
|
$self->{state} = 'open';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub close
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
$self->{state} = 'closed';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub printMsg
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $msg = shift;
|
||||||
|
my $msg_len = length($msg);
|
||||||
|
|
||||||
|
Debug( $msg."[".$msg_len."]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sendCmd
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $cmd = shift;
|
||||||
|
my $cgi = shift;
|
||||||
|
|
||||||
|
my $result = undef;
|
||||||
|
|
||||||
|
printMsg( $cmd, "Tx" );
|
||||||
|
|
||||||
|
my $req = HTTP::Request->new( POST=>"http://$self->{Monitor}->{ControlAddress}/$cgi.cgi" );
|
||||||
|
$req->content($cmd);
|
||||||
|
my $res = $self->{ua}->request($req);
|
||||||
|
|
||||||
|
if ( $res->is_success )
|
||||||
|
{
|
||||||
|
$result = !undef;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error( "Error check failed: '".$res->status_line()."'" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub move
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $dir = shift;
|
||||||
|
my $panStep = shift;
|
||||||
|
my $tiltStep = shift;
|
||||||
|
my $cmd = "PanSingleMoveDegree=$panStep&TiltSingleMoveDegree=$tiltStep&PanTiltSingleMove=$dir";
|
||||||
|
$self->sendCmd( $cmd, 'pantiltcontrol' );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRel
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
my $panStep = $self->getParam($params, 'panstep', 0);
|
||||||
|
my $tiltStep = $self->getParam($params, 'tiltstep', 0);
|
||||||
|
my $dir = shift;
|
||||||
|
$self->move( $dir, $panStep, $tiltStep );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelUpLeft
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelUp
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelUpRight
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelLeft
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelRight
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelDownLeft
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelDown
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 7 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub moveRelDownRight
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
$self->moveRel( $params, 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
# moves the camera to center on the point that the user clicked on in the video image.
|
||||||
|
# This isn't extremely accurate but good enough for most purposes
|
||||||
|
sub moveMap
|
||||||
|
{
|
||||||
|
# if the camera moves too much or too little, try increasing or decreasing this value
|
||||||
|
my $f = 11;
|
||||||
|
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
my $xcoord = $self->getParam( $params, 'xcoord' );
|
||||||
|
my $ycoord = $self->getParam( $params, 'ycoord' );
|
||||||
|
|
||||||
|
my $hor = $xcoord * 100 / $self->{Monitor}->{Width};
|
||||||
|
my $ver = $ycoord * 100 / $self->{Monitor}->{Height};
|
||||||
|
|
||||||
|
my $direction;
|
||||||
|
my $horSteps;
|
||||||
|
my $verSteps;
|
||||||
|
if ($hor < 50 && $ver < 50) {
|
||||||
|
# up left
|
||||||
|
$horSteps = (50 - $hor) / $f;
|
||||||
|
$verSteps = (50 - $ver) / $f;
|
||||||
|
$direction = 0;
|
||||||
|
} elsif ($hor >= 50 && $ver < 50) {
|
||||||
|
# up right
|
||||||
|
$horSteps = ($hor - 50) / $f;
|
||||||
|
$verSteps = (50 - $ver) / $f;
|
||||||
|
$direction = 2;
|
||||||
|
} elsif ($hor < 50 && $ver >= 50) {
|
||||||
|
# down left
|
||||||
|
$horSteps = (50 - $hor) / $f;
|
||||||
|
$verSteps = ($ver - 50) / $f;
|
||||||
|
$direction = 6;
|
||||||
|
} elsif ($hor >= 50 && $ver >= 50) {
|
||||||
|
# down right
|
||||||
|
$horSteps = ($hor - 50) / $f;
|
||||||
|
$verSteps = ($ver - 50) / $f;
|
||||||
|
$direction = 8;
|
||||||
|
}
|
||||||
|
my $v = int($verSteps + .5);
|
||||||
|
my $h = int($horSteps + .5);
|
||||||
|
Debug( "Move Map to $xcoord,$ycoord, hor=$h, ver=$v with direction $direction" );
|
||||||
|
$self->move( $direction, $h, $v );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub presetClear
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
my $preset = $self->getParam( $params, 'preset' );
|
||||||
|
Debug( "Clear Preset $preset" );
|
||||||
|
my $cmd = "ClearPosition=$preset";
|
||||||
|
$self->sendCmd( $cmd, 'pantiltcontrol' );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub presetSet
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
my $preset = $self->getParam( $params, 'preset' );
|
||||||
|
Debug( "Set Preset $preset" );
|
||||||
|
my $cmd = "SetCurrentPosition=$preset&SetName=preset_$preset";
|
||||||
|
$self->sendCmd( $cmd, 'pantiltcontrol' );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub presetGoto
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $params = shift;
|
||||||
|
my $preset = $self->getParam( $params, 'preset' );
|
||||||
|
Debug( "Goto Preset $preset" );
|
||||||
|
my $cmd = "PanTiltPresetPositionMove=$preset";
|
||||||
|
$self->sendCmd( $cmd, 'pantiltcontrol' );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub presetHome
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
Debug( "Home Preset" );
|
||||||
|
$self->move( 4, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# IR Controls
|
||||||
|
#
|
||||||
|
# wake = IR on
|
||||||
|
# sleep = IR off
|
||||||
|
# reset = IR auto
|
||||||
|
|
||||||
|
sub setDayNightMode {
|
||||||
|
my $self = shift;
|
||||||
|
my $mode = shift;
|
||||||
|
my $cmd = "DayNightMode=$mode&ConfigReboot=No";
|
||||||
|
$self->sendCmd( $cmd, 'daynight' );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub wake
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
Debug( "Wake - IR on" );
|
||||||
|
$self->setDayNightMode(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sleep
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
Debug( "Sleep - IR off" );
|
||||||
|
$self->setDayNightMode(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub reset
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
Debug( "Reset - IR auto" );
|
||||||
|
$self->setDayNightMode(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
__END__
|
||||||
|
# Below is stub documentation for your module. You'd better edit it!
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
ZoneMinder::Database - Perl extension for DCS-5020L
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
use ZoneMinder::Database;
|
||||||
|
DLINK DCS-5020L
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
ZoneMinder driver for the D-Link consumer camera DCS-5020L.
|
||||||
|
|
||||||
|
=head2 EXPORT
|
||||||
|
|
||||||
|
None by default.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
See if there are better instructions for the DCS-5020L at
|
||||||
|
http://www.zoneminder.com/wiki/index.php/Dlink
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Art Scheel <lt>ascheel (at) gmail<gt>
|
||||||
|
|
||||||
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
|
LGPLv3
|
||||||
|
|
||||||
|
=cut
|
|
@ -1,6 +1,6 @@
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
#
|
#
|
||||||
# ZoneMinder Filter Module, $Date$, $Revision$
|
# ZoneMinder Filter Module
|
||||||
# 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
|
||||||
|
@ -162,7 +162,9 @@ sub Sql {
|
||||||
my $value = $term->{val};
|
my $value = $term->{val};
|
||||||
my @value_list;
|
my @value_list;
|
||||||
if ( $term->{attr} ) {
|
if ( $term->{attr} ) {
|
||||||
if ( $term->{attr} =~ /^Monitor/ ) {
|
if ( $term->{attr} eq 'AlarmedZoneId' ) {
|
||||||
|
$term->{op} = 'EXISTS';
|
||||||
|
} elsif ( $term->{attr} =~ /^Monitor/ ) {
|
||||||
my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/;
|
my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/;
|
||||||
$self->{Sql} .= 'M.'.$temp_attr_name;
|
$self->{Sql} .= 'M.'.$temp_attr_name;
|
||||||
} elsif ( $term->{attr} eq 'ServerId' or $term->{attr} eq 'MonitorServerId' ) {
|
} elsif ( $term->{attr} eq 'ServerId' or $term->{attr} eq 'MonitorServerId' ) {
|
||||||
|
@ -214,7 +216,10 @@ sub Sql {
|
||||||
|
|
||||||
( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
|
( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
|
||||||
foreach my $temp_value ( split( /["'\s]*?,["'\s]*?/, $stripped_value ) ) {
|
foreach my $temp_value ( split( /["'\s]*?,["'\s]*?/, $stripped_value ) ) {
|
||||||
if ( $term->{attr} =~ /^MonitorName/ ) {
|
|
||||||
|
if ( $term->{attr} eq 'AlarmedZoneId' ) {
|
||||||
|
$value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')';
|
||||||
|
} elsif ( $term->{attr} =~ /^MonitorName/ ) {
|
||||||
$value = "'$temp_value'";
|
$value = "'$temp_value'";
|
||||||
} elsif ( $term->{attr} =~ /ServerId/) {
|
} elsif ( $term->{attr} =~ /ServerId/) {
|
||||||
Debug("ServerId, temp_value is ($temp_value) ($ZoneMinder::Config::Config{ZM_SERVER_ID})");
|
Debug("ServerId, temp_value is ($temp_value) ($ZoneMinder::Config::Config{ZM_SERVER_ID})");
|
||||||
|
@ -256,6 +261,8 @@ sub Sql {
|
||||||
} elsif ( $term->{attr} eq 'Date' or $term->{attr} eq 'StartDate' or $term->{attr} eq 'EndDate' ) {
|
} elsif ( $term->{attr} eq 'Date' or $term->{attr} eq 'StartDate' or $term->{attr} eq 'EndDate' ) {
|
||||||
if ( $temp_value eq 'NULL' ) {
|
if ( $temp_value eq 'NULL' ) {
|
||||||
$value = $temp_value;
|
$value = $temp_value;
|
||||||
|
} elsif ( $temp_value eq 'CURDATE()' or $temp_value eq 'NOW()' ) {
|
||||||
|
$value = 'to_days('.$temp_value.')';
|
||||||
} else {
|
} else {
|
||||||
$value = DateTimeToSQL($temp_value);
|
$value = DateTimeToSQL($temp_value);
|
||||||
if ( !$value ) {
|
if ( !$value ) {
|
||||||
|
@ -294,6 +301,8 @@ sub Sql {
|
||||||
} else {
|
} else {
|
||||||
$self->{Sql} .= " IS $value";
|
$self->{Sql} .= " IS $value";
|
||||||
}
|
}
|
||||||
|
} elsif ( $term->{op} eq 'EXISTS' ) {
|
||||||
|
$self->{Sql} .= " EXISTS $value";
|
||||||
} elsif ( $term->{op} eq 'IS NOT' ) {
|
} elsif ( $term->{op} eq 'IS NOT' ) {
|
||||||
$self->{Sql} .= " IS NOT $value";
|
$self->{Sql} .= " IS NOT $value";
|
||||||
} elsif ( $term->{op} eq '=[]' ) {
|
} elsif ( $term->{op} eq '=[]' ) {
|
||||||
|
|
|
@ -172,7 +172,7 @@ sub interpret_messages {
|
||||||
# functions
|
# functions
|
||||||
|
|
||||||
sub discover {
|
sub discover {
|
||||||
my ( $soap_version ) = @_;
|
my ( $soap_version, $net_interface ) = @_;
|
||||||
my @results;
|
my @results;
|
||||||
|
|
||||||
## collect all responses
|
## collect all responses
|
||||||
|
@ -192,13 +192,18 @@ sub discover {
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) {
|
if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) {
|
||||||
my %services;
|
my %services;
|
||||||
|
|
||||||
if($verbose) {
|
if ( $verbose ) {
|
||||||
print "Probing for SOAP 1.1\n"
|
print "Probing for SOAP 1.1\n";
|
||||||
}
|
}
|
||||||
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
||||||
# no_dispatch => '1',
|
# no_dispatch => '1',
|
||||||
});
|
});
|
||||||
$svc_discover->set_soap_version('1.1');
|
$svc_discover->set_soap_version('1.1');
|
||||||
|
if ( $net_interface ) {
|
||||||
|
my $transport = $svc_discover->get_transport();
|
||||||
|
print "Setting net interface for $transport to $net_interface\n";
|
||||||
|
$transport->set_net_interface($net_interface);
|
||||||
|
}
|
||||||
|
|
||||||
my $uuid = $uuid_gen->create_str();
|
my $uuid = $uuid_gen->create_str();
|
||||||
|
|
||||||
|
@ -221,13 +226,18 @@ sub discover {
|
||||||
|
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) {
|
if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) {
|
||||||
my %services;
|
my %services;
|
||||||
if($verbose) {
|
if ( $verbose ) {
|
||||||
print "Probing for SOAP 1.2\n"
|
print "Probing for SOAP 1.2\n";
|
||||||
}
|
}
|
||||||
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
||||||
# no_dispatch => '1',
|
# no_dispatch => '1',
|
||||||
});
|
});
|
||||||
$svc_discover->set_soap_version('1.2');
|
$svc_discover->set_soap_version('1.2');
|
||||||
|
if ( $net_interface ) {
|
||||||
|
my $transport = $svc_discover->get_transport();
|
||||||
|
print "Setting net interface for $transport to $net_interface\n";
|
||||||
|
$transport->set_net_interface($net_interface);
|
||||||
|
}
|
||||||
|
|
||||||
# copies of the same Probe message must have the same MessageID.
|
# copies of the same Probe message must have the same MessageID.
|
||||||
# This is not a copy. So we generate a new uuid.
|
# This is not a copy. So we generate a new uuid.
|
||||||
|
@ -250,7 +260,7 @@ sub discover {
|
||||||
push @results, interpret_messages($svc_discover, \%services, @responses);
|
push @results, interpret_messages($svc_discover, \%services, @responses);
|
||||||
} # end if doing soap 1.2
|
} # end if doing soap 1.2
|
||||||
return @results;
|
return @results;
|
||||||
}
|
} # end sub discover
|
||||||
|
|
||||||
sub profiles {
|
sub profiles {
|
||||||
my ( $client ) = @_;
|
my ( $client ) = @_;
|
||||||
|
|
|
@ -352,10 +352,13 @@ sub exportsql {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $name = $ARGV[0];
|
my $name = $ARGV[0];
|
||||||
if ($name) {
|
if ( $name ) {
|
||||||
$name =~ /([A-Za-z0-9 -]*)/; # Only allow alphanumeric, dash and space
|
if ( $name =~ /^([A-Za-z0-9 ,.&()\/\-]+)$/ ) { # Allow alphanumeric and " ,.&()/-"
|
||||||
$name = $1;
|
$name = $1;
|
||||||
$command .= qq( --where="Name = '$name'");
|
$command .= qq( --where="Name = '$name'");
|
||||||
|
} else {
|
||||||
|
print "Invalid characters in Name\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$command .= " zm Controls MonitorPresets";
|
$command .= " zm Controls MonitorPresets";
|
||||||
|
|
|
@ -196,7 +196,7 @@ my $last_action = 0;
|
||||||
while( !$zm_terminate ) {
|
while( !$zm_terminate ) {
|
||||||
my $now = time;
|
my $now = time;
|
||||||
if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) {
|
if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) {
|
||||||
Debug("Reloading filters");
|
Debug('Reloading filters');
|
||||||
$last_action = $now;
|
$last_action = $now;
|
||||||
@filters = getFilters({ Name=>$filter_name, Id=>$filter_id });
|
@filters = getFilters({ Name=>$filter_name, Id=>$filter_id });
|
||||||
}
|
}
|
||||||
|
@ -699,8 +699,10 @@ sub substituteTags {
|
||||||
$text =~ s/%ESM%/$Event->{MaxScore}/g;
|
$text =~ s/%ESM%/$Event->{MaxScore}/g;
|
||||||
|
|
||||||
if ( $first_alarm_frame ) {
|
if ( $first_alarm_frame ) {
|
||||||
$text =~ s/%EPI1%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
|
$text =~ s/%EPF1%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
|
||||||
$text =~ s/%EPIM%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
|
$text =~ s/%EPFM%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
|
||||||
|
$text =~ s/%EPI1%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
|
||||||
|
$text =~ s/%EPIM%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
|
||||||
if ( $attachments_ref ) {
|
if ( $attachments_ref ) {
|
||||||
if ( $text =~ s/%EI1%//g ) {
|
if ( $text =~ s/%EI1%//g ) {
|
||||||
my $path = generateImage($Event, $first_alarm_frame);
|
my $path = generateImage($Event, $first_alarm_frame);
|
||||||
|
@ -748,13 +750,14 @@ sub substituteTags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $text =~ s/%EIMOD%//g ) {
|
if ( $text =~ s/%EIMOD%//g or $text =~ s/%EFMOD%//g ) {
|
||||||
$text =~ s/%EIMOD%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g;
|
$text =~ s/%EFMOD%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g;
|
||||||
|
$text =~ s/%EIMOD%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g;
|
||||||
my $path = $Event->Path().'/objdetect.jpg';
|
my $path = $Event->Path().'/objdetect.jpg';
|
||||||
if ( -e $path ) {
|
if ( -e $path ) {
|
||||||
push @$attachments_ref, { type=>'image/jpeg', path=>$path };
|
push @$attachments_ref, { type=>'image/jpeg', path=>$path };
|
||||||
} else {
|
} else {
|
||||||
Warning('No image for EIMOD at ' . $path);
|
Warning('No image for MOD at '.$path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,17 +799,17 @@ sub sendEmail {
|
||||||
Error('No from email address defined, not sending email');
|
Error('No from email address defined, not sending email');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( ! $Config{ZM_EMAIL_ADDRESS} ) {
|
if ( ! $$filter{EmailTo} ) {
|
||||||
Error('No email address defined, not sending email');
|
Error('No email address defined, not sending email');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info('Creating notification email');
|
Info('Creating notification email');
|
||||||
|
|
||||||
my $subject = substituteTags($Config{ZM_EMAIL_SUBJECT}, $filter, $Event);
|
my $subject = substituteTags($$filter{EmailSubject}, $filter, $Event);
|
||||||
return 0 if !$subject;
|
return 0 if !$subject;
|
||||||
my @attachments;
|
my @attachments;
|
||||||
my $body = substituteTags($Config{ZM_EMAIL_BODY}, $filter, $Event, \@attachments);
|
my $body = substituteTags($$filter{EmailBody}, $filter, $Event, \@attachments);
|
||||||
return 0 if !$body;
|
return 0 if !$body;
|
||||||
|
|
||||||
Info("Sending notification email '$subject'");
|
Info("Sending notification email '$subject'");
|
||||||
|
@ -816,7 +819,7 @@ sub sendEmail {
|
||||||
### Create the multipart container
|
### Create the multipart container
|
||||||
my $mail = MIME::Lite->new (
|
my $mail = MIME::Lite->new (
|
||||||
From => $Config{ZM_FROM_EMAIL},
|
From => $Config{ZM_FROM_EMAIL},
|
||||||
To => $Config{ZM_EMAIL_ADDRESS},
|
To => $$filter{EmailTo},
|
||||||
Subject => $subject,
|
Subject => $subject,
|
||||||
Type => 'multipart/mixed'
|
Type => 'multipart/mixed'
|
||||||
);
|
);
|
||||||
|
@ -827,7 +830,7 @@ sub sendEmail {
|
||||||
);
|
);
|
||||||
### Add the attachments
|
### Add the attachments
|
||||||
foreach my $attachment ( @attachments ) {
|
foreach my $attachment ( @attachments ) {
|
||||||
Info( "Attaching '$attachment->{path}'" );
|
Info("Attaching '$attachment->{path}'");
|
||||||
$mail->attach(
|
$mail->attach(
|
||||||
Path => $attachment->{path},
|
Path => $attachment->{path},
|
||||||
Type => $attachment->{type},
|
Type => $attachment->{type},
|
||||||
|
@ -849,7 +852,7 @@ sub sendEmail {
|
||||||
$mail->send();
|
$mail->send();
|
||||||
} else {
|
} else {
|
||||||
### Send using SSMTP
|
### Send using SSMTP
|
||||||
$mail->send('sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS});
|
$mail->send('sendmail', $ssmtp_location, $$filter{EmailTo});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MIME::Lite->send('smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60);
|
MIME::Lite->send('smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60);
|
||||||
|
@ -858,7 +861,7 @@ sub sendEmail {
|
||||||
} else {
|
} else {
|
||||||
my $mail = MIME::Entity->build(
|
my $mail = MIME::Entity->build(
|
||||||
From => $Config{ZM_FROM_EMAIL},
|
From => $Config{ZM_FROM_EMAIL},
|
||||||
To => $Config{ZM_EMAIL_ADDRESS},
|
To => $$filter{EmailTo},
|
||||||
Subject => $subject,
|
Subject => $subject,
|
||||||
Type => (($body=~/<html>/)?'text/html':'text/plain'),
|
Type => (($body=~/<html>/)?'text/html':'text/plain'),
|
||||||
Data => $body
|
Data => $body
|
||||||
|
|
|
@ -41,7 +41,7 @@ my $OPTIONS = 'v';
|
||||||
|
|
||||||
sub HELP_MESSAGE {
|
sub HELP_MESSAGE {
|
||||||
my ($fh, $pkg, $ver, $opts) = @_;
|
my ($fh, $pkg, $ver, $opts) = @_;
|
||||||
print $fh "Usage: " . __FILE__ . " [-v] probe <soap version>\n";
|
print $fh "Usage: " . __FILE__ . " [-v] probe <soap version> <network interface>\n";
|
||||||
print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n";
|
print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n";
|
||||||
print $fh <<EOF
|
print $fh <<EOF
|
||||||
Commands are:
|
Commands are:
|
||||||
|
@ -69,7 +69,7 @@ if ( !getopts($OPTIONS) ) {
|
||||||
|
|
||||||
my $action = shift;
|
my $action = shift;
|
||||||
|
|
||||||
if(!defined $action) {
|
if ( ! defined $action ) {
|
||||||
HELP_MESSAGE(\*STDOUT);
|
HELP_MESSAGE(\*STDOUT);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,8 @@ if ( defined $opt_v ) {
|
||||||
|
|
||||||
if ( $action eq 'probe' ) {
|
if ( $action eq 'probe' ) {
|
||||||
my $soap_version = shift;
|
my $soap_version = shift;
|
||||||
ZoneMinder::ONVIF::discover($soap_version);
|
my $net_interface = shift;
|
||||||
|
ZoneMinder::ONVIF::discover($soap_version, $net_interface);
|
||||||
} else {
|
} else {
|
||||||
# all other actions need URI and credentials
|
# all other actions need URI and credentials
|
||||||
my $url_svc_device = shift @ARGV;
|
my $url_svc_device = shift @ARGV;
|
||||||
|
|
|
@ -234,7 +234,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) {
|
||||||
} else {
|
} else {
|
||||||
if ( ioctl( sd, FIONREAD, &total_bytes_to_read ) < 0 ) {
|
if ( ioctl( sd, FIONREAD, &total_bytes_to_read ) < 0 ) {
|
||||||
Error( "Can't ioctl(): %s", strerror(errno) );
|
Error( "Can't ioctl(): %s", strerror(errno) );
|
||||||
return( -1 );
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( total_bytes_to_read == 0 ) {
|
if ( total_bytes_to_read == 0 ) {
|
||||||
|
@ -242,20 +242,20 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
socklen_t len = sizeof (error);
|
socklen_t len = sizeof (error);
|
||||||
int retval = getsockopt( sd, SOL_SOCKET, SO_ERROR, &error, &len );
|
int retval = getsockopt( sd, SOL_SOCKET, SO_ERROR, &error, &len );
|
||||||
if(retval != 0 ) {
|
if ( retval != 0 ) {
|
||||||
Debug( 1, "error getting socket error code %s", strerror(retval) );
|
Debug( 1, "error getting socket error code %s", strerror(retval) );
|
||||||
}
|
}
|
||||||
if (error != 0) {
|
if ( error != 0 ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Case where we are grabbing a single jpg, but no content-length was given, so the expectation is that we read until close.
|
// Case where we are grabbing a single jpg, but no content-length was given, so the expectation is that we read until close.
|
||||||
return( 0 );
|
return 0;
|
||||||
}
|
}
|
||||||
// If socket is closed locally, then select will fail, but if it is closed remotely
|
// If socket is closed locally, then select will fail, but if it is closed remotely
|
||||||
// then we have an exception on our socket.. but no data.
|
// then we have an exception on our socket.. but no data.
|
||||||
Debug( 3, "Socket closed remotely" );
|
Debug(3, "Socket closed remotely");
|
||||||
//Disconnect(); // Disconnect is done outside of ReadData now.
|
//Disconnect(); // Disconnect is done outside of ReadData now.
|
||||||
return( -1 );
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There can be lots of bytes available. I've seen 4MB or more. This will vastly inflate our buffer size unnecessarily.
|
// There can be lots of bytes available. I've seen 4MB or more. This will vastly inflate our buffer size unnecessarily.
|
||||||
|
@ -292,6 +292,18 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) {
|
||||||
return total_bytes_read;
|
return total_bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RemoteCameraHttp::GetData() {
|
||||||
|
time_t start_time = time(NULL);
|
||||||
|
int buffer_len = 0;
|
||||||
|
while ( !( buffer_len = ReadData(buffer) ) ) {
|
||||||
|
if ( zm_terminate || ( start_time - time(NULL) < ZM_WATCH_MAX_DELAY ))
|
||||||
|
return -1;
|
||||||
|
Debug(4, "Timeout waiting for REGEXP HEADER");
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
return buffer_len;
|
||||||
|
}
|
||||||
|
|
||||||
int RemoteCameraHttp::GetResponse() {
|
int RemoteCameraHttp::GetResponse() {
|
||||||
int buffer_len;
|
int buffer_len;
|
||||||
#if HAVE_LIBPCRE
|
#if HAVE_LIBPCRE
|
||||||
|
@ -314,9 +326,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
switch( state ) {
|
switch( state ) {
|
||||||
case HEADER :
|
case HEADER :
|
||||||
{
|
{
|
||||||
while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
|
buffer_len = GetData();
|
||||||
Debug(4, "Timeout waiting for REGEXP HEADER");
|
|
||||||
}
|
|
||||||
if ( buffer_len < 0 ) {
|
if ( buffer_len < 0 ) {
|
||||||
Error("Unable to read header data");
|
Error("Unable to read header data");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -478,9 +488,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
||||||
while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
|
buffer_len = GetData();
|
||||||
Debug(4, "Timeout waiting to extract subheader");
|
|
||||||
}
|
|
||||||
if ( buffer_len < 0 ) {
|
if ( buffer_len < 0 ) {
|
||||||
Error( "Unable to extract subheader data" );
|
Error( "Unable to extract subheader data" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -521,7 +529,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
while ( ((long)buffer.size() < content_length ) && ! zm_terminate )
|
while ( ((long)buffer.size() < content_length ) && ! zm_terminate )
|
||||||
{
|
{
|
||||||
Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length );
|
Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length );
|
||||||
int bytes_read = ReadData( buffer );
|
int bytes_read = GetData();
|
||||||
|
|
||||||
if ( bytes_read < 0 ) {
|
if ( bytes_read < 0 ) {
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
|
@ -535,9 +543,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
{
|
{
|
||||||
while ( !content_length )
|
while ( !content_length )
|
||||||
{
|
{
|
||||||
while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
|
buffer_len = GetData();
|
||||||
Debug(4, "Timeout waiting for content");
|
|
||||||
}
|
|
||||||
if ( buffer_len < 0 ) {
|
if ( buffer_len < 0 ) {
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -652,9 +658,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
}
|
}
|
||||||
case HEADERCONT :
|
case HEADERCONT :
|
||||||
{
|
{
|
||||||
while ( !( buffer_len = ReadData(buffer) ) && !zm_terminate ) {
|
buffer_len = GetData();
|
||||||
Debug(1, "Timeout waiting for HEADERCONT");
|
|
||||||
}
|
|
||||||
if ( buffer_len < 0 ) {
|
if ( buffer_len < 0 ) {
|
||||||
Error("Unable to read header");
|
Error("Unable to read header");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -939,9 +943,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
state = CONTENT;
|
state = CONTENT;
|
||||||
} else {
|
} else {
|
||||||
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
||||||
while ( !( buffer_len = ReadData(buffer) ) &&!zm_terminate ) {
|
buffer_len = GetData();
|
||||||
Debug(1, "Timeout waiting to extra subheader non regexp");
|
|
||||||
}
|
|
||||||
if ( buffer_len < 0 ) {
|
if ( buffer_len < 0 ) {
|
||||||
Error( "Unable to read subheader" );
|
Error( "Unable to read subheader" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -981,7 +983,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
if ( content_length ) {
|
if ( content_length ) {
|
||||||
while ( ( (long)buffer.size() < content_length ) && ! zm_terminate ) {
|
while ( ( (long)buffer.size() < content_length ) && ! zm_terminate ) {
|
||||||
Debug(4, "getting more data");
|
Debug(4, "getting more data");
|
||||||
int bytes_read = ReadData(buffer);
|
int bytes_read = GetData();
|
||||||
if ( bytes_read < 0 ) {
|
if ( bytes_read < 0 ) {
|
||||||
Error("Unable to read content");
|
Error("Unable to read content");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -994,8 +996,7 @@ int RemoteCameraHttp::GetResponse() {
|
||||||
while ( !content_length && !zm_terminate ) {
|
while ( !content_length && !zm_terminate ) {
|
||||||
Debug(4, "!content_length, ReadData");
|
Debug(4, "!content_length, ReadData");
|
||||||
buffer_len = ReadData( buffer );
|
buffer_len = ReadData( buffer );
|
||||||
if ( buffer_len < 0 )
|
if ( buffer_len < 0 ) {
|
||||||
{
|
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
int Disconnect();
|
int Disconnect();
|
||||||
int SendRequest();
|
int SendRequest();
|
||||||
int ReadData( Buffer &buffer, unsigned int bytes_expected=0 );
|
int ReadData( Buffer &buffer, unsigned int bytes_expected=0 );
|
||||||
|
int GetData();
|
||||||
int GetResponse();
|
int GetResponse();
|
||||||
int PreCapture();
|
int PreCapture();
|
||||||
int Capture( Image &image );
|
int Capture( Image &image );
|
||||||
|
|
|
@ -11,6 +11,9 @@ class Filter extends ZM_Object {
|
||||||
'AutoExecute' => 0,
|
'AutoExecute' => 0,
|
||||||
'AutoExecuteCmd' => 0,
|
'AutoExecuteCmd' => 0,
|
||||||
'AutoEmail' => 0,
|
'AutoEmail' => 0,
|
||||||
|
'EmailTo' => '',
|
||||||
|
'EmailSubject' => '',
|
||||||
|
'EmailBody' => '',
|
||||||
'AutoDelete' => 0,
|
'AutoDelete' => 0,
|
||||||
'AutoArchive' => 0,
|
'AutoArchive' => 0,
|
||||||
'AutoVideo' => 0,
|
'AutoVideo' => 0,
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
namespace ZM;
|
||||||
|
require_once('database.php');
|
||||||
|
require_once('Object.php');
|
||||||
|
|
||||||
|
|
||||||
|
class Zone extends ZM_Object {
|
||||||
|
protected static $table = 'Zones';
|
||||||
|
|
||||||
|
protected $defaults = array(
|
||||||
|
'Id' => null,
|
||||||
|
'Name' => '',
|
||||||
|
'Type' => 'Active',
|
||||||
|
'Units' => 'Pixels',
|
||||||
|
'CheckMethod' => 'Blobs',
|
||||||
|
'MinPixelThreshold' => null,
|
||||||
|
'MaxPixelThreshold' => null,
|
||||||
|
'MinAlarmPixels' => null,
|
||||||
|
'MaxAlarmPixels' => null,
|
||||||
|
'FilterX' => null,
|
||||||
|
'FilterY' => null,
|
||||||
|
'MinFilterPixels' => null,
|
||||||
|
'MaxFilterPixels' => null,
|
||||||
|
'MinBlobPixels' => null,
|
||||||
|
'MaxBlobPixels' => null,
|
||||||
|
'MinBlobs' => null,
|
||||||
|
'MaxBlobs' => null,
|
||||||
|
'OverloadFrames' => 0,
|
||||||
|
'ExtendAlarmFrames' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function find( $parameters = array(), $options = array() ) {
|
||||||
|
return ZM_Object::_find(get_class(), $parameters, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function find_one( $parameters = array(), $options = array() ) {
|
||||||
|
return ZM_Object::_find_one(get_class(), $parameters, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
} # end class Zone
|
||||||
|
?>
|
|
@ -1094,6 +1094,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||||
for ( $i = 0; $i < count($terms); $i++ ) {
|
for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
|
|
||||||
$term = $terms[$i];
|
$term = $terms[$i];
|
||||||
|
ZM\Logger::Debug("Term: " . print_r($term,true));
|
||||||
|
|
||||||
if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) {
|
if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) {
|
||||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']);
|
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']);
|
||||||
|
@ -1109,6 +1110,9 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']);
|
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']);
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][attr]\" value=\"".htmlspecialchars($term['attr'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][attr]\" value=\"".htmlspecialchars($term['attr'])."\"/>\n";
|
||||||
switch ( $term['attr'] ) {
|
switch ( $term['attr'] ) {
|
||||||
|
case 'AlarmedZoneId':
|
||||||
|
$term['op'] = 'EXISTS';
|
||||||
|
break;
|
||||||
case 'MonitorName':
|
case 'MonitorName':
|
||||||
$filter['sql'] .= 'M.Name';
|
$filter['sql'] .= 'M.Name';
|
||||||
break;
|
break;
|
||||||
|
@ -1226,11 +1230,15 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||||
$valueList = array();
|
$valueList = array();
|
||||||
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
|
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
|
||||||
switch ( $term['attr'] ) {
|
switch ( $term['attr'] ) {
|
||||||
|
|
||||||
|
case 'AlarmedZoneId':
|
||||||
|
$value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')';
|
||||||
|
break;
|
||||||
case 'MonitorName':
|
case 'MonitorName':
|
||||||
case 'Name':
|
case 'Name':
|
||||||
case 'Cause':
|
case 'Cause':
|
||||||
case 'Notes':
|
case 'Notes':
|
||||||
if($term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE') {
|
if ( $term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE' ) {
|
||||||
$value = '%'.$value.'%';
|
$value = '%'.$value.'%';
|
||||||
}
|
}
|
||||||
$value = dbEscape($value);
|
$value = dbEscape($value);
|
||||||
|
@ -1261,8 +1269,11 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||||
case 'Date':
|
case 'Date':
|
||||||
case 'StartDate':
|
case 'StartDate':
|
||||||
case 'EndDate':
|
case 'EndDate':
|
||||||
if ( $value != 'NULL' )
|
if ( $value == 'CURDATE()' or $value == 'NOW()' ) {
|
||||||
|
$value = 'to_days('.$value.')';
|
||||||
|
} else if ( $value != 'NULL' ) {
|
||||||
$value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
|
$value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'Time':
|
case 'Time':
|
||||||
case 'StartTime':
|
case 'StartTime':
|
||||||
|
@ -1297,10 +1308,13 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||||
break;
|
break;
|
||||||
case '=[]' :
|
case '=[]' :
|
||||||
case 'IN' :
|
case 'IN' :
|
||||||
$filter['sql'] .= ' in ('.join(',', $valueList).')';
|
$filter['sql'] .= ' IN ('.join(',', $valueList).')';
|
||||||
break;
|
break;
|
||||||
case '![]' :
|
case '![]' :
|
||||||
$filter['sql'] .= ' not in ('.join(',', $valueList).')';
|
$filter['sql'] .= ' not in ('.join(',', $valueList).')';
|
||||||
|
break;
|
||||||
|
case 'EXISTS' :
|
||||||
|
$filter['sql'] .= ' EXISTS ' .$value;
|
||||||
break;
|
break;
|
||||||
case 'IS' :
|
case 'IS' :
|
||||||
if ( $value == 'Odd' ) {
|
if ( $value == 'Odd' ) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ if ( version_compare(phpversion(), '4.1.0', '<') ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useful debugging lines for mobile devices
|
// Useful debugging lines for mobile devices
|
||||||
if ( false ) {
|
if ( true ) {
|
||||||
ob_start();
|
ob_start();
|
||||||
phpinfo(INFO_VARIABLES);
|
phpinfo(INFO_VARIABLES);
|
||||||
$fp = fopen('/tmp/env.html', 'w+');
|
$fp = fopen('/tmp/env.html', 'w+');
|
||||||
|
@ -71,7 +71,7 @@ define('ZM_BASE_URL', '');
|
||||||
|
|
||||||
require_once('includes/functions.php');
|
require_once('includes/functions.php');
|
||||||
if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
|
if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
|
||||||
ZM\Logger::Debug("OPTIONS Method, only doing CORS");
|
ZM\Logger::Debug('OPTIONS Method, only doing CORS');
|
||||||
# Add Cross domain access headers
|
# Add Cross domain access headers
|
||||||
CORSHeaders();
|
CORSHeaders();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -116,6 +116,7 @@ $SLANG = array(
|
||||||
'Area' => 'Area',
|
'Area' => 'Area',
|
||||||
'AreaUnits' => 'Area (px/%)',
|
'AreaUnits' => 'Area (px/%)',
|
||||||
'AttrAlarmFrames' => 'Alarm Frames',
|
'AttrAlarmFrames' => 'Alarm Frames',
|
||||||
|
'AttrAlarmedZone' => 'Alarmed Zone',
|
||||||
'AttrArchiveStatus' => 'Archive Status',
|
'AttrArchiveStatus' => 'Archive Status',
|
||||||
'AttrAvgScore' => 'Avg. Score',
|
'AttrAvgScore' => 'Avg. Score',
|
||||||
'AttrCause' => 'Cause',
|
'AttrCause' => 'Cause',
|
||||||
|
@ -361,6 +362,9 @@ $SLANG = array(
|
||||||
'FilterCopyEvents' => 'Copy all matches',
|
'FilterCopyEvents' => 'Copy all matches',
|
||||||
'FilterMoveEvents' => 'Move all matches',
|
'FilterMoveEvents' => 'Move all matches',
|
||||||
'FilterEmailEvents' => 'Email details of all matches',
|
'FilterEmailEvents' => 'Email details of all matches',
|
||||||
|
'FilterEmailTo' => 'Email To',
|
||||||
|
'FilterEmailSubject' => 'Email Subject',
|
||||||
|
'FilterEmailBody' => 'Email Body',
|
||||||
'FilterExecuteEvents' => 'Execute command on all matches',
|
'FilterExecuteEvents' => 'Execute command on all matches',
|
||||||
'FilterLog' => 'Filter log',
|
'FilterLog' => 'Filter log',
|
||||||
'FilterMessageEvents' => 'Message details of all matches',
|
'FilterMessageEvents' => 'Message details of all matches',
|
||||||
|
|
|
@ -56,9 +56,14 @@ select {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
input[name="filter[EmailSubject]"],
|
||||||
|
input[name="filter[EmailTo]"],
|
||||||
|
textarea[name="filter[EmailBody]"] {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
select#Id {
|
select#Id {
|
||||||
min-width: 400px;
|
min-width: 500px;
|
||||||
}
|
}
|
||||||
.Name input {
|
.Name input {
|
||||||
min-width: 400px;
|
min-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,21 +191,25 @@ while ( $event_row = dbFetchNext($results) ) {
|
||||||
?>
|
?>
|
||||||
<tr<?php if ($event->Archived()) echo ' class="archived"' ?>>
|
<tr<?php if ($event->Archived()) echo ' class="archived"' ?>>
|
||||||
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
||||||
<td class="colName"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
|
<td class="colName"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a><br/>
|
||||||
|
<?php
|
||||||
|
if ( $event->Emailed() )
|
||||||
|
echo 'Emailed ';
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
<td class="colMonitorName"><?php echo makePopupLink( '?view=monitor&mid='.$event->MonitorId(), 'zmMonitor'.$event->MonitorId(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
<td class="colMonitorName"><?php echo makePopupLink( '?view=monitor&mid='.$event->MonitorId(), 'zmMonitor'.$event->MonitorId(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
||||||
<td class="colCause"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?>
|
<td class="colCause"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?>
|
||||||
<?php
|
<?php
|
||||||
# display notes as small text
|
# display notes as small text
|
||||||
if ($event->Notes()) {
|
if ( $event->Notes() ) {
|
||||||
# if notes include detection objects, then link it to objdetect.jpg
|
# if notes include detection objects, then link it to objdetect.jpg
|
||||||
if (strpos($event->Notes(),'detected:')!== false){
|
if ( strpos($event->Notes(), 'detected:') !== false ) {
|
||||||
# make a link
|
# make a link
|
||||||
echo makePopupLink( '?view=image&eid='.$event->Id().'&fid=objdetect', 'zmImage',
|
echo makePopupLink( '?view=image&eid='.$event->Id().'&fid=objdetect', 'zmImage',
|
||||||
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)),
|
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)),
|
||||||
"<div class=\"small text-nowrap text-muted\"><u>".$event->Notes()."</u></div>");
|
'<div class="small text-nowrap text-muted"><u>'.$event->Notes().'</u></div>');
|
||||||
}
|
} else if ( $event->Notes() != 'Forced Web: ' ) {
|
||||||
elseif ($event->Notes() != 'Forced Web: ') {
|
echo '<br/><div class="small text-nowrap text-muted">'.$event->Notes().'</div>';
|
||||||
echo "<br/><div class=\"small text-nowrap text-muted\">".$event->Notes()."</div>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
//
|
||||||
// ZoneMinder web filter view file, $Date$, $Revision$
|
// ZoneMinder web filter view file
|
||||||
// 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
|
||||||
|
@ -25,6 +25,8 @@ if ( !canView('Events') ) {
|
||||||
require_once('includes/Object.php');
|
require_once('includes/Object.php');
|
||||||
require_once('includes/Storage.php');
|
require_once('includes/Storage.php');
|
||||||
require_once('includes/Filter.php');
|
require_once('includes/Filter.php');
|
||||||
|
require_once('includes/Monitor.php');
|
||||||
|
require_once('includes/Zone.php');
|
||||||
parseSort();
|
parseSort();
|
||||||
|
|
||||||
$filterNames = array(''=>translate('ChooseFilter'));
|
$filterNames = array(''=>translate('ChooseFilter'));
|
||||||
|
@ -69,6 +71,7 @@ if ( count($terms) ) {
|
||||||
|
|
||||||
$attrTypes = array(
|
$attrTypes = array(
|
||||||
'AlarmFrames' => translate('AttrAlarmFrames'),
|
'AlarmFrames' => translate('AttrAlarmFrames'),
|
||||||
|
'AlarmedZoneId' => translate('AttrAlarmedZone'),
|
||||||
'Archived' => translate('AttrArchiveStatus'),
|
'Archived' => translate('AttrArchiveStatus'),
|
||||||
'AvgScore' => translate('AttrAvgScore'),
|
'AvgScore' => translate('AttrAvgScore'),
|
||||||
'Cause' => translate('AttrCause'),
|
'Cause' => translate('AttrCause'),
|
||||||
|
@ -78,17 +81,17 @@ $attrTypes = array(
|
||||||
'EndDateTime' => translate('AttrEndDateTime'),
|
'EndDateTime' => translate('AttrEndDateTime'),
|
||||||
'EndDate' => translate('AttrEndDate'),
|
'EndDate' => translate('AttrEndDate'),
|
||||||
'EndTime' => translate('AttrEndTime'),
|
'EndTime' => translate('AttrEndTime'),
|
||||||
|
'EndWeekday' => translate('AttrEndWeekday'),
|
||||||
'FilterServerId' => translate('AttrFilterServer'),
|
'FilterServerId' => translate('AttrFilterServer'),
|
||||||
'Frames' => translate('AttrFrames'),
|
'Frames' => translate('AttrFrames'),
|
||||||
'EndWeekday' => translate('AttrEndWeekday'),
|
|
||||||
'Id' => translate('AttrId'),
|
'Id' => translate('AttrId'),
|
||||||
'Length' => translate('AttrDuration'),
|
'Length' => translate('AttrDuration'),
|
||||||
'Name' => translate('AttrName'),
|
|
||||||
'Notes' => translate('AttrNotes'),
|
|
||||||
'MaxScore' => translate('AttrMaxScore'),
|
'MaxScore' => translate('AttrMaxScore'),
|
||||||
'MonitorId' => translate('AttrMonitorId'),
|
'MonitorId' => translate('AttrMonitorId'),
|
||||||
'MonitorName' => translate('AttrMonitorName'),
|
'MonitorName' => translate('AttrMonitorName'),
|
||||||
'MonitorServerId' => translate('AttrMonitorServer'),
|
'MonitorServerId' => translate('AttrMonitorServer'),
|
||||||
|
'Name' => translate('AttrName'),
|
||||||
|
'Notes' => translate('AttrNotes'),
|
||||||
'SecondaryStorageId' => translate('AttrSecondaryStorageArea'),
|
'SecondaryStorageId' => translate('AttrSecondaryStorageArea'),
|
||||||
'ServerId' => translate('AttrMonitorServer'),
|
'ServerId' => translate('AttrMonitorServer'),
|
||||||
'StartDateTime' => translate('AttrStartDateTime'),
|
'StartDateTime' => translate('AttrStartDateTime'),
|
||||||
|
@ -143,13 +146,22 @@ foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Servers` ORDER BY lower(`Name`)
|
||||||
$servers[$server['Id']] = validHtmlStr($server['Name']);
|
$servers[$server['Id']] = validHtmlStr($server['Name']);
|
||||||
}
|
}
|
||||||
$monitors = array();
|
$monitors = array();
|
||||||
|
$monitor_names = array();
|
||||||
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Monitors` ORDER BY lower(`Name`) ASC') as $monitor ) {
|
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Monitors` ORDER BY lower(`Name`) ASC') as $monitor ) {
|
||||||
if ( visibleMonitor($monitor['Id']) ) {
|
if ( visibleMonitor($monitor['Id']) ) {
|
||||||
$monitors[$monitor['Name']] = validHtmlStr($monitor['Name']);
|
$monitors[$monitor['Id']] = new ZM\Monitor($monitor);
|
||||||
|
$monitor_names[] = validHtmlStr($monitor['Name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$zones = array();
|
||||||
|
foreach ( dbFetchAll('SELECT Id, Name, MonitorId FROM Zones ORDER BY lower(`Name`) ASC') as $zone ) {
|
||||||
|
if ( visibleMonitor($zone['MonitorId']) ) {
|
||||||
|
$zone['Name'] = validHtmlStr($monitors[$zone['MonitorId']]->Name().': '.$zone['Name']);
|
||||||
|
$zones[$zone['Id']] = new ZM\Zone($zone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('EventFilter') );
|
xhtmlHeaders(__FILE__, translate('EventFilter'));
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
|
@ -259,10 +271,15 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $weekdays, $term['val']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $weekdays, $term['val']); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'MonitorName' ) {
|
} elseif ( $term['attr'] == 'Monitor' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $monitors, $term['val']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $monitors, $term['val']); ?></td>
|
||||||
|
<?php
|
||||||
|
} elseif ( $term['attr'] == 'MonitorName' ) {
|
||||||
|
?>
|
||||||
|
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||||
|
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", array_combine($monitor_names,$monitor_names), $term['val']); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'ServerId' || $term['attr'] == 'MonitorServerId' || $term['attr'] == 'StorageServerId' || $term['attr'] == 'FilterServerId' ) {
|
} elseif ( $term['attr'] == 'ServerId' || $term['attr'] == 'MonitorServerId' || $term['attr'] == 'StorageServerId' || $term['attr'] == 'FilterServerId' ) {
|
||||||
?>
|
?>
|
||||||
|
@ -273,6 +290,11 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||||
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $storageareas, $term['val']); ?></td>
|
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $storageareas, $term['val']); ?></td>
|
||||||
|
<?php
|
||||||
|
} elseif ( $term['attr'] == 'AlarmedZoneId' ) {
|
||||||
|
?>
|
||||||
|
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||||
|
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $zones, $term['val']); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
|
@ -365,8 +387,22 @@ if ( ZM_OPT_EMAIL ) {
|
||||||
?>
|
?>
|
||||||
<p>
|
<p>
|
||||||
<label><?php echo translate('FilterEmailEvents') ?></label>
|
<label><?php echo translate('FilterEmailEvents') ?></label>
|
||||||
<input type="checkbox" name="filter[AutoEmail]" value="1"<?php if ( $filter->AutoEmail() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
<input type="checkbox" name="filter[AutoEmail]" value="1"<?php if ( $filter->AutoEmail() ) { ?> checked="checked"<?php } ?> data-on-click-this="click_AutoEmail"/>
|
||||||
</p>
|
</p>
|
||||||
|
<div id="EmailOptions"<?php echo $filter->AutoEmail() ? '' : ' style="display:none;"' ?>>
|
||||||
|
<p>
|
||||||
|
<label><?php echo translate('FilterEmailTo') ?></label>
|
||||||
|
<input type="email" name="filter[EmailTo]" value="<?php echo validHtmlStr($filter->EmailTo()) ?>" multiple/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><?php echo translate('FilterEmailSubject') ?></label>
|
||||||
|
<input type="text" name="filter[EmailSubject]" value="<?php echo validHtmlStr($filter->EmailSubject()) ?>"/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><?php echo translate('FilterEmailBody') ?></label>
|
||||||
|
<textarea name="filter[EmailBody]"><?php echo validHtmlStr($filter->EmailBody()) ?></textarea>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( ZM_OPT_MESSAGE ) {
|
if ( ZM_OPT_MESSAGE ) {
|
||||||
|
@ -409,7 +445,7 @@ if ( ZM_OPT_MESSAGE ) {
|
||||||
<hr/>
|
<hr/>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<button type="submit" data-on-click-this="submitToEvents"><?php echo translate('ListMatches') ?></button>
|
<button type="submit" data-on-click-this="submitToEvents"><?php echo translate('ListMatches') ?></button>
|
||||||
<!--<button type="submit" data-on-click-this="submitToMontageReview"><?php echo translate('ViewMatches') ?></button>-->
|
<button type="button" data-on-click-this="submitToMontageReview"><?php echo translate('ViewMatches') ?></button>
|
||||||
<button type="button" data-on-click-this="submitToExport"><?php echo translate('ExportMatches') ?></button>
|
<button type="button" data-on-click-this="submitToExport"><?php echo translate('ExportMatches') ?></button>
|
||||||
<button type="button" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button>
|
<button type="button" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -66,6 +66,15 @@ function updateButtons(element) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function click_AutoEmail(element) {
|
||||||
|
updateButtons(this);
|
||||||
|
if ( this.checked ) {
|
||||||
|
$j('#EmailOptions').show();
|
||||||
|
} else {
|
||||||
|
$j('#EmailOptions').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function click_automove(element) {
|
function click_automove(element) {
|
||||||
updateButtons(this);
|
updateButtons(this);
|
||||||
if ( this.checked ) {
|
if ( this.checked ) {
|
||||||
|
@ -105,10 +114,12 @@ function submitToEvents( element ) {
|
||||||
history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
|
history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitToMontageReview( element ) {
|
function submitToMontageReview(element) {
|
||||||
var form = element.form;
|
var form = element.form;
|
||||||
form.action = thisUrl + '?view=montagereview';
|
form.action = thisUrl + '?view=montagereview';
|
||||||
history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
|
console.log($j(form).serialize());
|
||||||
|
window.location.assign('?view=montagereview&'+$j(form).serialize());
|
||||||
|
history.replaceState(null, null, '?view=montagereview&live=0&' + $j(form).serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitToExport(element) {
|
function submitToExport(element) {
|
||||||
|
@ -183,7 +194,8 @@ function parseRows(rows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var attr = inputTds.eq(2).children().val();
|
var attr = inputTds.eq(2).children().val();
|
||||||
if ( attr == 'Archived' ) { // Archived types
|
|
||||||
|
if ( attr == 'Archived' ) { //Archived types
|
||||||
inputTds.eq(3).html('equal to<input type="hidden" name="filter[Query][terms][' + rowNum + '][op]" value="=">');
|
inputTds.eq(3).html('equal to<input type="hidden" name="filter[Query][terms][' + rowNum + '][op]" value="=">');
|
||||||
var archiveSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
var archiveSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||||
for (var i = 0; i < archiveTypes.length; i++) {
|
for (var i = 0; i < archiveTypes.length; i++) {
|
||||||
|
@ -191,6 +203,18 @@ function parseRows(rows) {
|
||||||
}
|
}
|
||||||
var archiveVal = inputTds.eq(4).children().val();
|
var archiveVal = inputTds.eq(4).children().val();
|
||||||
inputTds.eq(4).html(archiveSelect).children().val(archiveVal).chosen({width: "101%"});
|
inputTds.eq(4).html(archiveSelect).children().val(archiveVal).chosen({width: "101%"});
|
||||||
|
} else if ( attr == 'AlarmedZoneId' ) {
|
||||||
|
var zoneSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||||
|
for ( monitor_id in monitors ) {
|
||||||
|
for ( zone_id in zones ) {
|
||||||
|
var zone = zones[zone_id];
|
||||||
|
if ( monitor_id == zone.MonitorId ) {
|
||||||
|
zoneSelect.append('<option value="' + zone_id + '">' + zone.Name + '</option>');
|
||||||
|
}
|
||||||
|
} // end foreach zone
|
||||||
|
} // end foreach monitor
|
||||||
|
var zoneVal = inputTds.eq(4).children().val();
|
||||||
|
inputTds.eq(4).html(zoneSelect).children().val(zoneVal).chosen({width: "101%"});
|
||||||
} else if ( attr.indexOf('Weekday') >= 0 ) { //Weekday selection
|
} else if ( attr.indexOf('Weekday') >= 0 ) { //Weekday selection
|
||||||
var weekdaySelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
var weekdaySelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||||
for (var i = 0; i < weekdays.length; i++) {
|
for (var i = 0; i < weekdays.length; i++) {
|
||||||
|
@ -221,22 +245,29 @@ function parseRows(rows) {
|
||||||
inputTds.eq(4).html(storageSelect).children().val(storageVal).chosen({width: "101%"});
|
inputTds.eq(4).html(storageSelect).children().val(storageVal).chosen({width: "101%"});
|
||||||
} else if ( attr == 'MonitorName' ) { //Monitor names
|
} else if ( attr == 'MonitorName' ) { //Monitor names
|
||||||
var monitorSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
var monitorSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||||
for (var key in monitors) {
|
for ( var monitor_id in monitors ) {
|
||||||
monitorSelect.append('<option value="' + key + '">' + monitors[key] + '</option>');
|
monitorSelect.append('<option value="' + monitors[monitor_id].Name + '">' + monitors[monitor_id].Name + '</option>');
|
||||||
}
|
}
|
||||||
var monitorVal = inputTds.eq(4).children().val();
|
var monitorVal = inputTds.eq(4).children().val();
|
||||||
inputTds.eq(4).html(monitorSelect).children().val(monitorVal);
|
inputTds.eq(4).html(monitorSelect).children().val(monitorVal);
|
||||||
} else { //Reset to regular text field and operator for everything that isn't special
|
} else { // Reset to regular text field and operator for everything that isn't special
|
||||||
var opSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][op]').attr('id', queryPrefix + rowNum + '][op]');
|
|
||||||
for (var key in opTypes) {
|
|
||||||
opSelect.append('<option value="' + key + '">' + opTypes[key] + '</option>');
|
|
||||||
}
|
|
||||||
var opVal = inputTds.eq(3).children().val();
|
|
||||||
inputTds.eq(3).html(opSelect).children().val(opVal).chosen({width: "101%"});
|
|
||||||
var textInput = $j('<input></input>').attr('type', 'text').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
var textInput = $j('<input></input>').attr('type', 'text').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||||
var textVal = inputTds.eq(4).children().val();
|
var textVal = inputTds.eq(4).children().val();
|
||||||
inputTds.eq(4).html(textInput).children().val(textVal);
|
inputTds.eq(4).html(textInput).children().val(textVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the operator
|
||||||
|
var opSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][op]').attr('id', queryPrefix + rowNum + '][op]');
|
||||||
|
var opVal = inputTds.eq(3).children().val();
|
||||||
|
if ( ! opVal ) {
|
||||||
|
// Default to equals so that something gets selected
|
||||||
|
console.log("No value for operator. Defaulting to =");
|
||||||
|
opVal = '=';
|
||||||
|
}
|
||||||
|
for ( var key in opTypes ) {
|
||||||
|
opSelect.append('<option value="' + key + '"'+(key == opVal ? ' selected="selected"' : '')+'>' + opTypes[key] + '</option>');
|
||||||
|
}
|
||||||
|
inputTds.eq(3).html(opSelect).children().val(opVal).chosen({width: "101%"});
|
||||||
if ( attr.endsWith('DateTime') ) { //Start/End DateTime
|
if ( attr.endsWith('DateTime') ) { //Start/End DateTime
|
||||||
inputTds.eq(4).children().datetimepicker({timeFormat: "HH:mm:ss", dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false});
|
inputTds.eq(4).children().datetimepicker({timeFormat: "HH:mm:ss", dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false});
|
||||||
} else if ( attr.endsWith('Date') ) { //Start/End Date
|
} else if ( attr.endsWith('Date') ) { //Start/End Date
|
||||||
|
|
|
@ -10,6 +10,7 @@ var states = <?php echo isset($states) ? json_encode($states) : '' ?>;
|
||||||
var servers = <?php echo isset($servers) ? json_encode($servers) : '' ?>;
|
var servers = <?php echo isset($servers) ? json_encode($servers) : '' ?>;
|
||||||
var storageareas = <?php echo isset($storageareas) ? json_encode($storageareas) : '' ?>;
|
var storageareas = <?php echo isset($storageareas) ? json_encode($storageareas) : '' ?>;
|
||||||
var monitors = <?php echo isset($monitors) ? json_encode($monitors) : '' ?>;
|
var monitors = <?php echo isset($monitors) ? json_encode($monitors) : '' ?>;
|
||||||
|
var zones = <?php echo isset($zones) ? json_encode($zones) : '' ?>;
|
||||||
|
|
||||||
var errorBrackets = '<?php echo translate('ErrorBrackets') ?>';
|
var errorBrackets = '<?php echo translate('ErrorBrackets') ?>';
|
||||||
var errorValue = '<?php echo translate('ErrorValidValue') ?>';
|
var errorValue = '<?php echo translate('ErrorValidValue') ?>';
|
||||||
|
|
|
@ -464,6 +464,7 @@ function initPage() {
|
||||||
|
|
||||||
// Start the fps and status updates. give a random delay so that we don't assault the server
|
// Start the fps and status updates. give a random delay so that we don't assault the server
|
||||||
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
||||||
|
console.log("delay: " + delay);
|
||||||
monitors[i].start(delay);
|
monitors[i].start(delay);
|
||||||
|
|
||||||
var interval = monitors[i].refresh;
|
var interval = monitors[i].refresh;
|
||||||
|
|
|
@ -62,6 +62,17 @@ ob_end_clean();
|
||||||
$filter = array();
|
$filter = array();
|
||||||
if ( isset($_REQUEST['filter']) ) {
|
if ( isset($_REQUEST['filter']) ) {
|
||||||
$filter = $_REQUEST['filter'];
|
$filter = $_REQUEST['filter'];
|
||||||
|
|
||||||
|
# Try to guess min/max time from filter
|
||||||
|
foreach ( $filter['Query'] as $term ) {
|
||||||
|
if ( $term['attr'] == 'StartDateTime' ) {
|
||||||
|
if ( $term['op'] == '<=' or $term['op'] == '<' ) {
|
||||||
|
$maxTime = $term['val'];
|
||||||
|
} else if ( $term['op'] == '>=' or $term['op'] == '>' ) {
|
||||||
|
$minTime = $term['val'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && (count($displayMonitors) != 0) ) {
|
if ( isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && (count($displayMonitors) != 0) ) {
|
||||||
|
|
Loading…
Reference in New Issue