Foscam FI8918W script with presets and IR control

If you've made a patch to quick fix a bug or to add a new feature not yet in the main tree then post it here so others can try it out.
hdurdle
Posts: 1
Joined: Sat Feb 26, 2011 11:06 pm

Foscam FI8918W script with presets and IR control

Post by hdurdle »

Hi all,

I've updated the existing Foscam Control Module to work properly with the Foscam FI8918W.

In the existing module horizontal panning appeared reversed so I've fixed that and added the ability to set and move to presets and turn the IR LEDs on and off (using the wake and sleep buttons). I also put the username and password in the Control Device field so it doesn't have to be hardcoded in the script. (See my site for information on configuring this.)

Wiki Page: http://www.zoneminder.com/wiki/index.php/Foscam_FI8918W

More information at my site: http://durdl.es/x

Hope this is useful to others.

Howard
newvisionantenna
Posts: 381
Joined: Sat Jan 17, 2009 7:49 pm
Location: Germany

Post by newvisionantenna »

Seems to work just fine. I tried it out on three cameras and decided to just put together an installable DVD with the files and examples included. Thanks for providing this code.
DREMA
Posts: 162
Joined: Fri Dec 12, 2008 2:39 am
Location: México

Post by DREMA »

Awesome! I'll try these on some Foscam clones I have installed.
Thanks a lot.
Just... enjoy life! :D
christophe_y2k
Posts: 102
Joined: Mon Oct 12, 2009 8:47 am
Location: EUROPE-FRANCE-MANDELIEU

Re: Foscam FI8918W script with presets and IR control

Post by christophe_y2k »

Hello and thanks you for the script
Have this cam since a couple of days with no PT success (zm v1.24.3 SVN 3312)

when i try to move cam have this popup
Control response was status = undefined
message = /usr/bin/zmcontrol.pl --autostop --command=moveConUp --id=3=>
with this zmcontrol.log

08/05/2011 00:29:07.134598 zmcontrol[17606].INF [Starting control server 3/Foscam]
08/05/2011 00:29:07.136469 zmcontrol[17609].INF [Control server 3/Foscam starting at 11/05/08 00:29:07]
08/05/2011 00:29:17.137647 zmcontrol[17606].FAT [Can't connect: Connexion refusée]

Have you an idea?

i try your auth. method and your pm script and the classic method user:password@ip with standard foscam.pm script
with no result
christophe_y2k
Posts: 102
Joined: Mon Oct 12, 2009 8:47 am
Location: EUROPE-FRANCE-MANDELIEU

Re: Foscam FI8918W script with presets and IR control

Post by christophe_y2k »

ok with the help of "ris2t" in this forum i can found the probleme and resolve it
Now my Foscam move...
Slite
Posts: 1
Joined: Thu Aug 18, 2011 9:09 am

Re: Foscam FI8918W script with presets and IR control

Post by Slite »

Could you please post HOW you solved it... seems I have the exact same issue with my Foscam F18918W.
christophe_y2k
Posts: 102
Joined: Mon Oct 12, 2009 8:47 am
Location: EUROPE-FRANCE-MANDELIEU

Re: Foscam FI8918W script with presets and IR control

Post by christophe_y2k »

(updated 11/SEPTEMBRE/2011)

Hello i send my working config with this FOSCAM FI8918W cam
"Wake" for IR LED ON
"Sleep' for IR LED OFF
And Auto stop after one click on LEFT RIGHT UP DOWN .... (Do not auto stop with diagonaly)
(with one arrow click LEFT RIGHT etc... the speed and distance can be modified with camera http interface)

Foscam.pm
file placed in: /usr/lib/perl5/site_perl/5.12.3/ZoneMinder/Control
With my gentoo64 config and user/group is apache

My camera config:
Remote Protocol= HTTP
Remote Method=Simple
Remote Host Name=192.168.1.123
Remote Host Port=80
Remote Host Path=/videostream.cgi?user=admin&pwd=MyVerySecretPassword
Remote Image Colours= 24bit
Larg. capture (pixels)=640
Haut. capture (pixels)=480

My camera control config:
Controllable = yes
Control Type=Foscam
Control Device=user=admin&pwd=MyVerySecretPassword
Control Address=192.168.123
Auto Stop Timeout=0.00
Track Motion = [x]
Track Delay =0
Return Location=None
Return Delay=0




Code: Select all


# =Name of this File : Foscam.pm =================================================================
#
# ZoneMinder Foscam FI8918W IP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0001 $
# Copyright (C) 2001-2008 Philip Coombes
# Modified for use with Foscam FI8918W IP Camera by Dave Harris
# Modified Feb 2011 by Howard Durdle (http://durdl.es/x) to:
#      fix horizontal panning, add presets and IR on/off
#      use Control Device field to pass username and password
#
# Modified 10 May 2011 By Christophe DAPREMONT (Christophe_y2k):
# 	Add auto stop after one UP DOWN LEFT RIGHT click (Do not work with diagonaly)
#
# 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 module contains the implementation of the Foscam FI8918W IP camera control
# protocol
#
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 FI8918W IP Control Protocol
#
# ==========================================================================
 
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 );
	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" );
}
 
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 );
}
 
