Important Message from Foscam Digital Technologies Regarding US Sales & Service

Foscam.US (aka Foscam Digital Technologies and now Amcrest Technologies) is an independent United States based distributor of "Foscam" branded products. We have been offering telephone support, US local warranty and building the Foscam brand in the US for the past 7 years. Based on our experiences with Foscam and feedback from end users we have launched our own new and improved line of wireless IP cameras and security systems under the Amcrest brand. Working in partnership with the second largest security camera manufacturer in the world, Amcrest was founded with a deep commitment to end-user privacy and security, highly reliable software and hardware as well a seamless and intuitive user experience. For more information, please visit www.Amcrest.com

If you are having trouble with your Foscam cameras, we sincerely apologize for this inconvenience and would love to help. For technical support, response to inquiries and for obtaining replacements for any Foscam IP Cameras or NVR products, please reach out to tech@foscam.com or call 1-844-344-1113.

If you are interested in exchanging your Foscam camera for an Amcrest camera, we can offer you a massive loyalty discount, even if you are out of warranty. Please send an email to support@amcrest.com, sales@amcrest.com or call 1-888-212-7538

If you are subscribed to Foscam Cloud (www.foscamcloud.com), please contact cloud@foscam.us for support.

If you currently use the manufacturer's cloud service (www.myfoscam.com or linked in any way to www.foscam.com), you will need to contact them directly for support, at www.myfoscam.com.


ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Users can ask and answer questions regarding Foscam IP Cameras

Moderators: mycam, FOSCAM

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby alfa24t » Sun Mar 16, 2014 8:02 pm

Hi, having the same problem and solved by

- make slink to /usr/share/perl/5.14.2/ZoneMinder in /usr/share/perl5

- make .pm file executable

- use this script (and my cam don't use 80 port, I juste put the port after ip)

Code: Select all
# ==========================================================================
#
# 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
#
# 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::FoscamFI8918W;

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 );
        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->{ua}->agent( "ZoneMinder Control Agent/");

        $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 reset
{
        my $self = shift;
        Debug( "Camera Reset" );
        my $cmd = "reboot.cgi?";
        $self->sendCmd( $cmd );
}

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

#Down Arrow
sub moveConDown
{
        my $self = shift;
        $stop_command = "1";
        Debug( "Move Down" );
        my $cmd = "decoder_control.cgi?command=2&onestep=1&";
        $self->sendCmd( $cmd );
}

#Left Arrow
sub moveConLeft
{
        my $self = shift;
        $stop_command = "1";
        Debug( "Move Left" );
        my $cmd = "decoder_control.cgi?command=6&onestep=1&";
        $self->sendCmd( $cmd );
}

#Left Arrow
sub moveConLeft
{
        my $self = shift;
        $stop_command = "1";
        Debug( "Move Left" );
        my $cmd = "decoder_control.cgi?command=6&onestep=1&";
        $self->sendCmd( $cmd );
}

#Right Arrow
sub moveConRight
{
        my $self = shift;
        $stop_command = "1";
        Debug( "Move Right" );
        my $cmd = "decoder_control.cgi?command=4&onestep=1&";
        $self->sendCmd( $cmd );
}

#Diagonally Up Right Arrow
sub moveConUpRight
{
        my $self = shift;
        $stop_command = "1";
        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;
        $stop_command = "1";
        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;
        $stop_command = "1";
        Debug( "Move Diagonally Up Left" );
        my $cmd = "decoder_control.cgi?command=91&onestep=1&";
        $self->sendCmd( $cmd );
}

#Diagonally Down Left Arrow
sub moveConDownLeft
{
        my $self = shift;
        $stop_command = "1";
        Debug( "Move Diagonally Down Left" );
        my $cmd = "decoder_control.cgi?command=93&onestep=1&";
        $self->sendCmd( $cmd );
}

#Stop
sub moveStop
{
        my $self = shift;
        Debug( "Move Stop" );
        my $cmd = "decoder_control.cgi?command=1&onestep=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;
    $stop_command = "1";
    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 );
}

#Horizontal Patrol
sub horizontalPatrol
{
    my $self = shift;
    Debug( "Horizontal Patrol" );
    my $cmd = "decoder_control.cgi?command=28";
    $self->sendCmd( $cmd );
}

#Horizontal Patrol Stop
sub horizontalPatrolStop
{
    my $self = shift;
    Debug( "Horizontal Patrol Stop" );
    my $cmd = "decoder_control.cgi?command=29";
    $self->sendCmd( $cmd );
}

#Vertical Patrol
sub verticalPatrol
{
    my $self = shift;
    Debug( "Vertical Patrol" );
    my $cmd = "decoder_control.cgi?command=26";
    $self->sendCmd( $cmd );
}

