[Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Forum for questions and support relating to the 1.34.x releases only.
Post Reply
nganga
Posts: 3
Joined: Wed Feb 17, 2021 5:18 am

[Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by nganga »

Hello there,
I am currently using ZoneMinder 1.34.23 on Ubuntu 20.04.2LTS for monitoring using Ctronics camera.
Here are my settings under Control tab:
  • Control Type: Netcat ONVIF
  • Control Address: camera_ip:8080
  • Auto Stop Timeout: 0.1
I was able to pan, tilt and zoom but it seems that the AutoStopTimeout configured doesn't work. My camera was continuously moving without stopping even though I tried to click Stop Zoom and Stop Pan/Tilt buttons.
When checking the log, I found the message same as below:
Component: zmcontrol_2
Level: ERR
Message: Can't access name:zoomStop AUTOLOAD:ZoneMinder::Control::Netcat::zoomStop member of object of class ZoneMinder::Control::Netcat from main:186
jperkins
Posts: 50
Joined: Sat Jan 23, 2021 11:08 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by jperkins »

this may be related in as much as how I fixed a similar issue with my PTZ setup.

viewtopic.php?f=9&t=25442&p=119856#p119856
nganga
Posts: 3
Joined: Wed Feb 17, 2021 5:18 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by nganga »

Same error but the handling of Hikvision and Netcat ONVIF are quite different since it's using ONVIF protocol.
I am not familiar with Perl but when i checked the source code Netcat.pm, there is still moveStop function.
jperkins
Posts: 50
Joined: Sat Jan 23, 2021 11:08 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by jperkins »

EDIT2. reread your original post and you have set the autotimeout. maybe try a whole number '1' ?
and dont hit zoom at all. once I got an error on my control script it wouldnt work at all till I restarted zoneminder.
maybe the pan and tilt will work , until you hit zoom and your error is generated

yea sorry I cant be of much more help. I peeked into the Netcat,PM

this caught my eye

Code: Select all

#autoStop
#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab
also noticed that most of the command end with this

Code: Select all

$self->autoStop($self->{Monitor}->{AutoStopTimeout});
So that got me wondering do you have anything set for the 'Auto Stop Timeout on the Control Tab' for that monitor ?
mine is blank, but as you point out I am using HIkvision , not ONVIF

I have no idea if a default value is set for 'Auto timeout' in the code.
EDIT - by my quess the AutoStopTimeout is undefined unless set https://github.com/ZoneMinder/zoneminde ... or.pm#L199

Maybe set your 'Auto timeout' on the Control Tab for that monitor at 1 second and see if it helps.

Other than that I am out of gas :-) good luck
nganga
Posts: 3
Joined: Wed Feb 17, 2021 5:18 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by nganga »

Thanks for your explanation. :D
I was set Auto Stop Timeout on the Control Tab at 1 second as well as smaller (0.25, 0.5)
But it still doesn't work.
Here is error message which is described in the Log Tab.

Code: Select all

After sending PTZ command, camera returned the following error:
'400 Bad Request'MSG:<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Stop xmlns="http://www.onvif.org/ver20/ptz/wsdl">
<ProfileToken>user=admin&pwd=xxxxx</ProfileToken>
<PanTilt>true</PanTilt><Zoom>false</Zoom></Stop></s:Body></s:Envelope>
Response:<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
xmlns:e="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" 
xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" 
xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" 
xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" 
xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" 
xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" 
xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" 
xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" 
xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" ><s:Body><s:Fault><s:Code><s:Value>s:Receiver</s:Value>
<s:Subcode><s:Value>ter:ActionNotSupported</s:Value></s:Subcode></s:Code>
<s:Reason><s:Text xml:lang="en">Action Not Implemented</s:Text></s:Reason></s:Fault></s:Body></s:Envelope>
piglet_74
Posts: 8
Joined: Thu May 03, 2012 11:43 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by piglet_74 »

I'm having the same issue and can't figure it out. I just got a Jidetech PTZ. It will move using the Netcat Onvif but it will keep going unless you click the opposite direction. I get the same error you get in the logs.

I have wiresharked the ONVIFDM tool to the camera which works correctly and can clearly see the tool sending a stop message. I compared the trace to the code and the error and the only difference I see is the nonce security is empty.

I have no idea what that is but it's empty in the error log and it has a value from the ONVIFDM tool.

I can collect more info if someone has any idea what to look at.

Thanks, Rob.
piglet_74
Posts: 8
Joined: Thu May 03, 2012 11:43 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by piglet_74 »

OK So I figured something out. Apparently Milestone (an NVMS company) had some info that they don't send stop commands. The spec allows sending x=0 and y=0 as an alternative. So I copied the up command code and pasted over the command part the autostop section and set the movements to 0. Then in the monitor I enabled autostop and set it to .5.

This is now working great for my Jidetech 20x PTZ camera. Fixed the zoom too. It used to only go to extremes. Also, no more bad requests in the log on every ptz move. I tried hard line by line to figure out what about the stop command my camera didn't like. Couldn't see any differences though.

Hope this helps. I can post more detail if you need it.
jfqbsm
Posts: 11
Joined: Tue Dec 14, 2021 6:36 pm

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by jfqbsm »

Hi piglet-74
I'm very new in ZoneMinder, and i have the same problem as you. I don't understand what you mean by copied the up command and pasted over the autostop section. Could you give me more details about your solution. Where this code is implemented, how these commands are coded? Is there somewhere documentation about these commands.
Thanks in advance for your help
jfqbsm
Posts: 11
Joined: Tue Dec 14, 2021 6:36 pm

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by jfqbsm »

Hi again,
Finally I found where the script Netcam.pm was (in /usr/share/perl5/ZoneMinder/Control) and updated the autostop section with the up arrow command and change x=0 y=0.
Now everything works fine.
alabamatoy
Posts: 349
Joined: Sun Jun 05, 2016 2:53 pm

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by alabamatoy »

can you post the specifics of the change you made to the Netcam.pm (specific line numbers, was and is) as an issue here so we can get it merged int master please?
jfqbsm
Posts: 11
Joined: Tue Dec 14, 2021 6:36 pm

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by jfqbsm »

Sorry for this late answer, i didn't login on the forum before now.
Then i replace the line 211 starting with my $msg ='<s:Envelope xml........
by the line 233 and change Y="0.5" by Y="0"
Hope this help
piglet_74
Posts: 8
Joined: Thu May 03, 2012 11:43 am

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by piglet_74 »

OK Sorry, didn't check in again and upgraded to 1.36 and had the issue come back. So more detail this time.

In /usr/share/perl5/Zoneminder/Control/Netcat.pm

I backed up the file then edited it in nano. I went down to the section for up arrow starting around line 263. I copied the lines that contain the start and end envelope tags. It's 5 lines in total. lines 268-272.

Then I paste it over the envelope line for the autostop. This is line 206. Then where it says pantilt x=0 y=0.5. I make both x and y 0.

Then I save the file. Go into ZM for the camera and choose a different control. Save and then change back to Netcat ONVIF.

Then in the control section, enable autostop and .5. So now it sends a move command of 0,0 for the autostop.

Hope this helps.
moennich
Posts: 2
Joined: Mon Sep 19, 2022 7:04 pm

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by moennich »

Well, I found another solution.

I'm using Zoneminder 1.36.26 version, and a chinese camera.

1. Edit file /usr/share/perl5/Zoneminder/Control/Netcat.pm
2. Change all ocurrences of "onvif/PTZ" by "onvif/ptz_service" (without double quotes)
3. Save the file

Just it, all working for me.
clipo
Posts: 101
Joined: Sat Sep 06, 2008 9:55 am
Location: Manchester, UK
Contact:

Re: [Netcat ONVIF] Can not stop while controlling PTZ - AutoStopTimeout doesn't work

Post by clipo »

There is a bug in the ONVIF code so that the STOP command isn't sent.

The solution is to pass a command to have X and Y motion as 0.

See this post and below code of the ieGeek camera that has the same issue.

viewtopic.php?p=127089#p127089

Code: Select all

#Stop
#The ieGeek implimentaion of ONVIF seems to not support the Stop command so a zero motion contious move command is sent.
sub moveStop
{
    Debug( "Move Stop" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
	<ProfileToken>000</ProfileToken>
	<Velocity>
	<PanTilt x="0" y="0" xmlns="http://www.onvif.org/ver10/schema"/>
	</Velocity>
	</ContinuousMove>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

Code: Select all

# ==========================================================================
#
# Basic ZoneMinder ieGeek IE20 ONVIF IP PTZ Camera Control Module 9-June-2022
# By Clipo (ZoneMinder Forums)
#
# This file is based up on the Reolink IP Control Module 2016-01-19
# Copyright (C) 2016 Chris Swertfeger
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# ==========================================================================
#
# This module contains the first implementation of the ieGeek ONVIF IP camera control
# protocol
#
package ZoneMinder::Control::ieGeek;

use 5.006;
use strict;
use warnings;

require ZoneMinder::Base;
require ZoneMinder::Control;

our @ISA = qw(ZoneMinder::Control);

our %CamParams = ();

# ==========================================================================
#
# ieGeek ONVIF IP Control Protocol
# The ieGeek camera support ONVIF in a limited way with 
# this script sends ONVIF style commands and may work with other cameras
# that require authentication
#
# The script was developed against an IE20 Camera.
#
# Basic preset functions are supported only.
# #
# On ControlAddress use the format :
#   USERNAME:PASSWORD@ADDRESS:PORT
#   eg : admin:pass@10.1.2.1:8080
#        
# ieGeek cameras use port 8080 by default
#
# The Auto Stop Timeout field.
# Recommend starting with a value of 1 second, and adjust accordingly.
#
# ==========================================================================

use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);

use Time::HiRes qw( usleep );

use MIME::Base64;
use Digest::SHA;
use DateTime;

my ($username,$password,$host,$port);

sub open
{
    my $self = shift;

    $self->loadMonitor();
    #
    # Extract the username/password host/port from ControlAddress
    #
    if( $self->{Monitor}{ControlAddress} =~ /^([^:]+):([^@]+)@(.+)/ ) 
    { # user:pass@host...
      $username = $1;
      $password = $2;
      $host = $3;
    }
    elsif( $self->{Monitor}{ControlAddress} =~ /^([^@]+)@(.+)/ )  
    { # user@host...
      $username = $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;
    }

    use LWP::UserAgent;
    $self->{ua} = LWP::UserAgent->new;
    $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );

    $self->{state} = 'open';
}

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 $msg = shift;
    my $content_type = shift;
    my $result = undef;

    printMsg( $cmd, "Tx" );

    my $server_endpoint = "http://".$host.":".$port."/$cmd";
    my $req = HTTP::Request->new( POST => $server_endpoint );
    $req->header('content-type' => $content_type);
    $req->header('Host' => $host.':'.$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("After sending PTZ command to $server_endpoint, camera returned the following error:'".$res->status_line()."'" );
    }
    return $result;
}