sub cameraReset
{
	my $self = shift;
	Debug( "Camera Reset" );
	my $cmd = "reboot.cgi?";
	$self->sendCmd( $cmd );
}
 
#Up Arrow
sub moveConUp
{
	my $self = shift;
	Debug( "Move Up" );
	my $cmd = "decoder_control.cgi?command=0&onestep=1&";
	$self->sendCmd( $cmd );
}
 
#Down Arrow
sub moveConDown
{
	my $self = shift;
	Debug( "Move Down" );
	my $cmd = "decoder_control.cgi?command=2&onestep=3&";
	$self->sendCmd( $cmd );
}
 
#Left Arrow
sub moveConLeft
{
	my $self = shift;
	Debug( "Move Left" );
	my $cmd = "decoder_control.cgi?command=6&onestep=7&";
	$self->sendCmd( $cmd );
}
 
#Right Arrow
sub moveConRight
{
	my $self = shift;
	Debug( "Move Right" );
	my $cmd = "decoder_control.cgi?command=4&onestep=5&";
	$self->sendCmd( $cmd );
}
 
#Diagonally Up Right Arrow
sub moveConUpRight
{
	my $self = shift;
	Debug( "Move Diagonally Up Right" );
	my $cmd = "decoder_control.cgi?command=90&onestep=1&";
	$self->sendCmd( $cmd );
	}
 
#Diagonally Down Right Arrow
sub moveConDownRight
{
	my $self = shift;
	Debug( "Move Diagonally Down Right" );
	my $cmd = "decoder_control.cgi?command=92&onestep=1&";
	$self->sendCmd( $cmd );
}
 
#Diagonally Up Left Arrow
sub moveConUpLeft
{
	my $self = shift;
	Debug( "Move Diagonally Up Left" );
	my $cmd = "decoder_control.cgi?command=91&";
	$self->sendCmd( $cmd );
}
 
#Diagonally Down Left Arrow
sub moveConDownLeft
{
	my $self = shift;
	Debug( "Move Diagonally Down Left" );
	my $cmd = "decoder_control.cgi?command=93&";
	$self->sendCmd( $cmd );
}
 
#Stop
sub moveStop
{
	my $self = shift;
	Debug( "Move Stop" );
	my $cmd = "decoder_control.cgi?command=1&";
	$self->sendCmd( $cmd );
}
 
#Move Camera to Home Position
sub presetHome
{
	my $self = shift;
	Debug( "Home Preset" );
	my $cmd = "decoder_control.cgi?command=25&";
	$self->sendCmd( $cmd );
}
 
