PTZ with onvif

Forum for questions and support relating to the 1.30.x releases only.
pat2
Posts: 157
Joined: Fri Sep 16, 2016 6:35 pm

Re: PTZ with onvif

Post by pat2 »

SOLVED! :D :D

I sent the first succesful PTZ command through the modified Netcat ONVIF ZM script ! :-)
I used the method suggested by knigget! Thanks

That is: sniff through Wireshark the commands sent by the Windows ONVIF app and compare them with the commands of Netcat ONVIF script sent by ZM (I was not able to sniff them, but i compared directly with the commands written in the script itself).
Then modify the script according to what sniffed.

So, for the first I tried Down Arrow I was succesful.
Now i understood the method and I will publish the script for the camera (when I will finish for all the commands): a dome cheap and powerful camera by Leftek. You could find on amazon:

https://www.amazon.co.uk/LEFTEK-3-5mm-1 ... rds=leftek

Thanks Knigget! You gave me the method! :-)
---------------------------------------------------------------------------
ZM 1.36.36 - 14 cameras on Orange Pi 5 (arm64) - Ubuntu Jammy 22.04
hz01web
Posts: 4
Joined: Fri May 18, 2018 8:02 am

Re: PTZ with onvif

Post by hz01web »

Hi! I have a little problem with Zoneminder PTZ control settings.
I bought a noname mini dome PTZ camera on eBay. (It's very good, there aren't any problem with this device. :) )

Open TCP ports: 80, 554, 8000, 8200
I tryed setting the ptz in iSpy, successfully: it's working. I using PTZ with ONVIF:
https://ibb.co/nhGYty
https://ibb.co/drdP0d

But I don't know how to set this in ZoneMinder. I tryed "ONVIF camera" and "Netcat ONVIF" (modify the pan/tilt parameters to my device), but doesn't work. I tryed more parameters in "Control Address":
admin:admin@10.0.1.4:8000
admin:admin@10.0.1.4:8000/onvif/device_service
etc...

What to do? What are the correct parameters?
hz01web
Posts: 4
Joined: Fri May 18, 2018 8:02 am

Re: PTZ with onvif

Post by hz01web »

pat2 wrote: Sat Mar 31, 2018 3:54 pm So, for the first I tried Down Arrow I was succesful.
Now i understood the method and I will publish the script for the camera (when I will finish for all the commands): a dome cheap and powerful camera by Leftek. You could find on amazon:

https://www.amazon.co.uk/LEFTEK-3-5mm-1 ... rds=leftek
Hi! My camera is too similar to yours. Please, publish your script. Thx!
https://www.ebay.com/itm/Waterproof-PTZ ... 2749.l2649
Epsilon187
Posts: 2
Joined: Fri Jul 06, 2018 1:08 pm

Re: PTZ with onvif

Post by Epsilon187 »

Hi there all, I followed your discussion here.
I am using a Dahua IP Dome cam DH-SD22204T-GN.
This camera works out of the box with PTZ commands with the android app called Onvifer. To capture some useful information I did the following:
install android app tPacketCapture and move the camera around with Onvifer app.
Then I saved the output as pcap file and emailed it to my account so I could open it in Wireshark on the desktop. Then analyse and filter the http/xml requests, and right click to follow the tcp stream, you will see readable service requests.

I have set up a centos server with zoneminder (which I can view via my ubuntu laptop, see below), everything is running and working correct, but the PTZ control does not.
I am using the ZM configuration with the camera IP in Controll Address and the Control Device is onvif/device_service. As Control Type I selected the Netcat ONVIF template.

Image

This should work, why? Because I first attemtped to get the camera respond to all the wsdl's from the ONVIF specs, which are the following:

http://www.onvif.org/ver10/device/wsdl
on my device it will be: http://192.168.1.253/onvif/device_service

http://www.onvif.org/ver20/analytics/wsdl
http://192.168.1.253/onvif/analytics_service

http://www.onvif.org/ver20/imaging/wsdl
http://192.168.1.253/onvif/imaging_service

http://www.onvif.org/ver10/media/wsdl
http://192.168.1.253/onvif/media_service

http://www.onvif.org/ver20/media/wsdl
http://192.168.1.253/onvif/media2_service

http://www.onvif.org/ver20/ptz/wsdl
http://192.168.1.253/onvif/ptz_service

http://www.onvif.org/ver10/events/wsdl
http://192.168.1.253/onvif/event_service

