Foscam Ip Camera PTZ Control

Post here to ask any questions about hardware suitability, configuration in ZoneMinder, or experiences. If you just want to know if something works with ZoneMinder or not, please check the Hardware Compatibility sections in the forum, and the Wiki first. Also search this topic as well.
Post Reply
ronluna
Posts: 8
Joined: Wed Apr 30, 2008 5:27 pm

Foscam Ip Camera PTZ Control

Post by ronluna »

I'm looking for the PTZ commands for the "Foscam FI8908 / FI8908W Ip Camera" is anybody around here have been able to gain PTZ control over this camera please share that info...

I'm currently able to see the image feed but no luck on the PTZ... any help would greatly appreciated...
ronluna
Posts: 8
Joined: Wed Apr 30, 2008 5:27 pm

Foscam.pm

Post by ronluna »

I was able to get some codes for Foscam IP FI8908W and based on the other pm's that zoneminder comes with this is the result

I'm not a perl guru but at least I got it to pan/tilt and center with Zoneminder 1.24.1

package ZoneMinder::Control::Foscam;

use 5.006;
use strict;
use warnings;

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

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

our $VERSION = $ZoneMinder::Base::VERSION;

# ==========================================================================
#
# Foscam IP Control Protocol
#
# ==========================================================================

use ZoneMinder::Debug 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 );
bless( $self, $class );
srand( time() );
return $self;
}

our $AUTOLOAD;

sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || 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" );
}
our $stop_command;

sub open
{
my $self = shift;

$self->loadMonitor();

use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".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 $result = undef;
printMsg( $cmd, "Tx" );

my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
my $res = $self->{ua}->request($req);

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

return( $result );
}

sub reset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "reboot.cgi?user=admin&pwd=";
$self->sendCmd( $cmd );
}

sub moveConUp
{
my $self = shift;
$stop_command = "1";
Debug( "Move Up" );
my $cmd = "decoder_control.cgi?command=0&user=admin&pwd=";
$self->sendCmd( $cmd );
}

sub moveConDown
{
my $self = shift;
$stop_command = "3";
Debug( "Move Down" );
my $cmd = "decoder_control.cgi?command=2&user=admin&pwd=";
$self->sendCmd( $cmd );
}

sub moveConLeft
{
my $self = shift;
$stop_command = "5";
Debug( "Move Left" );
my $cmd = "decoder_control.cgi?command=4&user=admin&pwd=";
$self->sendCmd( $cmd );
}

sub moveConRight
{
my $self = shift;
$stop_command = "7";
Debug( "Move Right" );
my $cmd = "decoder_control.cgi?command=6&user=admin&pwd=";
$self->sendCmd( $cmd );
}


sub moveStop
{
my $self = shift;
Debug( "Move Stop" );
my $cmd = "decoder_control.cgi?user=admin&pwd=&command=$stop_command";
$self->sendCmd( $cmd );
}



sub whiteConIn
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "White In $step" );
my $cmd = "/camera_control.cgi?2=$step";
$self->sendCmd( $cmd );
}

sub whiteConOut
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "White Out $step" );
my $cmd = "/camera_control.cgi?2=-$step";
$self->sendCmd( $cmd );
}

sub presetClear
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Clear Preset $preset" );
my $cmd = "nphPresetNameCheck?Data=$preset";
$self->sendCmd( $cmd );
}

sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "nphPresetNameCheck?PresetName=$preset&Data=$preset";
$self->sendCmd( $cmd );
}

sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "nphControlCamera?Direction=Preset&PresetOperation=Move&Data=$preset";
$self->sendCmd( $cmd );
}

sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "decoder_control.cgi?command=25&user=admin&pwd=";
$self->sendCmd( $cmd );
}

1;


if someone want to help finishing this script for full control.... this are the commands:

snapshot.cgi
description To obtain the snapshot
Permission visitor
Syntax /snapshot.cgi[?user=&pwd=&next_url=]
Parameters user:username
pwd:password
next_url:the name of snapshot
Note 1 If not use the parameter “next_urlâ€
e_lm_70
Posts: 1
Joined: Tue Aug 18, 2009 8:59 pm

Post by e_lm_70 »

Thanks ronluna,

Here is the "full" list of code after upgrade the FW: 2.4.8.11

var PTZ_STOP = 1;
var TILT_UP = 0;
var TILT_DOWN = 2;
var PAN_LEFT = 4;
var PAN_RIGHT = 6;
var PTZ_LEFT_UP = 90;
var PTZ_RIGHT_UP = 91;
var PTZ_LEFT_DOWN = 92;
var PTZ_RIGHT_DOWN = 93;
var PTZ_CENTER = 25;
var PTZ_VPATROL = 26;
var PTZ_VPATROL_STOP = 27;
var PTZ_HPATROL = 28;
var PTZ_HPATROL_STOP = 29;
var IO_ON = 94;
var IO_OFF = 95;

So, actually, stop is always 1 ... maybe there is back compatibility with previous stops code.

What is new is move up&left, down&right, etc

A easy way to make some easy reverse enginering, is just have a look of the new FW for the GUI :wink:

Tchuss

e_lm_70

ps: In my opinion the security of this and all the IP-WEB cam are too poor ... I made with TomCat a HTTP wrap up of my home cam ... based on Ubuntu over Acer One ... now I'm sure nobody can spy my home.

user name and password in clear form, not in HTTPS, is trivial to break in .. just a sniffer and you lost your privacy ...
Post Reply