#Vertical Patrol Stop
sub verticalPatrolStop
{
    my $self = shift;
    Debug( "Vertical Patrol Stop" );
    my $cmd = "decoder_control.cgi?command=27";
    $self->sendCmd( $cmd );
}

1;


Hope it can help you It work with 1.25 and 1.26.5 for me, just use $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); for 1.25 and $self->{ua}->agent( "ZoneMinder Control Agent/"); for 1.26.5

reboot, controls work I don't use other thing
alfa24t
 
Posts: 1
Joined: Sun Mar 16, 2014 7:56 pm

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby alvenegas » Thu Apr 03, 2014 10:17 am

So, was there any fix to the problem on the Control Address? It seems that the script defaults to 80, but does not read in the port specified.
Any ideas how to fix this?
alvenegas
 
Posts: 3
Joined: Thu Apr 03, 2014 10:15 am

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby alvenegas » Thu Apr 03, 2014 11:20 pm

Nevermind, the solution was simple, just placed the port number next to the IP number (separated by : ). For instance: 192.168.1.12:8212
then, I stopped zm, then I killed the zmcontrol.pl script and started the service again and it worked.
alvenegas
 
Posts: 3
Joined: Thu Apr 03, 2014 10:15 am

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby sagitt » Mon Apr 21, 2014 2:35 pm

Hi all! I'm using the last ZoneMinder 1.26.5 on last ubuntu server 14.04.

I edited the original script for works with original Foscam (I've Foscam FI8918) and some Foscam clones (I've WatchBot, i changed the out-of-box firmware with the original compatibile foscam firmware)

I renamed it IPCAM because foscam and other ipcam works with standards ipcam commands: http://www.notesco.net/download/ipcamcgisdk21.pdf, so is very stupid done a script only for FI8918W if can works with more ipcams.

STANDARD SCRIPT FOR ORIGINAL FOSCAM:
Code: Select all
# ==========================================================================
#
# ZoneMinder IPCAM (Standard Controls) Control Protocol Module
# Copyright (C) 2001-2008 Philip Coombes. Edited By Sagitt (sagitt@email.it)
#
# http://www.openipcam.com/files/Manuals/IPCAM%20CGI%20SDK%202.1.pdf
#
# ==========================================================================

package ZoneMinder::Control::ipcam_standard;

use 5.006;
use strict;
use warnings;

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

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

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

# ==========================================================================
#
# IPCAM 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 );
    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/");

    $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 = $res->decoded_content;
    }
    else
    {
   Error( "Error check failed:'".$res->status_line()."'" );
    }

    return( $result );
}

# IR ON
sub wake
{
    my $self = shift;
    Debug( "Wake - IR ON" );
    my $cmd = "decoder_control.cgi?command=95&";
    $self->sendCmd( $cmd );
}

# IR OFF
sub sleep
{
    my $self = shift;
    Debug( "Sleep - IR OFF" );
    my $cmd = "decoder_control.cgi?command=94&";
    $self->sendCmd( $cmd );
}

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

# Up
sub moveConUp
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Up" );
    my $cmd = "decoder_control.cgi?command=0&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down
sub moveConDown
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Down" );
    my $cmd = "decoder_control.cgi?command=2&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Left
sub moveConLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Left" );
    my $cmd = "decoder_control.cgi?command=6&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Up-Left
sub moveConUpLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Up-Left" );
    my $cmd = "decoder_control.cgi?command=91&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down-Left
sub moveConDownLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Down-Left" );
    my $cmd = "decoder_control.cgi?command=93&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Right
sub moveConRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Right" );
    my $cmd = "decoder_control.cgi?command=4&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Up-Right
sub moveConUpRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Up-Right" );
    my $cmd = "decoder_control.cgi?command=90&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down-Right
sub moveConDownRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Down-Right" );
    my $cmd = "decoder_control.cgi?command=92&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

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

# Zoom Tele
sub zoomConTele
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Tele" );
    my $cmd = "decoder_control.cgi?command=16&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
   $cmd = "decoder_control.cgi?command=17&";
   $self->sendCmd( $cmd );
    }
}

# Zoom Wide
sub zoomConWide
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Wide" );
    my $cmd = "decoder_control.cgi?command=18&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
   $cmd = "decoder_control.cgi?command=19&";
   $self->sendCmd( $cmd );
    }
}

# Zoom Stop
sub zoomConStop
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Stop" );
    my $cmd = "decoder_control.cgi?command=17&";
    $self->sendCmd( $cmd );
}