#Set preset
sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
	my $presetCmd = 30 + ($preset*2);
    Debug( "Set Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}
 
#Goto preset
sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    my $presetCmd = 31 + ($preset*2);
    Debug( "Goto Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}
 
#Turn IR on
sub wake
{
	my $self = shift;
	Debug( "Wake - IR on" );
	my $cmd = "decoder_control.cgi?command=95&";
	$self->sendCmd( $cmd );
}
 
#Turn IR off
sub sleep
{
	my $self = shift;
	Debug( "Sleep - IR off" );
	my $cmd = "decoder_control.cgi?command=94&";
	$self->sendCmd( $cmd );
}
 
1;
__END__
# Below is stub documentation for your module. You'd better edit it!

=head1 NAME

ZoneMinder::Database - Perl extension for blah blah blah

=head1 SYNOPSIS

  use ZoneMinder::Database;
  blah blah blah

=head1 DESCRIPTION

Stub documentation for ZoneMinder, created by h2xs. It looks like the
author of the extension was negligent enough to leave the stub
unedited.

Blah blah blah.

=head2 EXPORT

None by default.



=head1 SEE ALSO

Mention other useful documentation such as the documentation of
related modules or operating system documentation (such as man pages
in UNIX), or any relevant external documentation such as RFCs or
standards.

If you have a mailing list set up for your module, mention it here.

If you have a web site set up for your module, mention it here.

=head1 AUTHOR

Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2001-2008  Philip Coombes

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.


=cut
Last edited by christophe_y2k on Sun Sep 11, 2011 9:02 am, edited 2 times in total.
gmar_87
Posts: 72
Joined: Sat Aug 13, 2011 11:38 pm
Location: Melbourne, Australia

Re: Foscam FI8918W script with presets and IR control

Post by gmar_87 »

Hi christophe_y2k,

Your script doesn't work for me :(

I get this in the logs:

Code: Select all

2011-09-10 19:26:06.049905	web_php	13314	ERR	/usr/local/bin/zmcontrol.pl --preset=1 --command=presetGoto --id=1=>	includes/functions.php	2322
2011-09-10 19:26:06.041860	zmcontrol	15926	FAT	Can't connect: No such file or directory	zmcontrol.pl
Am i supposed to modify anything in the script?

Cheers,
John
gmar_87
Posts: 72
Joined: Sat Aug 13, 2011 11:38 pm
Location: Melbourne, Australia

Re: Foscam FI8918W script with presets and IR control

Post by gmar_87 »

Got it working. Solution in this thread - http://www.zoneminder.com/forums/viewto ... 744#p71744
christophe_y2k
Posts: 102
Joined: Mon Oct 12, 2009 8:47 am
Location: EUROPE-FRANCE-MANDELIEU

Re: Foscam FI8918W script with presets and IR control

Post by christophe_y2k »

Hello
are you sure the file script is named "Foscam.pm"

and is in the good directory?

another way that work for me one day :
# perl-cleaner reallyall
that rebuild all perl module.

and if i upgrade perl, i must rebuild zm (with my gentoo)

for me the PT script for foscam works fine with zm 1.25.0 svn build 3515

-------------
sorry haven't seen before you resolved issue with "Logger" in place of "Debug" in script (since v.1.25.0)
i updated the script to later in this forum sorry
Optimist
Posts: 11
Joined: Sun Sep 11, 2011 9:17 am

Modded script with Speed Control, Full Autostop and Jog

Post by Optimist »

Good afternoon.

I've restructured these scripts and incorporated speed control, full autostop and a jog facility, plus the settings required if you ceiling mount the camera.

I've only tried it on my DB Power and Tenvis cameras which are Foscam clones, but as I started with the Foscam scripts I'm fairly certain that it will work on the Foscam.

Save this script in your normal directory for .pm files as FoscamClone.pm and set the permissions.

Goto the Control tab of your monitor setup and click the edit link next to the control type. On the window that pops up click 'Add New Control Type' - the 'Control Capability - New' Window pops up.

Main Tab
Name: Foscam Clone
Type: Remote
Protocol: FoscamClone
Check these boxes:-
Can Wake (Optional - see below)
Can Sleep (Optional - see below)
Can Reset

Move Tab
Check these boxes:-
Can Move
Can Move Diagonally
Can Move Continuous

Pan Tab
Check these boxes:-
Can Pan
Has pan Speed

Min Pan Speed: 10
Max Pan Speed: 0

Tilt Tab
Check these boxes:-
Can Tilt
Has Tilt Speed

Min Tilt Speed: 10
Max Tilt Speed: 0

Zoom Tab
Check these boxes:-
Can Zoom
Can Zoom Continuous
Has Zoom Speed (Optional - see below)
Min Zoom Speed: 10
Max Zoom Speed: 0

Iris Tab
Check these boxes:-
Can Iris
Can Iris Continuous
Has Iris Speed (Optional - see below)
Min Iris Speed: 10
Max Iris Speed: 0

Note: These cameras have neither Zoom or Iris control I'm using them as jog position controls

Presets Tab
Check these boxes:-
Has Presets
Has Home Preset
Can Set Presets

Num Presets: 16

Click the Save Button, close the Control Capabilities box then close and reopen the Monitor edit box.

Control Tab
Check box Controllable
Control Type: Foscam Clone
Control Device: user=admin&pwd= (default)
Control Address: The ip address of your cam
Auto Stop Timeout: 0.80
Note this is obviously a matter of choice, but on my system it does not like being changed. Most times I end up rebooting to make it take effect.

Misc Tab
Default View: Control (Optional)

Once it is setup, you can control the position of the monitor in the normal way, but the further from the centre that you click the arrow, the faster the camera will move and therefore the further it will move before timing out.

There is also a jog facility, if you click the horizontal or vertical arrows very close to the centre button then the camera will be jogged one step regardless of the autostop setting. It requires a steady finger on your mouse but gives good macro control and not time is wasted sending the speed and stop controls to the camera. This does not work for diagonal movement

The downside of this is that you lose some lower ranges of speed control. If you don't like it, search the script for 'jog movement' to disable or change.

Another way to jog the camera is to use the Zoom and Iris controls - I'm not sure whether this is a good idea as it is neither pretty or intuitive but it can easily be disabled by unchecking the Can Zoom and Can Iris boxes. Click on:-

Tele Zoom - to Jog Left
Wide Zoom - to Jog Right
Open Iris - to Jog Up
Close Iris - to Jog Down

If you have checked the Has Zoom Speed and Has Iris Speed boxes then the closer to the arrow tip that you click the faster the speed. This has no effect on my cameras, but it would appear from other posts that some cameras will jog faster/further with a higher speed. If it has no effect then uncheck those boxes, as sending the speed command can take significant time.

The wake and sleep controls seem to have no effect on my clone cameras, but some posters have said that they turn the IR LED's on/off so they are there if you want them.

My script uses the command value 30 to set the preset 1 position. Some scripts appear to use 32 instead which alters the position of all presets by one. Search the script for 'Code for Preset 1' to change.

The stop button still sends the stop command, but it should only be used to stop a call preset initiated move. If you use it to stop normal movement, the command will still be sent but not until after the autostop has timed out and sent the stop signal.

I've noticed some problems with excessive time for the camera to respond. This is not a fault of the script so much as my computer/network/cameras delaying the time to send and reply to commands. However, if there is poor network response then this sript makes it worse because it first sends the speed command, then the movement command and finally a stop command except for the jog mode which just sends one.

I would like to thank all those who have posted the scripts for these cameras which I was able to use as the basis of this script.

If you still want to try it, here is the code. I hope it is useful.

Code: Select all

# ==========================================================================
# 
# ZoneMinder Foscam FI8908W IP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0001 $
# Copyright (C) 2001-2008 Philip Coombes
# Modified for use with Foscam FI8908W IP Camera by Dave Harris
#
# 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 module contains the implementation of the Foscam FI8908W IP camera control
# protocol
#

# uncomment following line and comment the next one for camera mounted in normal position and see NORMAL SETTINGS below
package ZoneMinder::Control::FoscamClone;                              
#uncomment following line and comment the previous one for ceiling mounted camera
# package ZoneMinder::Control::FoscamCloneInv;

use 5.006;
use strict;
use warnings;

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

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

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

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

# uncomment following line and comment the next one if using Zoneminder prior to v1.25.0
#use ZoneMinder::Debug qw(:all);
use ZoneMinder::Logger qw(:all);

use ZoneMinder::Config qw(:all);

use Time::HiRes qw( usleep gettimeofday tv_interval );
use feature "switch";

{

# maximum and minimum speed setings 0 & 10 should be OK but they MUST match those in the ZM Control Capability panel
my $maxspd = 0 ;
my $minspd = 10 ;

# The threshold for jog movement. If you select a low speed then instead of using the low speed, the camera will be 
#moved onestep in the required direction and the autostop is not needed.
# Set to 0 to dissable this feature.
# Set to 1 or greater to enable.
# A higher setting makes it easier to select this feature but reduces the availible speed range.
my $jogthreshold = 3 ;

# Code for Preset 1. My camera uses the command value 30 to set the preset 1 position. Some scripts appear to 
# use 32 instead which alters the position of all presets by one. Set this to 32 if required 
my $prest1 = 30 ;


my %cont_str = (
# Command codes for movement


# NORMAL SETTINGS or INVERTED SETTINGS
# Comment out following entire section and uncomment all in the NVERTED SETTINGS
# if the camera is to be ceiling mounted
#  It is best to also change the line 
# package ZoneMinder::Control::FoscamClone;
# to
# package ZoneMinder::Control::FoscamCloneinverted;
# and save this file as  FoscamCloneinverted.pm ,  then you can set a control for both
# configurations at once.

# START of NORMAL SETTINGS
                  "moveConUp" => "0"  ,
                  "moveConDown" => "2"  ,
                  "moveConLeft" => "4" ,
                  "moveConRight" => "6" ,
                  
                  "moveConUpRight" => "91"  ,
                  "moveConDownRight" => "93"  ,
                  "moveConUpLeft" => "90"  ,
                  "moveConDownLeft" => "92"  ,
                  
                  "moveRelUp" => "0&onestep=1" ,
                  "moveRelDown" => "2&onestep=1" ,
                  "moveRelLeft" => "4&onestep=1" ,
                  "moveRelRight" => "6&onestep=1" ,

                  "irisConOpen" => "0&onestep=1" ,
                  "irisConClose" => "2&onestep=1" ,
                  "zoomConTele" => "4&onestep=1" ,
                  "zoomConWide" => "6&onestep=1" ,

                  "moveRelUpRight" => "91"  ,
                  "moveRelDownRight" => "93"  ,
                  "moveRelUpLeft" => "90"  ,
                  "moveRelDownLeft" => "92"  ,
# END of NORMAL SETTINGS
                  

# START of INVERTED SETTINGS
#
#                  "moveConUp" => "2"  ,
#                  "moveConDown" => "0"  ,
#                  "moveConLeft" => "6" ,
#                  "moveConRight" => "4" ,
#                  
#                  "moveConUpRight" => "92"  ,
#                  "moveConDownRight" => "90"  ,
#                  "moveConUpLeft" => "93"  ,
#                  "moveConDownLeft" => "91"  ,
#                  
#                  "moveRelUp" => "2&onestep=1" ,
#                  "moveRelDown" => "0&onestep=1" ,
#                  "moveRelLeft" => "6&onestep=1" ,
#                  "moveRelRight" => "4&onestep=1" ,
#
#                  "irisConOpen" => "2&onestep=1" ,
#                  "irisConClose" => "0&onestep=1" ,
#                  "zoomConTele" => "6&onestep=1" ,
#                  "zoomConWide" => "4&onestep=1" ,
#
#                  "moveRelUpRight" => "92"  ,
#                  "moveRelDownRight" => "90"  ,
#                  "moveRelUpLeft" => "93"  ,
#                  "moveRelDownLeft" => "91"  ,
# END of INVERTED SETTINGS
                                   
                  "moveStop" => "1"  ,
                  "presetHome" => "25" ,
                  
# Not sure about the next 2 values. Some people say that they turn the IR LED's off/on. 
# It doesn't seem to do anything on my Foscam Clone and my documentation says they set Io output high/low whatever that is.
                  "sleep" => "94" ,
                  "wake" => "95" ,
                   
               )  ;
my $enableAutostop = "0" ;

    
    
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" );
}


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
{
Debug ( "Start of sub sendCmd")  ;
my $self = shift;
my $cmd = shift;
my $result = undef;
my $stofsendcmd = [gettimeofday]   ;

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

my ( $secstosend , $microsecstosend ) = tv_interval( $stofsendcmd ) ;
Debug ( "Command  $cmd has been sent. Time to send $secstosend sec." )  ;

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

return( $result );
}

sub reset
{
 my $self = shift;
 my $params = shift;
 Debug( "Camera Reset" );
 my $cmd = "reboot.cgi?";
 $self->sendCmd( $cmd );
}
sub setSpeed
{
     my $self = shift;
     my $params = shift;
     my $ctl = $self->getParam( $params, 'command' ) ;
     my $speed = "-1" ;
     my $newmov = $ctl ;
     
    #set pan/tilt speed
    Debug( "Start setSpeed sub" ) ;
    given ( $ctl )
    {
        when ( "moveConRight"  )
            {
                $speed = $self->getParam( $params, "panspeed" ,  -1 );

                if ( $speed > ( $minspd - $jogthreshold ) )
                    {
                          $newmov =  "moveRelRight"  ;
                          $speed = "-1" ;
                          $enableAutostop = "0" ;
                    }    

            }
            
        when ( "moveRelRight" )
            {
                $speed = $self->getParam( $params, "panspeed" ,  -1 );
            }
            
        when ( "moveConLeft"  )  
             {
                my $ps = $self->getParam( $params, "panspeed" ,  -1 );
                if ( $ps >= "0" )
                    {
                        # ZM V1.25.0  reverses the fast/slow speed range for this arrow - this works round it
                        # if it is corrected then this line should be changed to  $speed =  $ps ;
                        $speed = $maxspd - $ps  + $minspd ;
                    }
                if ( $speed > ( $minspd - $jogthreshold ) )
                    {
                          $newmov =  "moveRelLeft"  ;
                          $speed = "-1" ;
                          $enableAutostop = "0" ;
                    }    
             }
    
        when (  "moveRelLeft"  )  
             {
                my $ps = $self->getParam( $params, "panspeed" ,  -1 );
                if ( $ps >= "0" )
                    {
                        # ZM V1.25.0  reverses the fast/slow speed range for this arrow - this works round it
                        # if it is corrected then this line should be changed to  $speed =  $ps ;
                        $speed = $maxspd - $ps  + $minspd ;
                    }
             }
    
        when ( [ "moveRelUp" , "moveRelDown" ] )
            {
                $speed = $self->getParam( $params, "tiltspeed" ,  -1 );
            }
    
        when (  "moveConUp"  )
            {
                $speed = $self->getParam( $params, "tiltspeed" ,  -1 );

                if ( $speed > ( $minspd - $jogthreshold ) )
                    {
                          $newmov =  "moveRelUp"  ;
                          $speed = "-1" ;
                          $enableAutostop = "0" ;
                    }    
            }
    
        when ( "moveConDown"  )
            {
                $speed = $self->getParam( $params, "tiltspeed" ,  -1 );

                if ( $speed > ( $minspd - $jogthreshold ) )
                    {
                          $newmov =  "moveRelDown"  ;
                          $speed = "-1" ;
                          $enableAutostop = "0" ;
                    }    
            }
    
        when ( [ "moveConUpRight" ,"moveConDownRight" , "moveConUpLeft" , "moveConDownLeft" ,  "moveRelUpRight" ,
                  "moveRelDownRight" , "moveRelUpLeft" , "moveRelDownLeft" ] )
            {
                my $ts = $self->getParam( $params, "tiltspeed" ,  -1 );
                my $ps  = $self->getParam( $params, "tiltspeed" ,  -1 );
                
                if ( $ps >= "0" )
                    {
                        $speed = int(( $ps + $ts ) / 2 ) ;
                    }
            }
            
        when ( [ "zoomConTele" , "zoomConWide" , "irisConOpen" , "irisConClose" ] )
            {
                $speed = $self->getParam( $params, "speed" ,  -1 );
            }
    
    }

    
    
    if ( $speed  >= "0" )
    
      {
        my $cmd = "set_misc.cgi?ptz_patrol_rate=$speed&";
        Debug( "Ready to Send set speed command - $cmd to sub sendCmd" ) ;
        $self->sendCmd( $cmd );
      }
      else
      {
      Debug( "No speed to set") ;
      }
      
      return $newmov ;
}

sub proAutostop
{
      my $self = shift;
      Debug( "Start Autostop" ) ;
      my $asTimeOut =   $self->{Monitor}->{AutoStopTimeout} ;
      Debug( " Autostop- $asTimeOut" ) ;
              
      if( $asTimeOut > 0 ) 
          {
              Debug( "Autostop start timing - $asTimeOut" ) ;
              
              usleep( $asTimeOut );
              Debug( "Autostop timed out" ) ;
              my $c_str = $cont_str{"moveStop"}   ;
              $self->sendCmd( "decoder_control.cgi?command=$c_str&" ) ;
          }  
      else
          {
              Debug( "Autostop Skipped") ;
          }
           
      Debug( "End of Autostop" ) ;

}

sub getCmd
{
 my $self = shift;
 my $params = shift;
 my $mov = $self->setSpeed  ( $params  )  ;

# Debug( "Process Move Command = $mov" ) ;
 given ( $mov )
    {
        when ( "moveConRight" )
            {
               #Right Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Right - comand = $mov" );
            }
            
        when ( "moveConLeft" )
             {
                #Left Arrow Continuous
                $enableAutostop = "1" ;
                Debug( "Move Left - comand = $mov" );
             }
    
        when ( "moveConUp" )
            {
               #Up Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Up - comand = $mov" );
            }
    
        when ( "moveConDown" )
            {
               #Down Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Down - comand = $mov" );
            }
        
        when ( "moveConUpRight" )
            {
               #Diagonally Up Right Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Up Right - comand = $mov" );
            }
            
        when ( "moveConDownRight" )
            {
               #Diagonally Down Right Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Down Right - comand = $mov" );
            }
            
        when ( "moveConUpLeft" )
            {
               #Diagonally Up Left Arrow Continuous
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Up Left - comand = $mov" );
            }
            
        when ( "moveConDownLeft" )
            {
                #Diagonally Down Left Arrow Continuous
                $enableAutostop = "1" ;
                Debug( "Move Diagonally Down Left - comand = $mov" );
            }
            
        when ( "moveRelRight" )
            {
               #Right Arrow Relative
               Debug( "Move Right - comand = $mov" );
            }
            
        when ( "moveRelLeft" )
             {
                #Left Arrow Relative
                Debug( "Move Left - comand = $mov" );
             }
    
        when ( "moveRelUp" )
            {
               #Up Arrow Relative
               Debug( "Move Up - comand = $mov" );
            }
    
        when ( "moveRelDown" )
            {
               #Down Arrow Relative
               Debug( "Move Down - comand = $mov" );
            }
        
        when ( "moveRelUpRight" )
            {
               #Diagonally Up Right Arrow Relative
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Up Right - comand = $mov" );
            }
            
        when ( "moveRelDownRight" )
            {
               #Diagonally Down Right Arrow Relative
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Down Right - comand = $mov" );
            }
            
        when ( "moveRelUpLeft" )
            {
               #Diagonally Up Left Arrow Relative
               $enableAutostop = "1" ;
               Debug( "Move Diagonally Up Left - comand = $mov" );
            }
            
        when ( "moveRelDownLeft" )
            {
                #Diagonally Down Left Arrow Relative
                $enableAutostop = "1" ;
                Debug( "Move Diagonally Down Left - comand = $mov" );
            }

        when ( "moveStop" )
            {
                #Stop
                $enableAutostop = "0" ;
                Debug( "Move Stop - comand = $mov" );
            }

        when ( "presetHome" )
            {
                #Move Camera to Home Position
                Debug( "Home Preset - comand = $mov" );
            }

        when ( "sleep" )
            {
                #Turn IR off
                Debug( " - comand = $mov" );
            }

        when ( "wake" )
            {
                #Turn IR on
                Debug( "Wake - comand = $mov" );
            }

        when ( "irisConOpen" )
            {
                #Onestep Up
                Debug( "Onestep Up - comand = $mov" );
            }

        when ( "irisConClose" )
            {
                #Onestep Down
                Debug( "Onestep Down - comand = $mov" );
            }

        when ( "zoomConTele" )
            {
                #Onestep Left
                Debug( "Onestep Left - comand = $mov" );
            }

        when ( "zoomConWide" )
            {
                #Onestep Right
                Debug( "Onestep Right - comand = $mov" );
            }

}



#Send Movement command 
my $c_str = $cont_str{$mov}   ;
my $cmd = "decoder_control.cgi?command=$c_str&";


Debug( "Send Mov cmd $cmd" ) ;
$self->sendCmd( $cmd );
 
 if ( $enableAutostop )
     {
        $self->proAutostop ;
     }
          
}

#Up Arrow Relative
sub moveRelUp
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Up Arrow Continuous
sub moveConUp
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}


#Down Arrow Relative
sub moveRelDown
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Down Arrow Continuous
sub moveConDown
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}