sub getCamParams
{
    my $self = shift;
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<GetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl">
	<VideoSourceToken>000</VideoSourceToken>
	</GetImagingSettings>
	</s:Body>
	</s:Envelope>';
    my $server_endpoint = "http://".$self->{Monitor}->{ControlAddress}."/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' => $host.":".$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 ) {
        # We should really use an xml or soap library to parse the xml tags
        my $content = $res->decoded_content;

        if ($content =~ /.*<tt:(Brightness)>(.+)<\/tt:Brightness>.*/) {
            $CamParams{$1} = $2;
        }
        if ($content =~ /.*<tt:(Contrast)>(.+)<\/tt:Contrast>.*/) {
            $CamParams{$1} = $2;
        }
    } 
    else
    {
        Error( "Unable to retrieve camera image settings:'".$res->status_line()."'" );
    }
}

#autoStop
#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab
sub autoStop
{
    my $self = shift;
    my $autostop = shift;

    if( $autostop ) {
        Debug( "Auto Stop" );
        my $cmd = 'onvif/PTZ';
        my $nonce;
        for (0..20){$nonce .= chr(int(rand(254)));}
        my $mydate = DateTime->now()->iso8601().'Z';
        my $sha = Digest::SHA->new(1);
        $sha->add($nonce.$mydate.$password);
        my $digest = encode_base64($sha->digest,"");
        my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
		<s:Header>
		<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
		<UsernameToken>
		<Username>'.$username.'</Username>
		<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
		<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
		<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
		</UsernameToken>
		</Security>
		</s:Header>
		<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
		<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
		<ProfileToken>000</ProfileToken>
		<Velocity>
		<PanTilt x="0" y="0" xmlns="http://www.onvif.org/ver10/schema"/>
		</Velocity>
		</ContinuousMove>
		</s:Body>
		</s:Envelope>';
    	my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
        usleep( $autostop );
        $self->sendCmd( $cmd, $msg, $content_type );
    }
}