# Brightness Up
sub whiteAbsIn
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $brightness = 100;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $brightness = int($1) if ( $resp =~ m/var brightness=([0-9]*);/ );
    $brightness += $step;
    $brightness = 255 if ($brightness > 255);
    Debug( "White In - Brightness Up $brightness" );
    $cmd = "camera_control.cgi?param=1&value=".$brightness."&";
    $self->sendCmd( $cmd );
}

# Brightness Down
sub whiteAbsOut
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $brightness = 100;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $brightness = int($1) if ( $resp =~ m/var brightness=([0-9]*);/ );
    $brightness -= $step;
    $brightness = 0 if ($brightness < 0);
    Debug( "White Out - Brightness Down $brightness" );
    $cmd = "camera_control.cgi?param=1&value=".$brightness."&";
    $self->sendCmd( $cmd );
}

# Contrast Up
sub irisAbsOpen
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $contrast = 5;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $contrast = int($1) if ( $resp =~ m/var contrast=([0-9]*);/ );
    $contrast += $step;
    $contrast = 6 if ($contrast > 6);
    Debug( "Iris Open - Contrast Up $contrast" );
    $cmd = "camera_control.cgi?param=2&value=".$contrast."&";
    $self->sendCmd( $cmd );
}

# Contrast Down
sub irisAbsClose
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $contrast = 5;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $contrast = int($1) if ( $resp =~ m/var contrast=([0-9]*);/ );
    $contrast -= $step;
    $contrast = 0 if ($contrast < 0);
    Debug( "Iris Close - Contrast Down $contrast" );
    $cmd = "camera_control.cgi?param=2&value=".$contrast."&";
    $self->sendCmd( $cmd );
}

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

# Preset Set
sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    my $presetCmd = 30 + (($preset-1)*2);
    Debug( "Set Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}

# Preset Go To
sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    my $presetCmd = 31 + (($preset-1)*2);
    Debug( "Goto Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}

1;


INVERSE SCRIPT FOR CLONES WITH CHANGED FIRMWARE (I called it inverse because left and right are inverse, left-up etc.. too)

Code: Select all
# ==========================================================================
#
# ZoneMinder IPCAM (Inverse Controls) Control Protocol Module
# Copyright (C) 2001-2008 Philip Coombes. Edited By Sagitt (sagitt@email.it)
#
# http://www.openipcam.com/files/Manuals/IPCAM%20CGI%20SDK%202.1.pdf
#
# ==========================================================================

package ZoneMinder::Control::ipcam_inverse;

use 5.006;
use strict;
use warnings;

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

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

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

# ==========================================================================
#
# IPCAM 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 );
    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/");

    $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 = $res->decoded_content;
    }
    else
    {
   Error( "Error check failed:'".$res->status_line()."'" );
    }

    return( $result );
}

# IR ON
sub wake
{
    my $self = shift;
    Debug( "Wake - IR ON" );
    my $cmd = "decoder_control.cgi?command=95&";
    $self->sendCmd( $cmd );
}

# IR OFF
sub sleep
{
    my $self = shift;
    Debug( "Sleep - IR OFF" );
    my $cmd = "decoder_control.cgi?command=94&";
    $self->sendCmd( $cmd );
}

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

# Up
sub moveConUp
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Up" );
    my $cmd = "decoder_control.cgi?command=0&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down
sub moveConDown
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Down" );
    my $cmd = "decoder_control.cgi?command=2&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Left
sub moveConLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Left" );
    my $cmd = "decoder_control.cgi?command=4&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Up-Left
sub moveConUpLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Up-Left" );
    my $cmd = "decoder_control.cgi?command=90&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down-Left
sub moveConDownLeft
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Down-Left" );
    my $cmd = "decoder_control.cgi?command=92&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Right
sub moveConRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Right" );
    my $cmd = "decoder_control.cgi?command=6&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Up-Right
sub moveConUpRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Up-Right" );
    my $cmd = "decoder_control.cgi?command=91&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

# Down-Right
sub moveConDownRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Diagonally Down-Right" );
    my $cmd = "decoder_control.cgi?command=93&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
}

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

# Zoom Tele
sub zoomConTele
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Tele" );
    my $cmd = "decoder_control.cgi?command=16&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
   $cmd = "decoder_control.cgi?command=17&";
   $self->sendCmd( $cmd );
    }
}

# Zoom Wide
sub zoomConWide
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Wide" );
    my $cmd = "decoder_control.cgi?command=18&";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
   $cmd = "decoder_control.cgi?command=19&";
   $self->sendCmd( $cmd );
    }
}