#Left Arrow Relative
sub moveRelLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}


#Left Arrow Continuous
sub moveConLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}


#Right Arrow Relative
sub moveRelRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Right Arrow Continuous
sub moveConRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Up Right Arrow Relative 
sub moveRelUpRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Up Right Arrow Continuous
sub moveConUpRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Down Right Arrow Relative 
sub moveRelDownRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Down Right Arrow Continuous
sub moveConDownRight
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Up Left Arrow Relative 
sub moveRelUpLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}
 
#Diagonally Up Left Arrow Continuous
sub moveConUpLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Down Left Arrow Relative 
sub moveRelDownLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Diagonally Down Left Arrow Continuous
sub moveConDownLeft
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Stop
sub moveStop
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Move Camera to Home Position
sub presetHome
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Turn IR off
sub sleep
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Turn IR on
sub wake
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Onestep Left
sub zoomConTele
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Onestep Right
sub zoomConWide
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Onestep Up
sub irisConOpen
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

#Onestep Down
sub irisConClose
{
my $self = shift;
my $params = shift;
$self->getCmd ($params  ) ;
}

# Set the preset to the current camera position
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
# the first preset is command value 30/31. Some scripts are using 32/33 as preset 1
#ammend value of $prest1 at start to change
my $presetCmd  = ( $preset * 2) + $prest1 -2 ;