http://www.onvif.org/ver10/deviceIO/wsdl
http://192.168.1.253/onvif/deviceIO_service

Image

So I tried some tests in Soapui, referred to the correct wsdl from Onvif and then to set my camera as an endpoint, so the message will be sent to the camera... This works!!!! I think this is good news, because if you can get the services to respond and to work via SoapUI then it HAS TO WORK with any other application via webservices..... the only problem when I try the Netcat ONVIF template from ZM I get the following error in the /var/log/messages:

Jul 6 14:43:59 localhost zmcontrol[1581]: ERR [After sending PTZ command, camera returned the following error:'500 Can't connect to 192.168.1.253:8899 (Connection refused)']

Image

I don't understand, why connection is refused? With the SoapUI request It just executes the operation without telling me it is refused... For instance, via the Dahua software I set up a Home position for the PTZ to return to. So then I first move the camera to a random other position with the android app Onvifer... then I fire my SoapUI request from GotoHomePosition of the PTZ.wsdl of onvif (see above list of wsdls) and the camera instantly moves to the home position, it really looks like magic cause it works....

What am I missing here???

Hope someone can point me in a good direction here...

When I get it working, I will be more than happy to provide howto's or manuals.
Greets
starbuck5
Posts: 3
Joined: Mon Jul 09, 2018 7:18 pm

Re: PTZ with onvif

Post by starbuck5 »

Hey guys. I have a slightly different PTZ camera, but I believe it to be from the same original manufacturer. Mine is branded as a "JideTech" and came from here: https://www.amazon.com/Outdoor-Security ... B074N2TRRR

After some trial and error with Wireshark, I have a working PTZ script based on the included Netcat script. It could use some cleanup, but I thought it would be useful to post here for now.

https://pastebin.com/tAgHvXSe

I'm using the following settings:
Screen Shot 2018-07-09 at 1.26.52 PM.png
Screen Shot 2018-07-09 at 1.26.52 PM.png (32.21 KiB) Viewed 54523 times

I'm just messing around with the "Track Motion" setting. That doesn't need to be checked. I also haven't bothered to change the camera's username and password from the default admin:admin. They're on an isolated network so I don't have a need to.
l80jas
Posts: 7
Joined: Sat May 07, 2011 5:58 pm
Location: Belfast, Northern Ireland

Re: PTZ with onvif

Post by l80jas »

Hi there,
I can confirm that this works with Secuplug+ , branded as Zoneway HD 1080P PTZ Outdoor POE Security IP Dome Camera with 3X Optical Zoom Pan/Tilt/3X Motorized Zoom.
Good work.
User avatar
iconnor
Posts: 3198
Joined: Fri Oct 29, 2010 1:43 am
Location: Toronto
Contact:

Re: PTZ with onvif

Post by iconnor »

Epsilon187: I'm guessing that the port 8899 is wrong. From your screenshot, it looks like it should just be port 80. Did you put port 8899 in ControlAddress? Try removing it.
Epsilon187
Posts: 2
Joined: Fri Jul 06, 2018 1:08 pm

Re: PTZ with onvif

Post by Epsilon187 »

iconnor wrote: Wed Jul 11, 2018 12:33 pm Epsilon187: I'm guessing that the port 8899 is wrong. From your screenshot, it looks like it should just be port 80. Did you put port 8899 in ControlAddress? Try removing it.
Thanks for the guidance. As I come to think of it, WEB-services, web, http, is port 80. So I will change my hard coded address in the controlfile .pm
I will post the outcome later.
greets
starbuck5
Posts: 3
Joined: Mon Jul 09, 2018 7:18 pm

Re: PTZ with onvif

Post by starbuck5 »

@Epsilon187: I second the port suggestion. The "connection refused" error strongly suggests that the port is incorrect.

You should be able to use the control script I linked above. My cameras also use "onvif/ptz_service" to control the PTZ stuff. Though mine use port 8999, not sure what port is the correct one for yours.

The change to "onvif/ptz_service" was the biggest thing I had to do to get the script working. The original netcat script uses "onvif/device_service" but my cameras don't provide PTZ control at that URL.

I knew I was getting close when the cameras were responding with "400 Bad Request". instead of a connection refused error.
pat2
Posts: 157
Joined: Fri Sep 16, 2016 6:35 pm

Re: PTZ with onvif

Post by pat2 »

hi hz01web, I just found your mails sent to me. My excuses for the delay.

Please find below the modified script Netcat.pm I used to send PTZ command to my Leftek cameras (i have 3 cameras).

Currently working for up-down, left, right, diagonal movements, zoom and set/go to position commands.

Code: Select all

# ==========================================================================
#
# ZoneMinder Netcat IP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0001 $
# Copyright (C) 2001-2008 Philip Coombes
# Converted for use with Netcat IP Camera 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
# 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 Netcat IP camera control
# protocol
#
package ZoneMinder::Control::Netcat;

use 5.006;
use strict;
use warnings;

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

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

our %CamParams = ();

# ==========================================================================
#
# Netcat IP Control Protocol
# This script sends ONVIF compliant commands and may work with other cameras
#
# The Netcat camera gladly accepts any command with or without authentication,
# which prevented me from developing Onvif authentication in this control script.
#
# Basic preset functions are supported, but more advanced features, which make
# use of abnormally high preset numbers (ir lamp control, tours, pan speed, etc)
# may or may not work.
# 
#
# Possible future improvements (for anyone to improve upon):
#    - Onvif authentication
#    - Build the SOAP commands at runtime rather than use templates
#    - Implement previously mentioned advanced features
#
# Implementing the first two will require additional Perl modules, and adding
# more dependencies to ZoneMinder is always a concern.
#
# On ControlAddress use the format :
#   ADDRESS:PORT
#   eg : 10.1.2.1:8899
#        10.0.100.1:8899
#
# Use port 8899 for the Netcat camera
#
# Make sure and place a value in 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 );

sub new
{ 

    my $class = shift;
    my $id = shift;
    my $self = ZoneMinder::Control->new( $id );
    my $logindetails = "";
    bless( $self, $class );
    srand( time() );
    return $self;
}

our $AUTOLOAD;

sub AUTOLOAD
{
    my $self = shift;
    my $class = ref( ) || 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 $msg = shift;
    my $content_type = shift;
    my $result = undef;

    printMsg( $cmd, "Tx" );

    my $server_endpoint = "http://".$self->{Monitor}->{ControlAddress}."/$cmd";
    my $req = HTTP::Request->new( POST => $server_endpoint );
    $req->header('content-type' => $content_type);
    $req->header('Host' => $self->{Monitor}->{ControlAddress});
    $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, camera returned the following error:'".$res->status_line()."'" );
    }
    return( $result );
}