# Reboot the Camera
sub reboot
{
    Debug( "Camera Reboot" );
    my $self = shift;
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $cmd = "";
    my $msg = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<SystemReboot xmlns="http://www.onvif.org/ver10/device/wsdl"/>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/SystemReboot"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

#Up Arrow
sub moveConUp
{
    Debug( "Move Up" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    		<s:Header>
		<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
		<UsernameToken>
		<Username>'.$username.'</Username>
		<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
		<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
		<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
		</UsernameToken>
		</Security>
		</s:Header>
		<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
		<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
		<ProfileToken>000</ProfileToken>
		<Velocity>
		<PanTilt x="0" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/>
		</Velocity>
		</ContinuousMove>
		</s:Body>
		</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
    #AutoStop Commnented out to give fine control
    #$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Down Arrow
sub moveConDown
{
    Debug( "Move Down" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
	<ProfileToken>000</ProfileToken
	><Velocity>
	<PanTilt x="0" y="-0.5" xmlns="http://www.onvif.org/ver10/schema"/>
	</Velocity>
	</ContinuousMove>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
    #AutoStop Commnented out to give fine control
    #$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Left Arrow
sub moveConLeft
{
    Debug( "Move Left" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
	<ProfileToken>000</ProfileToken>
	<Velocity>
	<PanTilt x="-0.49" y="0" xmlns="http://www.onvif.org/ver10/schema"/>
	</Velocity>
	</ContinuousMove>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
    #AutoStop Commnented out to give fine control
    #$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Right Arrow
sub moveConRight
{
    Debug( "Move Right" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
     my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
     	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
	<ProfileToken>000</ProfileToken>
	<Velocity>
	<PanTilt x="0.5" y="0" xmlns="http://www.onvif.org/ver10/schema"/>
	</Velocity>
	</ContinuousMove>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
    #AutoStop Commnented out to give fine control
    #$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Stop
#The ieGeek implimentaion of ONVIF seems to not support the Stop command so a zero motion contious move command is sent.
sub moveStop
{
    Debug( "Move Stop" );
    my $self = shift;
    my $cmd = 'onvif/PTZ';
    my $nonce;
    for (0..20){$nonce .= chr(int(rand(254)));}
    my $mydate = DateTime->now()->iso8601().'Z';
    my $sha = Digest::SHA->new(1);
    $sha->add($nonce.$mydate.$password);
    my $digest = encode_base64($sha->digest,"");
    my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    	<s:Header>
	<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<UsernameToken>
	<Username>'.$username.'</Username>
	<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$digest.'</Password>
	<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.encode_base64($nonce,"").'</Nonce>
	<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$mydate.'</Created>
	</UsernameToken>
	</Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
	<ProfileToken>000</ProfileToken>
	<Velocity>
	<PanTilt x="0" y="0" xmlns="http://www.onvif.org/ver10/schema"/>
	</Velocity>
	</ContinuousMove>
	</s:Body>
	</s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

1;
Post Reply