Debug( "Set Preset $preset" );

my $cmd = "decoder_control.cgi?command=$presetCmd&";
$self->sendCmd( $cmd );
}

#Move Camera to Preset Position
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
# the first preset is command value 30/31. Some scripts are using 32/33 as preset 1
#ammend value of $prest1 at start to change
my    $presetCmd  = ( $preset * 2) + $prest1 -1 ;

Debug( "Goto Preset No $preset" );
my $cmd = "decoder_control.cgi?command=$presetCmd&";
$self->sendCmd( $cmd );
}


}
1;



Last edited by Optimist on Fri Oct 07, 2011 7:32 pm, edited 1 time in total.
christophe_y2k
Posts: 102
Joined: Mon Oct 12, 2009 8:47 am
Location: EUROPE-FRANCE-MANDELIEU

Re: Foscam FI8918W script with presets and IR control

Post by christophe_y2k »

Hello, i try to use rapidlly your script but it dosen't work on my FOSCAM FI8918W
Are you sure is usable for this model ?
Optimist
Posts: 11
Joined: Sun Sep 11, 2011 9:17 am

Re: Foscam FI8918W script with presets and IR control

Post by Optimist »

As I mentioned in my post, I have not tested it on the Foscam camera but can't see any reason why it would not work. My script is based on the others that have been posted on this thread, and I have not changed any command codes except for the preset 1 that I mentioned.

