HOWTO - D-Link DCS-6620G With PTZ & Toshiba IK-WB11A

Post here to indicate any hardware you have used and which is known to work with ZoneMinder. Not for questions.
Post Reply
MILxDOT
Posts: 64
Joined: Wed Mar 29, 2006 5:12 am

HOWTO - D-Link DCS-6620G With PTZ & Toshiba IK-WB11A

Post by MILxDOT »

I do some volunteer sysadmin work in our area. In the past we have used GNU motion for surveillance. (more efficient than ZM but less features) We are converting over to Zoneminder. Phil's zoneminder project is one of my new favorite past-times.

Before I begin I would like to note that the 6620G from D-Link is the exact same camera as the following other units:

Hawking Technologies HNC820G
Vivotek PZ6114/PZ6124

It looks like Vivotek actually manufactures the hardware itself. D-Link and Hawking Tech just use their own firmware releases.

Why did we choose the D-Link 6620 over some of the other netcams out there? Well, we are part of a medium sized distributed network that needs outdoor surveillance in a few key locations where wiring is not an option, but there were existing outlets in the ceiling that we could utilize. Normally as a rule of thumb we try to stay away from wireless as it is so insecure and slower that wire speed. After some research...we started this project by ordering up a Toshiba IK-WB11A (Pan-Tilt) unit with it's outdoor enclosure. After messing around for about a half a day...we got the Toshiba to work perfectly with Zoneminder. I will try to provide documentation on that setup below. The Toshiba did everything we wanted minus optical zoom, 802.11g (it is B only). We started talking about actually deploying this unit and went through our normal battery of tests including security checks. Here is where the unit would not work out. I fired up my notebook which has an intel pro wireless 2200 in it running kismet, airsnort, and then aircrack. Even with the Toshiba set to 128bit WEP encryption...we were able to jump into our access point after a couple hours of sniffing for keys and then running aircrack. We decided that WEP was not an option for this project so we scrapped the idea of the Toshiba because it does not support WPA. We then went shopping again for a camera that would do 30FPS, had optical zoom, and would do WPA wireless security, and had a decent looking outdoor enclosure that could withstand our Minnesota winters. The D-Link 6620G, Hawking Tech HNC820G, and the Vivotek PZ6114/PZ6124 were the only cams we found that fit these requirements.

For our final setup we ordered the following:

1 - D-Link DCS-6620G Camera ($785.98 from newegg.com)
1 - D-Link DCS-70 Outdoor Enclosure ($406 from c-source.com)
1 - Linksys WAP54GPE Outdoor POE Access Point ($389.98 from newegg.com)

Total Equipment: $1581.96 (Kinda Spendy...but worth it)

These units were really finiky about talking to each other using WPA-TKIP but we got it. Use the following options in your wireless config:

Will add this later...don't have access to it from home.

I will just jot down a few key notes for your zoneminder configs tonight, but will try to update this with a more detailed howto as time permits.

Zoneminder settings for DCS-6620G:

Source:
Remote Host Name admin:password@192.168.0.10
Remote Host Port 80
Remote Host Path /cgi-bin/video.jpg
Remote Image Colours 24bit
Capture Width 352
Capture Height 240
Orientation Normal

Buffers:
Image Buffer Size 15
Warmup Frames 5
Pre Event Image Buffer 10
Post Event Image Buffer 10
Alarm Frame Count 1

Misc:
Maximum FPS 10.00
FPS Report Interval 1000

Control:
Controllable Checked
Control Type DCS-6620G (you will have to create this)
Control Device blank
Control Address admin:password@192.168.0.10
Auto Stop Timeout blank
Track Motion blank
Track Delay 0
Return Location Home
Return Delay 0

Control Capability - DCS-6620G:
Main:
Name DCS-6620G
Type Remote
Command zmcontrol-6620g.pl (you will need to create this in /usr/local/bin)
Can Wake blank
Can Sleep blank
Can Reset blank

Move:
Can Move checked
Can Move Diagonally not checked
Can Move Mapped checked
Can Move Absolute checked
Can Move Relative checked
Can Move Continuous checked

Pan:
Can Pan checked
Min Pan Range -135
Max Pan Range 135
Min Pan Step 0
Max Pan Step 0
Has Pan Speed blank
Min Pan Speed blank
Max Pan Speed blank
Has Turbo Pan blank
Turbo Pan Speed blank