# Zoom Stop
sub zoomConStop
{
    my $self = shift;
    my $params = shift;
    Debug( "Zoom Stop" );
    my $cmd = "decoder_control.cgi?command=17&";
    $self->sendCmd( $cmd );
}

# Brightness Up
sub whiteAbsIn
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $brightness = 100;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $brightness = int($1) if ( $resp =~ m/var brightness=([0-9]*);/ );
    $brightness += $step;
    $brightness = 255 if ($brightness > 255);
    Debug( "White In - Brightness Up $brightness" );
    $cmd = "camera_control.cgi?param=1&value=".$brightness."&";
    $self->sendCmd( $cmd );
}

# Brightness Down
sub whiteAbsOut
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $brightness = 100;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $brightness = int($1) if ( $resp =~ m/var brightness=([0-9]*);/ );
    $brightness -= $step;
    $brightness = 0 if ($brightness < 0);
    Debug( "White Out - Brightness Down $brightness" );
    $cmd = "camera_control.cgi?param=1&value=".$brightness."&";
    $self->sendCmd( $cmd );
}

# Contrast Up
sub irisAbsOpen
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $contrast = 5;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $contrast = int($1) if ( $resp =~ m/var contrast=([0-9]*);/ );
    $contrast += $step;
    $contrast = 6 if ($contrast > 6);
    Debug( "Iris Open - Contrast Up $contrast" );
    $cmd = "camera_control.cgi?param=2&value=".$contrast."&";
    $self->sendCmd( $cmd );
}

# Contrast Down
sub irisAbsClose
{
    my $self = shift;
    my $params = shift;
    my $step = $self->getParam( $params, 'step' );
    my $contrast = 5;

    my $cmd = "get_camera_params.cgi?";
    my $resp = $self->sendCmd( $cmd );

    $contrast = int($1) if ( $resp =~ m/var contrast=([0-9]*);/ );
    $contrast -= $step;
    $contrast = 0 if ($contrast < 0);
    Debug( "Iris Close - Contrast Down $contrast" );
    $cmd = "camera_control.cgi?param=2&value=".$contrast."&";
    $self->sendCmd( $cmd );
}

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

# Preset Set
sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    my $presetCmd = 30 + (($preset-1)*2);
    Debug( "Set Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}

# Preset Go To
sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    my $presetCmd = 31 + (($preset-1)*2);
    Debug( "Goto Preset $preset with cmd $presetCmd" );
    my $cmd = "decoder_control.cgi?command=$presetCmd&";
    $self->sendCmd( $cmd );
}

1;


All works fine with this, IR on\off (Not for clones), brightness & contrast up\down, reboot and autostop motion that stop after command execution.

Please check white and iris values, i done a lot of tests for days to get correct zoneminder values

I already fixed "Debug -> Logger" and the ".ZM_VERSION" bug for the last 1.26.5 zoneminder.

See here for control script configuration: https://mega.co.nz/#!UF5T3DCS!JVbiedRUqV_Z5gDf3PRzwRGJTMRH5TL1h1y-2idjxJ4

And this for monitor settings (for me works fine autostop motion value: 0.5)
Schermata 2014-04-21 alle 21.37.41.png


I hope someone can update the official foscam wiki for zoneminder with this. (http://www.zoneminder.com/wiki/index.php/Foscam_FI8918W)

If someone have time, please do it.

Sorry for my bad english, i'm an italian boy :)

;)
sagitt
 
Posts: 2
Joined: Mon Apr 21, 2014 2:20 pm

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby DanielePirata » Wed Nov 05, 2014 2:32 am

Ciao Sagit.

E' fuori tema, ma ho letto che hai anche tu una Watchbot. Volevo anche io inserire un nuovo firmware ma ho paura a "briccarla". Mi confermi il tuo modello Watchbot e l'equivalente Foscam?
Grazie anticipate.

Sorry for this post "out of object", but I need to know which is the compatible Foscam firmware for my old "Watchbot" camera. I do not want to brick it. If someone can help me I'll appreciate.
Thanks.
DanielePirata
 
Posts: 1
Joined: Wed Nov 05, 2014 2:19 am

Re: ZoneMinder 1.25.0 with Foscam FI8918W - Control Problems

Postby sagitt » Fri Apr 03, 2015 4:35 pm

This is an "off topic"

Anyway i don't know my watchbot model but the firmware are

System: Apexis 17.37.2.41
WebUI: FI8908W 11.22.2.30

with this configuration i need to use ipcam_inverse and works perfectly for me.
sagitt
 
Posts: 2
Joined: Mon Apr 21, 2014 2:20 pm

Previous

Return to Technical Support

Who is online

Users browsing this forum: No registered users and 12 guests