In order to troubleshoot your system, can you tell me what happens when you use it. If you click on a preset call (2 or greater) or the stop button, do you get an error message pop up on the control window after a few seconds? If you do, it shows that the script has not compiled properly or could not be found.

Edit

I have just found that in the instructions above, I had not mentioned the protocol entry in the Main Tab of the Control Capability box. Unless you had spoted that, it would certainly stop it working.

The Protocol box should be FoscamClone

Sorry if I have caused you problems - I've edited the original post.
TylerSchwend
Posts: 22
Joined: Sat Nov 05, 2011 11:03 pm

Re: Foscam FI8918W script with presets and IR control

Post by TylerSchwend »

Optimist,

Have you considered making the "Iris" commands control the brightness of the camera?

I'd love to give your script a try on my Foscam, but for some reason my latest upgrade has resulted in none of the control scripts even appearing to run... Even manually with zmcontrol. I'm poking around the forum trying to find a resolution to that... If I can fix that, I'll update the Foscam 8918 wiki with your script and post here.
Optimist
Posts: 11
Joined: Sun Sep 11, 2011 9:17 am

Re: Foscam FI8918W script with presets and IR control

Post by Optimist »

TylerSchwend

Sorry for the delay in replying.

It is possible to use the Iris control to control brightness, but I'm not sure how effective it would be.

It is easy enough to change my Up/Down control to use the Focus and leave the Iris free, but the problem is that the Foscam uses a brightness value between 0 and 255, but the ZM control GUI will only detect a limited number of steps. You would have a down arrow that gave you around 10 absolute values between 0 and 127 and another 10 steps on the up arrow between 128 and 255.

The best work around would be to change the Control GUI and script to provide a slider control. Unfortunately, I've no idea how to do this.

The other way, would be to query the camera to get the brightness value and then change it by in small amounts. If anyone can post a subroutine to read this value then I will incorporate it into my script.

I'll try to get a modified script out during the next week, but as I said, I have my doubts about how practical it will be.

Have you resolved your problems with the control scripts not running? If so, please post how you solved it.

I've had my share of problems starting ZM after a computer crash and never really solved it. The problem must be something to do with Perl but that's as far as I've got. I now run it on a virtual machine on VMware ESXi which makes it easy to restore the system, but I'd prefer to find a solution.
Post Reply