Page 1 of 1

Foscam Ip Camera PTZ Control

Posted: Sat Apr 18, 2009 8:14 am
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...

Foscam.pm

Posted: Wed May 13, 2009 3:16 am
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â€

Posted: Tue Aug 18, 2009 9:10 pm
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 ...