diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 7a87f2403..fe6bc3e98 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -893,7 +893,7 @@ INSERT INTO Controls VALUES (NULL,'Loftek Sentinel','Remote','LoftekSentinel',0, INSERT INTO Controls VALUES (NULL,'Toshiba IK-WB11A','Remote','Toshiba_IK_WB11A',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,1,10,0,1,1,0,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,'WanscamPT','Remote','Wanscam',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,1,0,1,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,16,0,0,0,0,0,1,16,1,1,1,1,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,'3S Domo N5071', 'Remote', '3S', 0, 0, 1, 0,1, 0, 1, 1, 0, 0, 9999, 0, 9999, 0, 0, 0, 1, 1, 1, 1, 0, 0, 9999, 20, 9999, 0, 0, 0, 1, 1, 1, 1, 0, 0, 9999, 1, 9999, 0, 0, 0, 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, 64, 1, 0, 1, 1, 0, 0, 0, 0, 1, -180, 180, 40, 100, 1, 40, 100, 0, 0, 1, -180, 180, 40, 100, 1, 40, 100, 0, 0, 0, 0); -INSERT INTO Controls VALUES (NULL,'ONVIF Camera','Ffmpeg','onvif',0,0,1,0,1,0,0,0,1,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,255,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,6,1,1,0,0,0,1,10,0,1,1,1,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,'ONVIF Camera','Ffmpeg','onvif',0,0,1,1,1,0,0,0,1,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,255,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,6,1,1,0,0,0,1,10,1,1,1,1,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,'Foscam 9831W','Ffmpeg','FI9831W',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,1,16,1,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,0,0,0,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',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,1,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/onvif.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/onvif.pm index 8c1f2114e..4ae2ba1fc 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/onvif.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/onvif.pm @@ -1,7 +1,7 @@ # ========================================================================== # -# ZoneMinder ONVIF Control Protocol Module -# Copyright (C) Jan M. Hochstein +# ZoneMinder ONVIF Control Protocol Module, $Date: 2021-02-25 22:07:00 +0000 (Thu, 25 Feb 2021) $, $Revision: 0001 $ +# Based on the Netcat onvif script by Andrew Bauer (knnniggett@users.sourceforge.net) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,28 +19,55 @@ # # ========================================================================== # -# This module contains the implementation of the ONVIF device control protocol +# This module contains the implementation of onvif protocol # package ZoneMinder::Control::onvif; use 5.006; use strict; use warnings; +use MIME::Base64; +use Digest::SHA; +use DateTime; +use URI; +use Data::Dumper; +require ZoneMinder::Base; require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); our %CamParams = (); +our ($profileToken, $address, $port, %identity); +my ( $controlUri, $scheme ); + # ========================================================================== # -# ONVIF Control Protocol +# This script sends ONVIF compliant commands and may work with other cameras # -# On ControlAddress use the format : -# USERNAME:PASSWORD@ADDRESS:PORT -# eg : admin:@10.1.2.1:80 -# zoneminder:zonepass@10.0.100.1:40000 +# Configuration options (Source->Control tab) +# - Control Type: ONVIF +# - Control Device: prof0 - this is dependant on camera. It maybe required to sniff the traffic using Wireshark to find this out. If left empty value of "000" will be used. +# - Control Address: ://[:@][:port][control_uri] +# - Auto Stop Timeout: 1.00 - how long shold the camera move for when move command is issued. Value of 1.00 means 1s. +# - Track Motion: NOT IMPLEMENTED - this suppose to be a feature for automatic camera scrolling (moving). +# - Track Delay: NOT IMPLEMENTED +# - Return Location: Home|Preset 1 - NOT IMPLEMENTED +# +# Absolute minimum required supported "Control Address" would be: +# - 192.168.1.199 +# This will use the following defaults: +# - port: 80 +# - Control Device: 000 +# - Control URI: /onvif/device_control +# - No authentication +# - No Auto Stop Timeout (on movement command the camera will keep moving until it reaches it's edge) +# +# Example Control Address values: +# - http://user:password@192.168.1.199:888/onvif/device_control :Connect to camera at IP: 192.168.1.199 on port 888 with "username" and "password" credentials using /onvif/device_control URI +# - user:password@192.168.1.199 :Connect to camera at IP: 192.168.1.199 on default port 80 with "username" and "password" credentials using default /onvif/device_control URI +# - 192.168.1.199 :Connect to camera at IP: 192.168.1.199 without any authentication and use the default /onvif/device_control URI over HTTP. # # ========================================================================== @@ -54,6 +81,11 @@ sub open { $self->loadMonitor(); + $profileToken = $self->{Monitor}->{ControlDevice}; + if ($profileToken eq '') { $profileToken = '000'; } + + parseControlAddress($self->{Monitor}->{ControlAddress}); + use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; $self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION); @@ -61,39 +93,140 @@ sub open { $self->{state} = 'open'; } +sub parseControlAddress { + + my $controlAddress = shift; + + #make sure url start with a scheme + if ( $controlAddress !~ m'^https?://') { + $scheme = "http"; + $controlAddress = $scheme."://".$controlAddress; + } + + my $url = URI->new($controlAddress); + + #set the scheme + $scheme = $url->scheme; + + #If we have authinfo + if ($url->userinfo){ + my ($username , $password) = split /:/, $url->userinfo; + %identity = (username => $username, password => $password); + } + + #If we have no explicitly defined port + if (!$url->port){ + $port = $url->default_port; + } else { + $port = $url->port; + } + + if (!$url->path){ + $controlUri = "/onvif/device_control"; + } else { + $controlUri = $url->path; + } + + $address = $url->host; +} + +sub digestBase64 { + my ($nonce, $date, $password) = @_; + my $shaGenerator = Digest::SHA->new(1); + $shaGenerator->add($nonce . $date . $password); + return encode_base64($shaGenerator->digest, ''); +} + +sub authentificationHeader { + my ($username, $password) = @_; + my @set = ('0' ..'9', 'A' .. 'Z', 'a' .. 'z'); + my $nonce = join '' => map $set[rand @set], 1 .. 20; + + my $nonceBase64 = encode_base64($nonce, ''); + my $currentDate = DateTime->now()->iso8601().'Z'; + + return ' + + + + ' . $username . ' + ' . digestBase64($nonce, $currentDate, $password) . ' + ' . $nonceBase64 . ' + ' . $currentDate . ' + + +'; +} + sub sendCmd { my $self = shift; my $cmd = shift; + my $msg_body = shift; + my $content_type = shift; my $result = undef; + + my $msg = ' + '. + ((%identity) ? authentificationHeader($identity{username}, $identity{password}) : '') . + $msg_body . ' + '; + $self->printMsg($cmd, 'Tx'); - my $req = HTTP::Request->new(GET=>'http://'.$self->{Monitor}->{ControlAddress}.'/'.$cmd); + my $server_endpoint = $scheme.'://'.$address.':'.$port.$controlUri; + my $req = HTTP::Request->new(POST => $server_endpoint); + $req->header('content-type' => $content_type); + $req->header('Host' => $address . ':' . $port); + $req->header('content-length' => length($msg)); + $req->header('accept-encoding' => 'gzip, deflate'); + $req->header('connection' => 'Close'); + $req->content($msg); + my $res = $self->{ua}->request($req); if ( $res->is_success ) { $result = !undef; } else { - Error("Error check failed:'".$res->status_line()."'" ); + Error("After sending PTZ command, camera returned the following error:'".$res->status_line()."'\nMSG:$msg\nResponse:".$res->content); } - return $result; } sub getCamParams { my $self = shift; + my $msg = ' + + + + 000 + + + '; + + my $server_endpoint = $scheme.'://'.$address.':'.$port.'/onvif/imaging'; + + my $req = HTTP::Request->new(POST => $server_endpoint); + $req->header('content-type' => 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/GetImagingSettings"'); + $req->header('Host' => $address . ':' . $port); + $req->header('content-length' => length($msg)); + $req->header('accept-encoding' => 'gzip, deflate'); + $req->header('connection' => 'Close'); + $req->content($msg); - my $req = HTTP::Request->new(GET=>'http://'.$self->{Monitor}->{ControlAddress}.'/get_camera_params.cgi'); my $res = $self->{ua}->request($req); if ( $res->is_success ) { - # Parse results setting values in %FCParams + # We should really use an xml or soap library to parse the xml tags my $content = $res->decoded_content; - while ($content =~ s/var\s+([^=]+)=([^;]+);//ms) { + if ( $content =~ /.*(.+)<\/tt:Brightness>.*/ ) { + $CamParams{$1} = $2; + } + if ( $content =~ /.*(.+)<\/tt:Contrast>.*/ ) { $CamParams{$1} = $2; } } else { - Error("Error check failed:'".$res->status_line()."'"); + Error("Unable to retrieve camera image settings:'".$res->status_line()."'"); } } @@ -101,256 +234,418 @@ sub getCamParams { #This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab sub autoStop { my $self = shift; - my $stop_command = shift; my $autostop = shift; - if ( $stop_command && $autostop ) { + + if ( $autostop ) { Debug('Auto Stop'); + my $cmd = $controlUri; + my $msg_body = ' + + + '.$profileToken.' + + true + + + false + + + '; + + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; usleep($autostop); - my $cmd = 'decoder_control.cgi?command='.$stop_command; - $self->sendCmd($cmd); + $self->sendCmd($cmd, $msg_body, $content_type); } } -# Reset the Camera -sub reset { +# Reboot +sub reboot { + Debug('Camera reboot'); my $self = shift; + my $cmd = ''; + my $msg_body = << "END_MESSAGE"; + + + +END_MESSAGE + + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/SystemReboot"'; + $self->sendCmd($cmd, $msg_body, $content_type); + +} + +# Reset(Reboot) the Camera +sub reset { Debug('Camera Reset'); - my $cmd = 'reboot.cgi?'; - $self->sendCmd($cmd); + my $self = shift; + my $cmd = ''; + my $msg_body = << "END_MESSAGE"; + + + +END_MESSAGE + + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/SystemReboot"'; + $self->sendCmd($cmd, $msg_body, $content_type); +} + + +sub moveCamera { + + my $type = shift; + my $x = shift; + my $y = shift; + my $msg_move_body = ""; + + if ( $type == "move" ){ + $msg_move_body = ' + + + '.$profileToken.' + + + + + '; + + } elsif ( $type == "zoom" ) { + $msg_move_body = ' + + + '.$profileToken.' + + + + + '; + } + + return $msg_move_body; + } #Up Arrow -sub moveConUp -{ +sub moveConUp { + Debug('Move Up'); my $self = shift; - my $stop_command = "1"; - Debug( "Move Up" ); - my $cmd = "decoder_control.cgi?command=0"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move", "0","0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } + #Down Arrow -sub moveConDown -{ +sub moveConDown { + Debug('Move Down'); my $self = shift; - my $stop_command = "3"; - Debug( "Move Down" ); - my $cmd = "decoder_control.cgi?command=2"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","0","-0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Left Arrow -sub moveConLeft -{ +sub moveConLeft { + Debug('Move Left'); my $self = shift; - my $stop_command = "5"; - Debug( "Move Left" ); - my $cmd = "decoder_control.cgi?command=4"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","-0.49","0"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Right Arrow -sub moveConRight -{ +sub moveConRight { + Debug('Move Right'); my $self = shift; - my $stop_command = "7"; - Debug( "Move Right" ); - my $cmd = "decoder_control.cgi?command=6"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","0.49","0"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Zoom In -sub zoomConTele -{ +sub zoomConTele { + Debug('Zoom Tele'); my $self = shift; - my $stop_command = "17"; - Debug( "Zoom Tele" ); - my $cmd = "decoder_control.cgi?command=18"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("zoom","0.49","0"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Zoom Out -sub zoomConWide -{ +sub zoomConWide { + Debug('Zoom Wide'); my $self = shift; - my $stop_command = "19"; - Debug( "Zoom Wide" ); - my $cmd = "decoder_control.cgi?command=16"; - $self->sendCmd( $cmd ); - $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); + my $cmd = $controlUri; + my $msg_body = moveCamera("zoom","-0.49","0"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Diagonally Up Right Arrow #This camera does not have builtin diagonal commands so we emulate them -sub moveConUpRight -{ +sub moveConUpRight { + Debug('Move Diagonally Up Right'); my $self = shift; - Debug( "Move Diagonally Up Right" ); - $self->moveConUp( ); - $self->moveConRight( ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","0.5","0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Diagonally Down Right Arrow #This camera does not have builtin diagonal commands so we emulate them -sub moveConDownRight -{ +sub moveConDownRight { + Debug('Move Diagonally Down Right'); my $self = shift; - Debug( "Move Diagonally Down Right" ); - $self->moveConDown( ); - $self->moveConRight( ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","0.5","-0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Diagonally Up Left Arrow #This camera does not have builtin diagonal commands so we emulate them -sub moveConUpLeft -{ +sub moveConUpLeft { + Debug('Move Diagonally Up Left'); my $self = shift; - Debug( "Move Diagonally Up Left" ); - $self->moveConUp( ); - $self->moveConLeft( ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","-0.5","0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Diagonally Down Left Arrow #This camera does not have builtin diagonal commands so we emulate them -sub moveConDownLeft -{ +sub moveConDownLeft { + Debug('Move Diagonally Down Left'); my $self = shift; - Debug( "Move Diagonally Down Left" ); - $self->moveConDown( ); - $self->moveConLeft( ); + my $cmd = $controlUri; + my $msg_body = moveCamera("move","-0.5","-0.5"); + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); + $self->autoStop($self->{Monitor}->{AutoStopTimeout}); } #Stop -sub moveStop -{ +sub moveStop { + Debug('Move Stop'); my $self = shift; - Debug( "Move Stop" ); - my $cmd = "decoder_control.cgi?command=1"; - $self->sendCmd( $cmd ); + my $cmd = $controlUri; + my $msg_body = ' + + + '.$profileToken.' + true + false + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"'; + $self->sendCmd($cmd, $msg_body, $content_type); } #Set Camera Preset -#Presets must be translated into values internal to the camera -#Those values are: 30,32,34,36,38,40,42,44 for presets 1-8 respectively -sub presetSet -{ +sub presetSet { my $self = shift; my $params = shift; - my $preset = $self->getParam( $params, 'preset' ); - Debug( "Set Preset $preset" ); - - if (( $preset >= 1 ) && ( $preset <= 8 )) { - my $cmd = "decoder_control.cgi?command=".(($preset*2) + 28); - $self->sendCmd( $cmd ); - } + my $preset = $self->getParam($params, 'preset'); + Debug("Set Preset $preset"); + my $cmd = $controlUri; + my $msg_body =' + + + ' . $profileToken . ' + '.$preset.' + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/SetPreset"'; + $self->sendCmd($cmd, $msg_body, $content_type); } #Recall Camera Preset -#Presets must be translated into values internal to the camera -#Those values are: 31,33,35,37,39,41,43,45 for presets 1-8 respectively -sub presetGoto -{ +sub presetGoto { my $self = shift; my $params = shift; - my $preset = $self->getParam( $params, 'preset' ); - Debug( "Goto Preset $preset" ); + my $preset = $self->getParam($params, 'preset'); - if (( $preset >= 1 ) && ( $preset <= 8 )) { - my $cmd = "decoder_control.cgi?command=".(($preset*2) + 29); - $self->sendCmd( $cmd ); - } - - if ( $preset == 9 ) { - $self->horizontalPatrol(); - } - - if ( $preset == 10 ) { - $self->horizontalPatrolStop(); - } + Debug("Goto Preset $preset"); + my $cmd = $controlUri; + my $msg_body =' + + + ' . $profileToken . ' + '.$preset.' + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/GotoPreset"'; + $self->sendCmd( $cmd, $msg_body, $content_type ); } -#Horizontal Patrol - Vertical Patrols are not supported -sub horizontalPatrol -{ +#Recall Camera Preset +sub presetHome { my $self = shift; - Debug( "Horizontal Patrol" ); - my $cmd = "decoder_control.cgi?command=20"; - $self->sendCmd( $cmd ); + my $params = shift; + + Debug("Goto Home preset"); + my $cmd = $controlUri; + my $msg_body =' + + + ' . $profileToken . ' + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/GotoPreset"'; + $self->sendCmd( $cmd, $msg_body, $content_type ); +} + +#Horizontal Patrol +#To be determined if this camera supports this feature +sub horizontalPatrol { + Debug('Horizontal Patrol'); + my $self = shift; + my $cmd = ''; + my $msg =''; + my $content_type = ''; + # $self->sendCmd( $cmd, $msg, $content_type ); + Error('PTZ Command not implemented in control script.'); } #Horizontal Patrol Stop -sub horizontalPatrolStop -{ +#To be determined if this camera supports this feature +sub horizontalPatrolStop { + Debug('Horizontal Patrol Stop'); my $self = shift; - Debug( "Horizontal Patrol Stop" ); - my $cmd = "decoder_control.cgi?command=21"; - $self->sendCmd( $cmd ); + my $cmd = ''; + my $msg =''; + my $content_type = ''; + # $self->sendCmd( $cmd, $msg, $content_type ); + Error('PTZ Command not implemented in control script.'); } # Increase Brightness -sub irisAbsOpen -{ +sub irisAbsOpen { + Debug("Iris $CamParams{Brightness}"); my $self = shift; my $params = shift; - $self->getCamParams() unless($CamParams{'brightness'}); - my $step = $self->getParam( $params, 'step' ); + $self->getCamParams() unless($CamParams{Brightness}); + my $step = $self->getParam($params, 'step'); + my $max = 100; - $CamParams{'brightness'} += $step; - $CamParams{'brightness'} = 255 if ($CamParams{'brightness'} > 255); - Debug( "Iris $CamParams{'brightness'}" ); - my $cmd = "camera_control.cgi?param=1&value=".$CamParams{'brightness'}; - $self->sendCmd( $cmd ); + $CamParams{Brightness} += $step; + $CamParams{Brightness} = $max if ($CamParams{Brightness} > $max); + + my $cmd = 'onvif/imaging'; + my $msg_body =' + + + 000 + + '.$CamParams{Brightness}.' + + true + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"'; + $self->sendCmd($cmd, $msg_body, $content_type); } # Decrease Brightness -sub irisAbsClose -{ +sub irisAbsClose { + Debug("Iris $CamParams{Brightness}"); my $self = shift; my $params = shift; - $self->getCamParams() unless($CamParams{'brightness'}); - my $step = $self->getParam( $params, 'step' ); + $self->getCamParams() unless($CamParams{brightness}); + my $step = $self->getParam($params, 'step'); + my $min = 0; - $CamParams{'brightness'} -= $step; - $CamParams{'brightness'} = 0 if ($CamParams{'brightness'} < 0); - Debug( "Iris $CamParams{'brightness'}" ); - my $cmd = "camera_control.cgi?param=1&value=".$CamParams{'brightness'}; - $self->sendCmd( $cmd ); + $CamParams{Brightness} -= $step; + $CamParams{Brightness} = $min if ($CamParams{Brightness} < $min); + + my $cmd = 'onvif/imaging'; + my $msg_body =' + + + 000 + + '.$CamParams{Brightness}.' + + true + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"'; + $self->sendCmd($cmd, $msg_body, $content_type); } # Increase Contrast -sub whiteAbsIn -{ +sub whiteAbsIn { + Debug("Iris $CamParams{Contrast}"); my $self = shift; my $params = shift; - $self->getCamParams() unless($CamParams{'contrast'}); - my $step = $self->getParam( $params, 'step' ); + $self->getCamParams() unless($CamParams{Contrast}); + my $step = $self->getParam($params, 'step'); + my $max = 100; - $CamParams{'contrast'} += $step; - $CamParams{'contrast'} = 6 if ($CamParams{'contrast'} > 6); - Debug( "Iris $CamParams{'contrast'}" ); - my $cmd = "camera_control.cgi?param=2&value=".$CamParams{'contrast'}; - $self->sendCmd( $cmd ); + $CamParams{Contrast} += $step; + $CamParams{Contrast} = $max if ($CamParams{Contrast} > $max); + + my $cmd = 'onvif/imaging'; + my $msg_body =' + + + 000 + + '.$CamParams{Contrast}.' + + true + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"'; + $self->sendCmd($cmd, $msg_body, $content_type); } # Decrease Contrast -sub whiteAbsOut -{ +sub whiteAbsOut { + Debug("Iris $CamParams{Contrast}"); my $self = shift; my $params = shift; - $self->getCamParams() unless($CamParams{'contrast'}); - my $step = $self->getParam( $params, 'step' ); + $self->getCamParams() unless($CamParams{Contrast}); + my $step = $self->getParam($params, 'step'); + my $min = 0; - $CamParams{'contrast'} -= $step; - $CamParams{'contrast'} = 0 if ($CamParams{'contrast'} < 0); - Debug( "Iris $CamParams{'contrast'}" ); - my $cmd = "camera_control.cgi?param=2&value=".$CamParams{'contrast'}; - $self->sendCmd( $cmd ); + $CamParams{Contrast} -= $step; + $CamParams{Contrast} = $min if ($CamParams{Contrast} < $min); + + my $cmd = 'onvif/imaging'; + my $msg_body =' + + + 000 + + '.$CamParams{Contrast}.' + + true + + '; + my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"'; + $self->sendCmd($cmd, $msg_body, $content_type); } 1; - +__END__