sub getCamParams
{
    my $self = shift;
    my $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"><GetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>MainStream</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' => $self->{Monitor}->{ControlAddress});
    $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_service';
        my $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>MainStream</ProfileToken><PanTilt>true</PanTilt><Zoom>false</Zoom></Stop></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 );
    }
}

# Reset the Camera
sub reset
{
    Debug( "Camera Reset" );
    my $self = shift;
    my $cmd = "";
    my $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"><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_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Down Arrow
#MODIFICATO x="0" y="0.5"
sub moveConDown
{
    Debug( "Move Down" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Left Arrow
#MODIFICATO x="0.5" y="0"
sub moveConLeft
{
    Debug( "Move Left" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Right Arrow
#MODIFICATO x="-0.5" y="0"
sub moveConRight
{
    Debug( "Move Right" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Zoom In
sub zoomConTele
{
    Debug( "Zoom Tele" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><Zoom x="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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Zoom Out
sub zoomConWide
{
    Debug( "Zoom Wide" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><Zoom x="-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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Diagonally Up Right Arrow
#MODIFICATO x="-0.5" y="-0.5"
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpRight
{
    Debug( "Move Diagonally Up Right" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><PanTilt x="-0.5" 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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Diagonally Down Right Arrow
#MODIFICATO x="-0.5" y="0.5"
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownRight
{
    Debug( "Move Diagonally Down Right" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><PanTilt x="-0.5" 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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Diagonally Up Left Arrow
#MODIFICATO x="0.5" y="-0.5"
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpLeft
{
    Debug( "Move Diagonally Up Left" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><PanTilt x="0.5" 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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Diagonally Down Left Arrow
#MODIFICATO x="0.5" y="0.5"
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownLeft
{
    Debug( "Move Diagonally Down Left" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><Velocity><PanTilt x="0.5" 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 );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

#Stop
#MODIFICATO
sub moveStop
{
    Debug( "Move Stop" );
    my $self = shift;
    my $cmd = 'onvif/ptz_service';
    my $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>MainStream</ProfileToken><PanTilt>true</PanTilt><Zoom>false</Zoom></Stop></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/Stop"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

#Set Camera Preset
sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Set Preset $preset" );
    my $cmd = 'onvif/ptz_service';
    my $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"><SetPreset xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><PresetToken>'.$preset.'</PresetToken></SetPreset></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/SetPreset"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

#Recall Camera Preset
sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Goto Preset $preset" );
    my $cmd = 'onvif/ptz_service';
    my $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"><GotoPreset xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>MainStream</ProfileToken><PresetToken>'.$preset.'</PresetToken></GotoPreset></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/GotoPreset"';
    $self->sendCmd( $cmd, $msg, $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
#To be determined if this camera supports this feature
sub horizontalPatrolStop
{
    Debug( "Horizontal Patrol Stop" );
    my $self = shift;
    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
{
    Debug( "Iris $CamParams{'Brightness'}" );
    my $self = shift;
    my $params = shift;
    $self->getCamParams() unless($CamParams{'Brightness'});
    my $step = $self->getParam( $params, 'step' );
    my $max = 100;

    $CamParams{'Brightness'} += $step;
    $CamParams{'Brightness'} = $max if ($CamParams{'Brightness'} > $max);

    my $cmd = 'onvif/imaging';
    my $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"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>MainStream</VideoSourceToken><ImagingSettings><Brightness xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Brightness'}.'</Brightness></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

# Decrease Brightness
sub irisAbsClose
{
    Debug( "Iris $CamParams{'Brightness'}" );
    my $self = shift;
    my $params = shift;
    $self->getCamParams() unless($CamParams{'brightness'});
    my $step = $self->getParam( $params, 'step' );
    my $min = 0;

    $CamParams{'Brightness'} -= $step;
    $CamParams{'Brightness'} = $min if ($CamParams{'Brightness'} < $min);

    my $cmd = 'onvif/imaging';
    my $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"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>MainStream</VideoSourceToken><ImagingSettings><Brightness xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Brightness'}.'</Brightness></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
    $self->sendCmd( $cmd, $msg, $content_type );
}

# Increase Contrast
sub whiteAbsIn
{
    Debug( "Iris $CamParams{'Contrast'}" );
    my $self = shift;
    my $params = shift;
    $self->getCamParams() unless($CamParams{'Contrast'});
    my $step = $self->getParam( $params, 'step' );
    my $max = 100;

    $CamParams{'Contrast'} += $step;
    $CamParams{'Contrast'} = $max if ($CamParams{'Contrast'} > $max);

    my $cmd = 'onvif/imaging';
    my $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"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>MainStream</VideoSourceToken><ImagingSettings><Contrast xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Contrast'}.'</Contrast></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
}

# Decrease Contrast
sub whiteAbsOut
{
    Debug( "Iris $CamParams{'Contrast'}" );
    my $self = shift;
    my $params = shift;
    $self->getCamParams() unless($CamParams{'Contrast'});
    my $step = $self->getParam( $params, 'step' );
    my $min = 0;

    $CamParams{'Contrast'} -= $step;
    $CamParams{'Contrast'} = $min if ($CamParams{'Contrast'} < $min);

    my $cmd = 'onvif/imaging';
    my $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"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>MainStream</VideoSourceToken><ImagingSettings><Contrast xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Contrast'}.'</Contrast></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
    my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
}

1;

Last edited by pat2 on Sun Jul 15, 2018 11:08 pm, edited 6 times in total.
---------------------------------------------------------------------------
ZM 1.36.36 - 14 cameras on Orange Pi 5 (arm64) - Ubuntu Jammy 22.04
pat2
Posts: 157
Joined: Fri Sep 16, 2016 6:35 pm

Re: PTZ with onvif

Post by pat2 »

Hi guys and hz01web, below my experience (above the modified Netcat.pm script)

I discovered the ONVIF port my camera uses through the app:

https://sourceforge.net/projects/onvifdm/

Check if the camera works with the win ONVIFDM app. If so, you could find in identification, in the field URI the port the app is using.
In my case It was 8999.

I used exactly the setting posted by starbucks:

viewtopic.php?f=36&t=25138&start=15#p106457

i.e.:

Control Type = Netcat ONVIF
(nothing for Control Device)
Control Address = 192.168.1.200:8999
Auto Stop Timeout = 2.00

and I modified the Netcat.pm as posted above.

The method used to discover how to modify the original Netcat.pm script:
after some trial and error sessions with Wireshark I sniffed the commands sent by the Windows ONVIFDM app and compared them with the commands written in the original Netcat.pm script and modifyed it accordingly.

I hope it could help.
Last edited by pat2 on Tue Jul 17, 2018 8:52 am, edited 1 time in total.
---------------------------------------------------------------------------
ZM 1.36.36 - 14 cameras on Orange Pi 5 (arm64) - Ubuntu Jammy 22.04
pat2
Posts: 157
Joined: Fri Sep 16, 2016 6:35 pm

Re: PTZ with onvif

Post by pat2 »

starbuck5 wrote: Thu Jul 12, 2018 3:26 am @Epsilon187: I second the port suggestion. The "connection refused" error strongly suggests that the port is incorrect.

You should be able to use the control script I linked above. My cameras also use "onvif/ptz_service" to control the PTZ stuff. Though mine use port 8999, not sure what port is the correct one for yours.

The change to "onvif/ptz_service" was the biggest thing I had to do to get the script working. The original netcat script uses "onvif/device_service" but my cameras don't provide PTZ control at that URL.

I knew I was getting close when the cameras were responding with "400 Bad Request". instead of a connection refused error.
I fully agree with your comment.
the same for me: I knew I was getting close when the cameras were responding with "400 Bad Request".
in my case too there is the "onvif/ptz_service".
in my case too the port is 8999.
---------------------------------------------------------------------------
ZM 1.36.36 - 14 cameras on Orange Pi 5 (arm64) - Ubuntu Jammy 22.04
JLerch Tampa
Posts: 1
Joined: Mon Jun 03, 2019 5:31 pm

Re: PTZ with onvif

Post by JLerch Tampa »

Just a quick 1st Post to say Thank You! This thread helped me figure out how to get PTZ working in ZM with my new el-cheapo POE Camera.

Image

Image

I've been using a Reolink NVR (RLN8-410) with 6 of their RLC-410 IP Cameras, and for the most part it was ok. However it refuses to support any 3rd party cameras so it was time to build my own NVR. I went with ZoneMinder as I couldn't stomach the thought of running iSpy on Windows. :)

Still have a bunch of learning to do, but just wanted to say thank you!

Kind Regards,
James in Tampa,FL,USA,Earth
hans109h
Posts: 18
Joined: Fri Jun 10, 2011 11:58 pm

Re: PTZ with onvif

Post by hans109h »

I want to share what has worked for me in case it will help others.

I have 3 JideTech POE PTZ cameras. By appearance they look identical, however they have different firmware:
Two of my cameras have the following:
Version: V1.04.10-180423 IPD-E17T08 series

And my newest camera has:
Version: V1.04.11-190715 IPD-E1B2Y04

The V1.04.10 needed a modified version of the Netcat onvif as mentioned on page one of this post, and you can follow that, however V1.04.11 worked with the Netcat onvif packaged with ZoneMinder with these settings:
Control Device: MainStream
Control Address: user:passwd@ip:port (fill in your info) for me the port was 8999 out of the box.

I hope this helps someone,

Hans
jeremyenos
Posts: 10
Joined: Sat Apr 04, 2020 2:01 am

Re: PTZ with onvif

Post by jeremyenos »

I've been having some trouble with an S3VC PTZ camera.
https://www.amazon.com/gp/product/B07KW ... UTF8&psc=1

I can get the camera to move according the arrows- it just never stops. When I try w/ the ONVIF app and capture the stop instruction that comes automatically at the end of a ContinuousMove instruction, it looks like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope ... ><Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/ ... ><Password Type="http://docs.oasis-open.org/wss/2004/01/ ... ord><Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/ ... e><Created xmlns="http://docs.oasis-open.org/wss/2004/01/ ... er><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"><P ... e>HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/Stop"
Content-Length: 1183
Connection: close

I've tried to put that in place in both the stop function and the autostop, but neither seems to work. It also made me wonder if the camera is interpreting RelativeMove and ContinuousMove in reverse, so I tried subbing RelativeMove in the script too. Still wouldn't stop.
I don't know what to try next.

I wish someone could make a "trainer" script if you will that would tell me to hit certain buttons in a working or native app for a camera, intercept the instruction, and generate a functional netcat script for ZM. I'd do it, but I don't even know what I'm doing with SOAP stuff manually yet.
thanks.

Jeremy
Locked