Tilt:
Can Tilt checked
Min Tilt Range -45
Max Tilt Range 90
Min Tilt Step blank
Max Tilt Step blank
Has Tilt Speed blank
Min Tilt Speed blank
Max Tilt Speed blank
Has Turbo Tilt blank

Zoom:
Can Zoom checked
Can Zoom Absolute blank
Can Zoom Relative blank
Can Zoom Continuous checked
Min Zoom Range 1
Max Zoom Range 10
Min Zoom Step 1
Max Zoom Step 10
Has Zoom Speed blank
Min Zoom Speed 0
Max Zoom Speed 5

Presets:
Has Presets checked
Num Presets 1
Has Home Preset checked
Can Set Presets blank

For the zmcontrol file in /usr/local/bin I just copied the existing zmcontrol-axis-v2.pl to zmcontrol-6620g.pl and edited. Here are some key snippets:

sub moveUp
{
print( "Move Up\n" );
my $cmd = "cgi-bin/camctrl.cgi?move=up";
sendCmd( $cmd );
}


sub zoomTele
{
print( "Zoom Tele\n" );
my $cmd = "cgi-bin/camctrl.cgi?zoom=tele";
sendCmd( $cmd );
}

sub zoomWide
{
print( "Zoom Wide\n" );
my $cmd = "cgi-bin/camctrl.cgi?zoom=wide";
sendCmd( $cmd );
}

To get the zoom working you will also need to go to the bottom of the file and change the zoom elseifs to:

elsif ( $command eq "zoom_con_tele" )
{
zoomTele();
}
elsif ( $command eq "zoom_con_wide" )
{

That should get you doing PTZ on the 6620G. Most of this information was actually dug up from a PDF that we downloaded from Vivotek's site. D-Link will not provide any of this information.

Now some more configs for getting the Toshiba ID-WB11A working:

Source:
Remote Host Name 192.168.0.11
Remote Host Port 80
Remote Host Path /__live.jpg?&&&
Remote Image Colours 24bit
Capture Width (pixels) 640
Capture Height (pixels) 480
Orientation Normal

Buffers:
Image Buffer Size (frames) 20
Warmup Frames 5
Pre Event Image Buffer 10
Post Event Image Buffer 10
Alarm Frame Count 1

Misc:
Maximum FPS 10.00
FPS Report Interval 1000

Control:
Controllable checked
Control Type IK-WB11A (you will need to create this)
Control Device
Control Address 192.168.0.11
Auto Stop Timeout blank
Track Motion blank
Track Delay blank
Return Location none
Return Delay 0

Control Capability - IK-WB11A

Main:
Name IK-WB11A
Type Remote
Command zmcontrol-toshiba.pl (you will need to create this)
Can Wake blank
Can Sleep blank
Can Reset blank

Move:
Can Move checked
Can Move Diagonally blank
Can Move Mapped checked
Can Move Absolute checked
Can Move Relative checked
Can Move Continuous checked

Pan:
Can Pan checked
Min Pan Range -56
Max Pan Range 56
Min Pan Step 1
Max Pan Step 90
Has Pan Speed blank
Min Pan Speed blank
Max Pan Speed blank
Has Turbo Pan blank
Turbo Pan Speed blank

Tilt:
Can Tilt checked
Min Tilt Range -49
Max Tilt Range 5
Min Tilt Step blank
Max Tilt Step blank
Has Tilt Speed blank
Min Tilt Speed blank
Max Tilt Speed blank
Has Turbo Tilt blank
Turbo Tilt Speed blank

Zoom...we didn't even mess with it cause it is only digital not optical do-able though.

Presets:
Has Presets checked
Num Presets 10
Has Home Preset checked
Can Set Presets checked

For the zmcontrol file in /usr/local/bin I just copied the existing zmcontrol-axis-v2.pl to zmcontrol-toshiba.pl and edited. Here are some key snippets:

sub moveUp
{
print( "Move Up\n" );
my $cmd = "/pantiltapi.cgi?cont_2=4&ok=dummy.htm";
sendCmd( $cmd );
}

sub moveDown
{
print( "Move Down\n" );
my $cmd = "/pantiltapi.cgi?cont_2=8&ok=dummy.htm";
sendCmd( $cmd );
}

sub moveLeft
{
print( "Move Left\n" );
my $cmd = "/pantiltapi.cgi?cont_2=1&ok=dummy.htm";
sendCmd( $cmd );
}

sub moveRight
{
print( "Move Right\n" );
my $cmd = "/pantiltapi.cgi?cont_2=2&ok=dummy.htm";
sendCmd( $cmd );
}

That should get you going with Pan & Zoom on the IK-WB11A.
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post by cordel »

Thank you Miket for smoe very usefull information.

Cheers,
Corey
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

Yes, excellent and very thorough documentation. Most appreciated.

Thanks
Phil
paperstreet
Posts: 82
Joined: Thu May 18, 2006 7:45 pm

Post by paperstreet »

Thanks for the advice, got a vivotek and a wk-11a working, thought I would post some additional stuff:

with the Toshiba WK11-A
Remote Host Name 192.168.0.11
Remote Host Port 80
Remote Host Path /__live.jpg?&&&
Remote Image Colours 24bit
Capture Width (pixels) 640
Capture Height (pixels) 480
Orientation Normal
works but if you have password protection then you need to add it after the /_live.jpg?&&& in hash form like so:

Code: Select all

/__live.jpg?&&Z3Vlc3Q=&YnIxT2e=

where ""Z3Vlc3q=" is the user name and "&YnIxT2e=" is the pass..


As I work more with the cameras and zoneminder, I will post more

below is the complete output of "zmcontrol-6620g.pl'

Code: Select all


#!/usr/bin/perl -wT
#
# ==========================================================================
#
# ZoneMinder Axis HTTP API v2 Control Script, $Date: 2005/10/17 16:30:49 $, $Revision: 1.4 $
# Copyright (C) 2003, 2004, 2005  Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ==========================================================================
#
# This script continuously monitors the recorded events for the given
# monitor and applies any filters which would delete and/or upload 
# matching events
#
use strict;

# ==========================================================================
#
# These are the elements you need to edit to suit your installation
#
# ==========================================================================
use constant ZM_CONFIG => "/etc/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
use constant ZM_VERSION => "1.21.4";	# ZoneMinder version number, autogenerated do not change (from zmconfig)
use constant ZM_PATH_BIN => "/usr/lib/zm/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)

# Load the config from the database into the symbol table
BEGIN
{
	no strict 'refs';

	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
	foreach my $str ( <CONFIG> )
	{
		next if ( $str =~ /^\s*$/ );
		next if ( $str =~ /^\s*#/ );
		my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
		$name =~ tr/a-z/A-Z/;
		if (( $name eq 'ZM_DB_SERVER' ) ||
			( $name eq 'ZM_DB_NAME' ) ||
			( $name eq 'ZM_DB_USER' ) ||
			( $name eq 'ZM_DB_PASS' ))
		{
			*{$name} = sub { $value };
		}
	}
	close( CONFIG );

	use DBI;
	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
	my $sql = "select * from Config";
	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
	my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
	while( my $config = $sth->fetchrow_hashref() )
	{
		*{$config->{Name}} = sub { $config->{Value} };
	}
	$sth->finish();
	$dbh->disconnect();
}

use Getopt::Long;
use Device::SerialPort;

use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-6620g.log';

$| = 1;

$ENV{PATH}  = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

sub Usage
{
	print( "
Usage: zmcontrol-6620g.pl <various options>
");
	exit( -1 );
}

my $arg_string = join( " ", @ARGV );

my $address;
my $command;
my ( $speed, $step );
my ( $xcoord, $ycoord );
my ( $width, $height );
my ( $panspeed, $tiltspeed );
my ( $panstep, $tiltstep );
my $preset;

if ( !GetOptions(
	'address=s'=>\$address,
	'command=s'=>\$command,
	'speed=i'=>\$speed,
	'step=i'=>\$step,
	'xcoord=i'=>\$xcoord,
	'ycoord=i'=>\$ycoord,
	'width=i'=>\$width,
	'height=i'=>\$height,
	'panspeed=i'=>\$panspeed,
	'tiltspeed=i'=>\$tiltspeed,
	'panstep=i'=>\$panstep,
	'tiltstep=i'=>\$tiltstep,
	'preset=i'=>\$preset
	)
)
{
	Usage();
}

if ( !$address )
{
	Usage();
}

my $log_file = LOG_FILE;
open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
select( STDOUT ); $| = 1;
open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
select( STDERR ); $| = 1;
select( LOG ); $| = 1;

print( $arg_string."\n" );

srand( time() );

sub printMsg
{
	my $msg = shift;
	my $msg_len = length($msg);

	print( $msg );
	print( "[".$msg_len."]\n" );
}

sub sendCmd
{
	my $cmd = shift;

	my $result = undef;

	printMsg( $cmd, "Tx" );

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

	#print( "http://$address/$cmd\n" );
	my $req = HTTP::Request->new( GET=>"http://$address/$cmd" );
	my $res = $ua->request($req);

	if ( $res->is_success )
	{
		$result = !undef;
	}
	else
	{
		print( "Error check failed: '".$res->status_line()."'\n" );
	}

	return( $result );
}

sub cameraReset
{
	print( "Camera Reset\n" );
	my $cmd = "nphRestart?PAGE=Restart&Restart=OK";
	sendCmd( $cmd );
}

sub moveUp
{
	print( "Move Up\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=up";
	sendCmd( $cmd );
}

sub moveDown
{
	print( "Move Down\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=down";
	sendCmd( $cmd );
}

sub moveLeft
{
	print( "Move Left\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=left";
	sendCmd( $cmd );
}

sub moveRight
{
	print( "Move Right\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=right";
	sendCmd( $cmd );
}

sub moveUpRight
{
	print( "Move Up/Right\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=upright";
	sendCmd( $cmd );
}

sub moveUpLeft
{
	print( "Move Up/Left\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=upleft";
	sendCmd( $cmd );
}

sub moveDownRight
{
	print( "Move Down/Right\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=downright";
	sendCmd( $cmd );
}

sub moveDownLeft
{
	print( "Move Down/Left\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=downleft";
	sendCmd( $cmd );
}

sub moveMap
{
	my ( $xcoord, $ycoord, $width, $height ) = @_;
	print( "Move Map to $xcoord,$ycoord\n" );
	my $cmd = "cgi-bin/camctrl.cgi?center=$xcoord,$ycoord&imagewidth=$width&imageheight=$height";
	sendCmd( $cmd );
}

sub stepUp
{
	my $step = shift;
	print( "Step Up $step\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rtilt=$step";
	sendCmd( $cmd );
}

sub stepDown
{
	my $step = shift;
	print( "Step Down $step\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rtilt=-$step";
	sendCmd( $cmd );
}

sub stepLeft
{
	my $step = shift;
	print( "Step Left $step\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=-$step";
	sendCmd( $cmd );
}

sub stepRight
{
	my $step = shift;
	print( "Step Right $step\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=$step";
	sendCmd( $cmd );
}

sub stepUpRight
{
	my $panstep = shift;
	my $tiltstep = shift;
	print( "Step Up/Right $tiltstep/$panstep\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=$panstep&rtilt=$tiltstep";
	sendCmd( $cmd );
}

sub stepUpLeft
{
	my $panstep = shift;
	my $tiltstep = shift;
	print( "Step Up/Left $tiltstep/$panstep\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=-$panstep&rtilt=$tiltstep";
	sendCmd( $cmd );
}

sub stepDownRight
{
	my $panstep = shift;
	my $tiltstep = shift;
	print( "Step Down/Right $tiltstep/$panstep\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=$panstep&rtilt=-$tiltstep";
	sendCmd( $cmd );
}

sub stepDownLeft
{
	my $panstep = shift;
	my $tiltstep = shift;
	print( "Step Down/Left $tiltstep/$panstep\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rpan=-$panstep&rtilt=-$tiltstep";
	sendCmd( $cmd );
}

sub zoomTele
{
	my $step = shift;
	print( "Zoom Tele\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rzoom=$step";
	sendCmd( $cmd );
}

sub zoomWide
{
	my $step = shift;
	print( "Zoom Wide\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rzoom=-$step";
	sendCmd( $cmd );
}

sub focusNear
{
	my $step = shift;
	print( "Focus Near\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rfocus=-$step";
	sendCmd( $cmd );
}

sub focusFar
{
	my $step = shift;
	print( "Focus Far\n" );
	my $cmd = "cgi-bin/camctrl.cgi?rfocus=$step";
	sendCmd( $cmd );
}

sub focusAuto
{
	print( "Focus Auto\n" );
	my $cmd = "cgi-bin/camctrl.cgi?autofocus=on";
	sendCmd( $cmd );
}

sub focusMan
{
	print( "Focus Manual\n" );
	my $cmd = "cgi-bin/camctrl.cgi?autofocus=off";
	sendCmd( $cmd );
}

sub irisOpen
{
	my $step = shift;
	print( "Iris Open\n" );
	my $cmd = "cgi-bin/camctrl.cgi?riris=$step";
	sendCmd( $cmd );
}

sub irisClose
{
	my $step = shift;
	print( "Iris Close\n" );
	my $cmd = "cgi-bin/camctrl.cgi?riris=-$step";
	sendCmd( $cmd );
}

sub irisAuto
{
	print( "Iris Auto\n" );
	my $cmd = "cgi-bin/camctrl.cgi?autoiris=on";
	sendCmd( $cmd );
}

sub irisMan
{
	print( "Iris Manual\n" );
	my $cmd = "cgi-bin/camctrl.cgi?autoiris=off";
	sendCmd( $cmd );
}

sub presetClear
{
	my $preset = shift || 1;
	print( "Clear Preset $preset\n" );
	my $cmd = "nphPresetNameCheck?Data=$preset";
	sendCmd( $cmd );
}

sub presetSet
{
	my $preset = shift || 1;
	print( "Set Preset $preset\n" );
	my $cmd = "cgi-bin/camctrl.cgi?setserverpresetno=$preset";
	sendCmd( $cmd );
}

sub presetGoto
{
	my $preset = shift || 1;
	print( "Goto Preset $preset\n" );
	my $cmd = "cgi-bin/camctrl.cgi?gotoserverpresetno=$preset";
	sendCmd( $cmd );
}

sub presetHome
{
	print( "Home Preset\n" );
	my $cmd = "cgi-bin/camctrl.cgi?move=home";
	sendCmd( $cmd );
}

if ( $command eq "move_con_up" )
{
	moveUp();
}
elsif ( $command eq "move_con_down" )
{
	moveDown();
}
elsif ( $command eq "move_con_left" )
{
	moveLeft();
}
elsif ( $command eq "move_con_right" )
{
	moveRight();
}
elsif ( $command eq "move_con_upleft" )
{
	moveUpLeft();
}
elsif ( $command eq "move_con_upright" )
{
	moveUpRight();
}
elsif ( $command eq "move_con_downleft" )
{
	moveDownLeft();
}
elsif ( $command eq "move_con_downright" )
{
	moveDownLeft();
}
elsif ( $command eq "move_map" )
{
	moveMap( $xcoord, $ycoord, $width, $height );
}
elsif ( $command eq "move_rel_up" )
{
	stepUp( $tiltstep );
}
elsif ( $command eq "move_rel_down" )
{
	stepDown( $tiltstep );
}
elsif ( $command eq "move_rel_left" )
{
	stepLeft( $panstep );
}
elsif ( $command eq "move_rel_right" )
{
	stepRight( $panstep );
}
elsif ( $command eq "move_rel_upleft" )
{
	stepUpLeft( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_upright" )
{
	stepUpRight( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_downleft" )
{
	stepDownLeft( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_downright" )
{
	stepDownRight( $panstep, $tiltstep );
}
elsif ( $command eq "zoom_rel_tele" )
{
	zoomTele( $step );
}
elsif ( $command eq "zoom_rel_wide" )
{
	zoomWide( $step );
}
elsif ( $command eq "focus_rel_near" )
{
	focusNear( $step );
}
elsif ( $command eq "focus_rel_far" )
{
	focusFar( $step );
}
elsif ( $command eq "focus_auto" )
{
	focusAuto();
}
elsif ( $command eq "focus_man" )
{
	focusMan();
}
elsif ( $command eq "iris_rel_open" )
{
	irisOpen( $step );
}
elsif ( $command eq "iris_rel_close" )
{
	irisClose( $step );
}
elsif ( $command eq "iris_auto" )
{
	irisAuto();
}
elsif ( $command eq "iris_man" )
{
	irisMan();
}
elsif ( $command eq "preset_home" )
{
	presetHome();
}
elsif ( $command eq "preset_set" )
{
	presetSet( $preset );
}
elsif ( $command eq "preset_goto" )
{
	presetGoto( $preset );
}
else
{
	print( "Error, can't handle command $command\n" );
}
hope this helps someone!

Scott
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

Thanks very much for this, I will add it to the next version.
Phil
dashnak
Posts: 15
Joined: Tue Aug 12, 2008 10:55 pm

Post by dashnak »

Is this control script already in 1.23? I am unable to find it, and can't make it work with the methods described here.
User avatar
caladeira
Posts: 64
Joined: Wed Dec 05, 2007 10:57 am
Location: Lisbon

Post by caladeira »

Hello!

I'm running ZM version 1.23.3.

Another thing that I can't find is the "Command" under control capabilities.
Is is the "Protocol"?

Thanks for any help.
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post by cordel »

See the post here.
I'm just getting ready to convert this, but like I stated before I can make no promises and i will not be able to include any functionality that is not already available in the original script.
bogeyd6
Posts: 1
Joined: Mon Jul 05, 2010 1:06 pm

Post by bogeyd6 »

There is almost no way to make the DCS-6620 work on the newest Ubuntu 10.04. There are several perl problems and Zoneminder changed the architecture so following the above is not going to work. If you try to use Ubuntu 10.04 just for recording and then make some crontab scripts to make the camera follow a path you are going to run into several problems with Zoneminder randomly turning the picture black and failing the recording.

This script below is the correct script for zoom and moving the DCS-6620 camera on Zoneminder 1.22.3. This is the most up to date version of zone minder on Ubuntu 8.04.4. Just follow the setup in the first post and create this file in /usr/bin. You will need to chmod +x the file as well for it to execute.

Code: Select all

#!/usr/bin/perl -wT
#
# ==========================================================================
#
# ZoneMinder DCS-6620 Control Script, $Date: 2005/10/17 16:30:49 $, $Revision: 1.4 $
# Copyright (C) 2003, 2004, 2005  Philip Coombes
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ==========================================================================
#
# This script continuously monitors the recorded events for the given
# monitor and applies any filters which would delete and/or upload
# matching events
#
use strict;

# ==========================================================================
#
# These are the elements you need to edit to suit your installation
#
# ==========================================================================
use constant ZM_CONFIG => "/etc/zm/zm.conf";   # Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
use constant ZM_VERSION => "1.21.4";   # ZoneMinder version number, autogenerated do not change (from zmconfig)
use constant ZM_PATH_BIN => "/usr/bin";   # Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)

# Load the config from the database into the symbol table
BEGIN
{
   no strict 'refs';

   open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
   foreach my $str ( <CONFIG> )
   {
      next if ( $str =~ /^\s*$/ );
      next if ( $str =~ /^\s*#/ );
      my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*([^=\s]+)\s*$/;
      $name =~ tr/a-z/A-Z/;
      if (( $name eq 'ZM_DB_HOST' ) ||
         ( $name eq 'ZM_DB_NAME' ) ||
         ( $name eq 'ZM_DB_USER' ) ||
         ( $name eq 'ZM_DB_PASS' ))
      {
         *{$name} = sub { $value };
      }
   }
   close( CONFIG );

   use DBI;
   my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_HOST, &ZM_DB_USER, &ZM_DB_PASS );
   my $sql = "select * from Config";
   my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
   my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
   while( my $config = $sth->fetchrow_hashref() )
   {
      *{$config->{Name}} = sub { $config->{Value} };
   }
   $sth->finish();
   $dbh->disconnect();
}

use Getopt::Long;
use Device::SerialPort;

use constant LOG_FILE => ZM_PATH_LOGS.'/zmcontrol-6620g.log';

$| = 1;

$ENV{PATH}  = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

sub Usage
{
   print( "
Usage: zmcontrol-6620g.pl <various>
");
   exit( -1 );
}

my $arg_string = join( " ", @ARGV );

my $address;
my $command;
my ( $speed, $step );
my ( $xcoord, $ycoord );
my ( $width, $height );
my ( $panspeed, $tiltspeed );
my ( $panstep, $tiltstep );
my $preset;

if ( !GetOptions(
   'address=s'=>\$address,
   'command=s'=>\$command,
   'speed=i'=>\$speed,
   'step=i'=>\$step,
   'xcoord=i'=>\$xcoord,
   'ycoord=i'=>\$ycoord,
   'width=i'=>\$width,
   'height=i'=>\$height,
   'panspeed=i'=>\$panspeed,
   'tiltspeed=i'=>\$tiltspeed,
   'panstep=i'=>\$panstep,
   'tiltstep=i'=>\$tiltstep,
   'preset=i'=>\$preset
   )
)
{
   Usage();
}

if ( !$address )
{
   Usage();
}

my $log_file = LOG_FILE;
open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
select( STDOUT ); $| = 1;
open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
select( STDERR ); $| = 1;
select( LOG ); $| = 1;

print( $arg_string."\n" );

srand( time() );

sub printMsg
{
   my $msg = shift;
   my $msg_len = length($msg);

   print( $msg );
   print( "[".$msg_len."]\n" );
}

sub sendCmd
{
   my $cmd = shift;

   my $result = undef;

   printMsg( $cmd, "Tx" );

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

   #print( "http://$address/$cmd\n" );
   my $req = HTTP::Request->new( GET=>"http://$address/$cmd" );
   my $res = $ua->request($req);

   if ( $res->is_success )
   {
      $result = !undef;
   }
   else
   {
      print( "Error check failed: '".$res->status_line()."'\n" );
   }

   return( $result );
}

sub cameraReset
{
   print( "Camera Reset\n" );
   my $cmd = "nphRestart?PAGE=Restart&Restart=OK";
   sendCmd( $cmd );
}

sub moveUp
{
   print( "Move Up\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=up";
   sendCmd( $cmd );
}

sub moveDown
{
   print( "Move Down\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=down";
   sendCmd( $cmd );
}

sub moveLeft
{
   print( "Move Left\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=left";
   sendCmd( $cmd );
}

sub moveRight
{
   print( "Move Right\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=right";
   sendCmd( $cmd );
}

sub moveUpRight
{
   print( "Move Up/Right\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=upright";
   sendCmd( $cmd );
}

sub moveUpLeft
{
   print( "Move Up/Left\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=upleft";
   sendCmd( $cmd );
}

sub moveDownRight
{
   print( "Move Down/Right\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=downright";
   sendCmd( $cmd );
}

sub moveDownLeft
{
   print( "Move Down/Left\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=downleft";
   sendCmd( $cmd );
}

sub moveMap
{
   my ( $xcoord, $ycoord, $width, $height ) = @_;
   print( "Move Map to $xcoord,$ycoord\n" );
   my $cmd = "cgi-bin/camctrl.cgi?center=$xcoord,$ycoord&imagewidth=$width&imageheight=$height";
   sendCmd( $cmd );
}

sub stepUp
{
   my $step = shift;
   print( "Step Up $step\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rtilt=$step";
   sendCmd( $cmd );
}

sub stepDown
{
   my $step = shift;
   print( "Step Down $step\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rtilt=-$step";
   sendCmd( $cmd );
}

sub stepLeft
{
   my $step = shift;
   print( "Step Left $step\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=-$step";
   sendCmd( $cmd );
}

sub stepRight
{
   my $step = shift;
   print( "Step Right $step\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=$step";
   sendCmd( $cmd );
}

sub stepUpRight
{
   my $panstep = shift;
   my $tiltstep = shift;
   print( "Step Up/Right $tiltstep/$panstep\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=$panstep&rtilt=$tiltstep";
   sendCmd( $cmd );
}

sub stepUpLeft
{
   my $panstep = shift;
   my $tiltstep = shift;
   print( "Step Up/Left $tiltstep/$panstep\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=-$panstep&rtilt=$tiltstep";
   sendCmd( $cmd );
}

sub stepDownRight
{
   my $panstep = shift;
   my $tiltstep = shift;
   print( "Step Down/Right $tiltstep/$panstep\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=$panstep&rtilt=-$tiltstep";
   sendCmd( $cmd );
}

sub stepDownLeft
{
   my $panstep = shift;
   my $tiltstep = shift;
   print( "Step Down/Left $tiltstep/$panstep\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rpan=-$panstep&rtilt=-$tiltstep";
   sendCmd( $cmd );
}

sub zoom_con_tele
{
   print( "Zoom Tele\n" );
   my $cmd = "cgi-bin/camctrl.cgi?zoom=tele";
   sendCmd( $cmd );
}

sub zoomTele
{
   print( "Zoom Tele\n" );
   my $cmd = "cgi-bin/camctrl.cgi?zoom=tele";
   sendCmd( $cmd );
}

sub zoom_con_wide
{
   print( "Zoom Tele\n" );
   my $cmd = "cgi-bin/camctrl.cgi?zoom=wide";
   sendCmd( $cmd );
}

sub zoomWide
{
   print( "Zoom Wide\n" );
   my $cmd = "cgi-bin/camctrl.cgi?zoom=wide";
   sendCmd( $cmd );
}

sub focusNear
{
   my $step = shift;
   print( "Focus Near\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rfocus=-$step";
   sendCmd( $cmd );
}

sub focusFar
{
   my $step = shift;
   print( "Focus Far\n" );
   my $cmd = "cgi-bin/camctrl.cgi?rfocus=$step";
   sendCmd( $cmd );
}

sub focusAuto
{
   print( "Focus Auto\n" );
   my $cmd = "cgi-bin/camctrl.cgi?autofocus=on";
   sendCmd( $cmd );
}

sub focusMan
{
   print( "Focus Manual\n" );
   my $cmd = "cgi-bin/camctrl.cgi?autofocus=off";
   sendCmd( $cmd );
}

sub irisOpen
{
   my $step = shift;
   print( "Iris Open\n" );
   my $cmd = "cgi-bin/camctrl.cgi?riris=$step";
   sendCmd( $cmd );
}

sub irisClose
{
   my $step = shift;
   print( "Iris Close\n" );
   my $cmd = "cgi-bin/camctrl.cgi?riris=-$step";
   sendCmd( $cmd );
}

sub irisAuto
{
   print( "Iris Auto\n" );
   my $cmd = "cgi-bin/camctrl.cgi?autoiris=on";
   sendCmd( $cmd );
}

sub irisMan
{
   print( "Iris Manual\n" );
   my $cmd = "cgi-bin/camctrl.cgi?autoiris=off";
   sendCmd( $cmd );
}

sub presetClear
{
   my $preset = shift || 1;
   print( "Clear Preset $preset\n" );
   my $cmd = "nphPresetNameCheck?Data=$preset";
   sendCmd( $cmd );
}

sub presetSet
{
   my $preset = shift || 1;
   print( "Set Preset $preset\n" );
   my $cmd = "cgi-bin/camctrl.cgi?setserverpresetno=$preset";
   sendCmd( $cmd );
}

sub presetGoto
{
   my $preset = shift || 1;
   print( "Goto Preset $preset\n" );
   my $cmd = "cgi-bin/camctrl.cgi?gotoserverpresetno=$preset";
   sendCmd( $cmd );
}

sub presetHome
{
   print( "Home Preset\n" );
   my $cmd = "cgi-bin/camctrl.cgi?move=home";
   sendCmd( $cmd );
}

if ( $command eq "move_con_up" )
{
   moveUp();
}
elsif ( $command eq "move_con_down" )
{
   moveDown();
}
elsif ( $command eq "move_con_left" )
{
   moveLeft();
}
elsif ( $command eq "move_con_right" )
{
   moveRight();
}
elsif ( $command eq "move_con_upleft" )
{
   moveUpLeft();
}
elsif ( $command eq "move_con_upright" )
{
   moveUpRight();
}
elsif ( $command eq "move_con_downleft" )
{
   moveDownLeft();
}
elsif ( $command eq "move_con_downright" )
{
   moveDownLeft();
}
elsif ( $command eq "move_map" )
{
   moveMap( $xcoord, $ycoord, $width, $height );
}
elsif ( $command eq "move_rel_up" )
{
   stepUp( $tiltstep );
}
elsif ( $command eq "move_rel_down" )
{
   stepDown( $tiltstep );
}
elsif ( $command eq "move_rel_left" )
{
   stepLeft( $panstep );
}
elsif ( $command eq "move_rel_right" )
{
   stepRight( $panstep );
}
elsif ( $command eq "move_rel_upleft" )
{
   stepUpLeft( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_upright" )
{
   stepUpRight( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_downleft" )
{
   stepDownLeft( $panstep, $tiltstep );
}
elsif ( $command eq "move_rel_downright" )
{
   stepDownRight( $panstep, $tiltstep );
}
elsif ( $command eq "zoom_con_tele" )
{
   zoomTele( $step );
}
elsif ( $command eq "zoom_rel_tele" )
{
   zoomTele( $step );
}
elsif ( $command eq "zoom_con_wide" )
{
   zoomWide( $step );
}
elsif ( $command eq "zoom_rel_wide" )
{
   zoomWide( $step );
}
elsif ( $command eq "focus_rel_near" )
{
   focusNear( $step );
}
elsif ( $command eq "focus_rel_far" )
{
   focusFar( $step );
}
elsif ( $command eq "focus_auto" )
{
   focusAuto();
}
elsif ( $command eq "focus_man" )
{
   focusMan();
}
elsif ( $command eq "iris_rel_open" )
{
   irisOpen( $step );
}
elsif ( $command eq "iris_rel_close" )
{
   irisClose( $step );
}
elsif ( $command eq "iris_auto" )
{
   irisAuto();
}
elsif ( $command eq "iris_man" )
{
   irisMan();
}
elsif ( $command eq "preset_home" )
{
   presetHome();
}
elsif ( $command eq "preset_set" )
{
   presetSet( $preset );
}
elsif ( $command eq "preset_goto" )
{
   presetGoto( $preset );
}
else
{
   print( "Error, can't handle command $command\n" );
} 

Post Reply