diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/HikVision.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/HikVision.pm index 8fabcdf2f..04aaabb23 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/HikVision.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/HikVision.pm @@ -55,134 +55,131 @@ my $DefaultFocusSpeed = 50; # Should be between 1 and 100 my $DefaultIrisSpeed = 50; # Should be between 1 and 100 sub open { - my $self = shift; - $self->loadMonitor(); - # - # Create a UserAgent for the requests - # - $self->{UA} = LWP::UserAgent->new(); - $self->{UA}->cookie_jar( {} ); - # - # Extract the username/password host/port from ControlAddress - # - my ($user,$pass,$host,$port); - if( $self->{Monitor}{ControlAddress} =~ /^([^:]+):([^@]+)@(.+)/ ) { # user:pass@host... - $user = $1; - $pass = $2; - $host = $3; - } - elsif( $self->{Monitor}{ControlAddress} =~ /^([^@]+)@(.+)/ ) { # user@host... - $user = $1; - $host = $2; - } - else { # Just a host - $host = $self->{Monitor}{ControlAddress}; - } - # Check if it is a host and port or just a host - if( $host =~ /([^:]+):(.+)/ ) { - $host = $1; - $port = $2; - } - else { - $port = 80; - } - # Save the credentials - if( defined($user) ) { - $self->{UA}->credentials( "$host:$port", $self->{Monitor}{ControlDevice}, $user, $pass ); - } - # Save the base url - $self->{BaseURL} = "http://$host:$port"; + my $self = shift; + $self->loadMonitor(); + # + # Create a UserAgent for the requests + # + $self->{UA} = LWP::UserAgent->new(); + $self->{UA}->cookie_jar( {} ); + # + # Extract the username/password host/port from ControlAddress + # + my ($user,$pass,$host,$port); + if ( $self->{Monitor}{ControlAddress} =~ /^([^:]+):([^@]+)@(.+)/ ) { # user:pass@host... + $user = $1; + $pass = $2; + $host = $3; + } elsif ( $self->{Monitor}{ControlAddress} =~ /^([^@]+)@(.+)/ ) { # user@host... + $user = $1; + $host = $2; + } else { # Just a host + $host = $self->{Monitor}{ControlAddress}; + } + # Check if it is a host and port or just a host + if ( $host =~ /([^:]+):(.+)/ ) { + $host = $1; + $port = $2; + } else { + $port = 80; + } + # Save the credentials + if ( defined($user) ) { + $self->{UA}->credentials("$host:$port", $self->{Monitor}{ControlDevice}, $user, $pass); + } + # Save the base url + $self->{BaseURL} = "http://$host:$port"; } + sub PutCmd { - my $self = shift; - my $cmd = shift; - my $content = shift; - my $req = HTTP::Request->new(PUT => "$self->{BaseURL}/$cmd"); - if(defined($content)) { - $req->content_type("application/x-www-form-urlencoded; charset=UTF-8"); - $req->content('' . "\n" . $content); - } - my $res = $self->{UA}->request($req); - unless( $res->is_success ) { - # - # The camera timeouts connections at short intervals. When this - # happens the user agent connects again and uses the same auth tokens. - # The camera rejects this and asks for another token but the UserAgent - # just gives up. Because of this I try the request again and it should - # succeed the second time if the credentials are correct. - # - if($res->code == 401) { - $res = $self->{UA}->request($req); - unless( $res->is_success ) { - # - # It has failed authentication. The odds are - # that the user has set some paramater incorrectly - # so check the realm against the ControlDevice - # entry and send a message if different - # - my $auth = $res->headers->www_authenticate; - foreach (split(/\s*,\s*/,$auth)) { - if( $_ =~ /^realm\s*=\s*"([^"]+)"/i ) { - if( $self->{Monitor}{ControlDevice} ne $1 ) { - Info "Control Device appears to be incorrect."; - Info "Control Device should be set to \"$1\"."; - Info "Control Device currently set to \"$self->{Monitor}{ControlDevice}\"."; - } + my $self = shift; + my $cmd = shift; + my $content = shift; + my $req = HTTP::Request->new(PUT => "$self->{BaseURL}/$cmd"); + if ( defined($content) ) { + $req->content_type("application/x-www-form-urlencoded; charset=UTF-8"); + $req->content('' . "\n" . $content); + } + my $res = $self->{UA}->request($req); + unless( $res->is_success ) { + # + # The camera timeouts connections at short intervals. When this + # happens the user agent connects again and uses the same auth tokens. + # The camera rejects this and asks for another token but the UserAgent + # just gives up. Because of this I try the request again and it should + # succeed the second time if the credentials are correct. + # + if ( $res->code == 401 ) { + $res = $self->{UA}->request($req); + unless( $res->is_success ) { + # + # It has failed authentication. The odds are + # that the user has set some parameter incorrectly + # so check the realm against the ControlDevice + # entry and send a message if different + # + my $auth = $res->headers->www_authenticate; + foreach (split(/\s*,\s*/,$auth)) { + if ( $_ =~ /^realm\s*=\s*"([^"]+)"/i ) { + if ( $self->{Monitor}{ControlDevice} ne $1 ) { + Warning("Control Device appears to be incorrect. + Control Device should be set to \"$1\". + Control Device currently set to \"$self->{Monitor}{ControlDevice}\"."); } } - # - # Check for username/password - # - if( $self->{Monitor}{ControlAddress} =~ /.+:(.+)@.+/ ) { - Info "Check username/password is correct"; - } elsif ( $self->{Monitor}{ControlAddress} =~ /^[^:]+@.+/ ) { - Info "No password in Control Address. Should there be one?"; - } elsif ( $self->{Monitor}{ControlAddress} =~ /^:.+@.+/ ) { - Info "Password but no username in Control Address."; - } else { - Info "Missing username and password in Control Address."; - } - Fatal $res->status_line; } + # + # Check for username/password + # + if ( $self->{Monitor}{ControlAddress} =~ /.+:(.+)@.+/ ) { + Info("Check username/password is correct"); + } elsif ( $self->{Monitor}{ControlAddress} =~ /^[^:]+@.+/ ) { + Info("No password in Control Address. Should there be one?"); + } elsif ( $self->{Monitor}{ControlAddress} =~ /^:.+@.+/ ) { + Info("Password but no username in Control Address."); + } else { + Info("Missing username and password in Control Address."); + } + Fatal($res->status_line); } - else { - Fatal $res->status_line; - } + } else { + Fatal($res->status_line); } -} + } # end unless res->is_success +} # end sub putCmd # # The move continuous functions all call moveVector # with the direction to move in. This includes zoom # sub moveVector { - my $self = shift; - my $pandirection = shift; - my $tiltdirection = shift; - my $zoomdirection = shift; - my $params = shift; - my $command; # The ISAPI/PTZ command + my $self = shift; + my $pandirection = shift; + my $tiltdirection = shift; + my $zoomdirection = shift; + my $params = shift; + my $command; # The ISAPI/PTZ command - # Calculate autostop time - my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; - # Change from microseconds to milliseconds - $duration = int($duration/1000); - my $momentxml; - if( $duration ) { - $momentxml = "$duration"; - $command = "ISAPI/PTZCtrl/channels/$ChannelID/momentary"; - } - else { - $momentxml = ""; - $command = "ISAPI/PTZCtrl/channels/$ChannelID/continuous"; - } - # Calculate movement speeds - my $x = $pandirection * $self->getParam( $params, 'panspeed', 0 ); - my $y = $tiltdirection * $self->getParam( $params, 'tiltspeed', 0 ); - my $z = $zoomdirection * $self->getParam( $params, 'speed', 0 ); - # Create the XML - my $xml = "$x$y$z$momentxml"; - # Send it to the camera - $self->PutCmd($command,$xml); + # Calculate autostop time + my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; + # Change from microseconds to milliseconds + $duration = int($duration/1000); + my $momentxml; + if( $duration ) { + $momentxml = "$duration"; + $command = "ISAPI/PTZCtrl/channels/$ChannelID/momentary"; + } + else { + $momentxml = ""; + $command = "ISAPI/PTZCtrl/channels/$ChannelID/continuous"; + } + # Calculate movement speeds + my $x = $pandirection * $self->getParam( $params, 'panspeed', 0 ); + my $y = $tiltdirection * $self->getParam( $params, 'tiltspeed', 0 ); + my $z = $zoomdirection * $self->getParam( $params, 'speed', 0 ); + # Create the XML + my $xml = "$x$y$z$momentxml"; + # Send it to the camera + $self->PutCmd($command,$xml); } sub moveStop { $_[0]->moveVector( 0, 0, 0, splice(@_,1)); } sub moveConUp { $_[0]->moveVector( 0, 1, 0, splice(@_,1)); } @@ -199,191 +196,191 @@ sub zoomConWide { $_[0]->moveVector( 0, 0,-1, splice(@_,1)); } # Presets including Home set and clear # sub presetGoto { - my $self = shift; - my $params = shift; - my $preset = $self->getParam($params,'preset'); - $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/presets/$preset/goto"); + my $self = shift; + my $params = shift; + my $preset = $self->getParam($params,'preset'); + $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/presets/$preset/goto"); } sub presetSet { - my $self = shift; - my $params = shift; - my $preset = $self->getParam($params,'preset'); - my $xml = "$preset"; - $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/presets/$preset",$xml); + my $self = shift; + my $params = shift; + my $preset = $self->getParam($params,'preset'); + my $xml = "$preset"; + $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/presets/$preset",$xml); } sub presetHome { - my $self = shift; - my $params = shift; - $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/homeposition/goto"); + my $self = shift; + my $params = shift; + $self->PutCmd("ISAPI/PTZCtrl/channels/$ChannelID/homeposition/goto"); } # # Focus controls all call Focus with a +/- speed # sub Focus { - my $self = shift; - my $speed = shift; - my $xml = "$speed"; - $self->PutCmd("ISAPI/System/Video/inputs/channels/$ChannelID/focus",$xml); + my $self = shift; + my $speed = shift; + my $xml = "$speed"; + $self->PutCmd("ISAPI/System/Video/inputs/channels/$ChannelID/focus",$xml); } sub focusConNear { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Calculate autostop time - my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus(-$speed); - if($duration) { - usleep($duration); - $self->moveStop($params); - } + # Calculate autostop time + my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus(-$speed); + if($duration) { + usleep($duration); + $self->moveStop($params); + } } sub Near { - my $self = shift; - my $params = shift; - $self->Focus(-$DefaultFocusSpeed); + my $self = shift; + my $params = shift; + $self->Focus(-$DefaultFocusSpeed); } sub focusAbsNear { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus(-$speed); + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus(-$speed); } sub focusRelNear { - my $self = shift; - my $params = shift; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus(-$speed); + my $self = shift; + my $params = shift; + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus(-$speed); } sub focusConFar { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Calculate autostop time - my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus($speed); - if($duration) { - usleep($duration); - $self->moveStop($params); - } + # Calculate autostop time + my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus($speed); + if($duration) { + usleep($duration); + $self->moveStop($params); + } } sub Far { - my $self = shift; - my $params = shift; - $self->Focus($DefaultFocusSpeed); + my $self = shift; + my $params = shift; + $self->Focus($DefaultFocusSpeed); } sub focusAbsFar { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus($speed); + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus($speed); } sub focusRelFar { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the focus speed - my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); - $self->Focus($speed); + # Get the focus speed + my $speed = $self->getParam( $params, 'speed', $DefaultFocusSpeed ); + $self->Focus($speed); } # # Iris controls all call Iris with a +/- speed # sub Iris { - my $self = shift; - my $speed = shift; + my $self = shift; + my $speed = shift; - my $xml = "$speed"; - $self->PutCmd("ISAPI/System/Video/inputs/channels/$ChannelID/iris",$xml); + my $xml = "$speed"; + $self->PutCmd("ISAPI/System/Video/inputs/channels/$ChannelID/iris",$xml); } sub irisConClose { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Calculate autostop time - my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris(-$speed); - if($duration) { - usleep($duration); - $self->moveStop($params); - } + # Calculate autostop time + my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris(-$speed); + if($duration) { + usleep($duration); + $self->moveStop($params); + } } sub Close { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - $self->Iris(-$DefaultIrisSpeed); + $self->Iris(-$DefaultIrisSpeed); } sub irisAbsClose { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris(-$speed); + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris(-$speed); } sub irisRelClose { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris(-$speed); + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris(-$speed); } sub irisConOpen { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Calculate autostop time - my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris($speed); - if($duration) { - usleep($duration); - $self->moveStop($params); - } + # Calculate autostop time + my $duration = $self->getParam( $params, 'autostop', 0 ) * $self->{Monitor}{AutoStopTimeout}; + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris($speed); + if($duration) { + usleep($duration); + $self->moveStop($params); + } } sub Open { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - $self->Iris($DefaultIrisSpeed); + $self->Iris($DefaultIrisSpeed); } sub irisAbsOpen { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris($speed); + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris($speed); } sub irisRelOpen { - my $self = shift; - my $params = shift; + my $self = shift; + my $params = shift; - # Get the iris speed - my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); - $self->Iris($speed); + # Get the iris speed + my $speed = $self->getParam( $params, 'speed', $DefaultIrisSpeed ); + $self->Iris($speed); } # # reset (reboot) the device # sub reset { - my $self = shift; + my $self = shift; - $self->PutCmd("ISAPI/System/reboot"); + $self->PutCmd("ISAPI/System/reboot"); } 1; - +__END__ diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 098a7b7e7..eaa717273 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -302,7 +302,7 @@ sub run { if ( ! ( $secs_count % 60 ) ) { Debug("Connecting"); while ( (!$zm_terminate) and !($dbh and $dbh->ping()) ) { - Warning("Not connected to db ($dbh). Reconnecting"); + Warning("Not connected to db ($dbh) ping(".$dbh->ping().". Reconnecting"); $dbh = zmDbConnect(); } my @cpuload = CpuLoad(); diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 3f6b0a807..346ba6549 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -69,7 +69,7 @@ Event::Event( untimedEvent = true; start_time = now; } else if ( start_time.tv_sec > now.tv_sec ) { - Error("StartTime in the future %d.%d > $d.%d", + Error("StartTime in the future %d.%d > %d.%d", start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec ); start_time = now; diff --git a/web/skins/classic/css/dark/views/watch.css b/web/skins/classic/css/dark/views/watch.css index 4ebb30dda..a8adf124c 100644 --- a/web/skins/classic/css/dark/views/watch.css +++ b/web/skins/classic/css/dark/views/watch.css @@ -1,49 +1,3 @@ -#header { - display: flex; - justify-content: space-between; -} - -#menuControls { - display: flex; - align-items: center; -} - -#menuControls div { - margin: 0 0 0 1em; -} - -#imageFeed{ - text-align: center; -} - -#monitorStatus { - margin: 4px auto; - text-align: center; -} - -#monitorStatus #enableDisableAlarms { - float: left; -} - -#monitorStatus #forceCancelAlarm { - float: right; -} - -#monitorStatus #monitorState { -} - -#dvrControls { - margin-top: 3px; - margin-bottom: 2px; - text-align: center; -} - -#dvrControls input { - height: 20px; - width: 28px; - padding-bottom: 3px; - margin: 0 3px; -} #dvrControls input[disabled] { color: #aaaaaa; @@ -61,45 +15,12 @@ border: 1px solid red; } -#replayStatus { - margin: 3px 0 2px; - text-align: center; - clear: both; -} - -#replayStatus > span { - padding: 0 4px; -} - -#events { - margin: 0 auto; -} - -#eventList { - width: 100%; -} - -#eventList thead td { - font-weight: bold; -} - -#eventList th, #eventList td { - text-align: center; -} - -li { - display: inline; - list-style-type: none; -} - span.alarm { color: #DC143C; - font-weight: bold; } span.alert { color: #FF8C00; - font-weight: bold; } #eventList tr.recent {