I have created a control script for the Foscam FI9821W IP camera.
The script is based on the FI8918W script and has been modified to use the new CGI SDK for the FI9821W.
Working controls
Added 15/04/2013:
- Up, down, left, right & diagonal movements
- Stop movement
- Reset PTZ position (home button)
- Wake and sleep IR LEDs (wake and sleep buttons)
- Reboot camera (reset button)
Added 20/04/2013:
- Set presets
- Move to presets
Limitations:
- Preset cannot be overridden if the preset number has already been set. Preset needs to be deleted from the Foscam FI9821W camera web interface first.
Control Capability Config:
Main tab:
Name - Foscam FI9821W
Type - Remote
Protocol - FoscamFI9821W
Can Wake - ticked
Can Sleep - ticked
Can Reset - ticked
Move tab:
Can Move - ticked
Can Move Diagonally - ticked
Can Move Relative - ticked
Can Move Continuous - ticked
Pan tab:
Can Pan - ticked
Tilt tab:
Can Tilt - ticked
Presets tab:
Has Presets - ticked
Num Presets - 16
Has Home Preset - ticked
Can Set Presets - ticked
Monitor - Control tab
Controllable - ticked
Control type - Foscam FI9821W
Control device - usr=admin&pwd=password
Control address - Camera IP address
Filename = FoscamFI9821W.pm
Code: Select all
# ==========================================================================
#
# ZoneMinder Foscam FI9821W IP Control Protocol Module
#
# Created from Dave Harris Foscam FI8918W control script - Feb 2011
# Modified by John Marzella on 15/04/2013 to work with Foscam FI9821W
#
# 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.
#
# ==========================================================================
# Enter username and password in the "Control Device" field
# E.g. usr=admin&pwd=password
package ZoneMinder::Control::FoscamFI9821W;
use 5.006; use strict; use warnings;
require ZoneMinder::Base; require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# Foscam FI9821W IP Control Protocol
#
# ==========================================================================
#Commented out to work with ZoneMinder 1.25
#use ZoneMinder::Debug qw(:all); use ZoneMinder::Config qw(:all);
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($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".$self->{Monitor}->{ControlDevice} );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed:'".$res->status_line()."'" );
}
return( $result );
}
#Reboot camera
sub reset {
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=rebootSystem&";
$self->sendCmd( $cmd );
}
#Up Arrow
sub moveConUp {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Up" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveUp&";
$self->sendCmd( $cmd );
}
#Down Arrow
sub moveConDown {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Down" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveDown&";
$self->sendCmd( $cmd );
}
#Left Arrow
sub moveConLeft {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Left" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveLeft&";
$self->sendCmd( $cmd );
}
#Right Arrow
sub moveConRight {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Right" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveRight&";
$self->sendCmd( $cmd );
}
#Diagonally Up Right Arrow
sub moveConUpRight {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Diagonally Up Right" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveTopRight&";
$self->sendCmd( $cmd );
}
#Diagonally Down Right Arrow
sub moveConDownRight {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Diagonally Down Right" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveBottomRight&";
$self->sendCmd( $cmd );
}
#Diagonally Up Left Arrow
sub moveConUpLeft {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Diagonally Up Left" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveTopLeft&";
$self->sendCmd( $cmd );
}
#Diagonally Down Left Arrow
sub moveConDownLeft {
my $self = shift;
$stop_command = "ptzStopRun";
Debug( "Move Diagonally Down Left" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzMoveBottomLeft&";
$self->sendCmd( $cmd );
}
#Stop
sub moveStop {
my $self = shift;
Debug( "Move Stop" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzStopRun&";
$self->sendCmd( $cmd );
}
#Move Camera to Home Position
sub presetHome {
my $self = shift;
Debug( "Home Preset" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzReset&";
$self->sendCmd( $cmd );
}
#Set preset
# Basic preset functionality
# Uses zoneminder preset number as preset name in Foscam FI9821W.
# If preset name already exists it will not override... Old preset needs to be removed from Foscam FI9821W web interface first!
sub presetSet {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzAddPresetPoint&name=$preset&";
$self->sendCmd( $cmd );
}
#Goto preset
# Goes to present name that matches zoneminder preset number
sub presetGoto {
my $self = shift;
my $params = shift;
$stop_command = "ptzStopRun";
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=ptzGotoPresetPoint&name=$preset&";
$self->sendCmd( $cmd );
}
#Turn IR on
sub wake {
my $self = shift;
Debug( "Wake - IR on" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=openInfraLed&";
$self->sendCmd( $cmd );
}
#Turn IR off
sub sleep {
my $self = shift;
Debug( "Sleep - IR off" );
my $cmd = "cgi-bin/CGIProxy.fcgi?cmd=closeInfraLed&";
$self->sendCmd( $cmd );
}
1;
John