Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support non-embedded password challenge #33

Closed
knight-of-ni opened this issue Aug 2, 2013 · 15 comments
Closed

Support non-embedded password challenge #33

knight-of-ni opened this issue Aug 2, 2013 · 15 comments
Assignees
Labels

Comments

@knight-of-ni
Copy link
Member

I'm not sure what the following method is called in software terms...
Zoneminder currently does not support cameras whose only method of authentication is via a separate password challenge response after making initial communication to the camera. When using a web browser, this manifests as a pop-up login after entering the camera's ip address.

Foscam H.264 cameras come to mind, and it is discussed here:
http://foscam.us/forum/post14111.html

One important note from the reference is that wget knows how to handle this kind of password challenge so perhaps there is some kind of common library that Zoenminder can link to?

I'm not entirely sure this is the same issue as the previously reported digest authentication issue. Feel free to mark this as a duplicate if this is the case.

@bemosior
Copy link

bemosior commented Aug 2, 2013

If I'm understanding correctly, this method of authentication is supported. In the Remote Host Name field, I've used the following: username:password@hostname

It's not exactly intuitive, but has worked for me so far.

@knight-of-ni
Copy link
Member Author

Hi bemosior,
The method you method embeds the username & password into the http string like this:
http://username:password@www.example.com/path

In this case, Zoneminder does this for you behind the scenes after you fill out the appropriate fields and hit save.

The cameras I am referring to do not support this method. I know. It seems silly, but they are out there.

@bemosior
Copy link

bemosior commented Aug 3, 2013

Without having a test camera with the issue or more information, it's kind of difficult to tell how to approach the issue. The demo camera they talk about in the forum post was still able to use the above method (prepending the authentication string to the URL): http://user:user@x.x.x.x:port/tmpfs/auto.jpg

Would you happen to have one of those cameras on-hand to test?

@knight-of-ni
Copy link
Member Author

hmmm... I don't see the potential solution you mention in the referenced thread. Maybe I overlooked something. What I see is the script TheUberOverLoard mentions he has written, which would proxy requests between the source (zoneminder in our case) and the camera. That sounded interesting, but after I investigated that reference I discovered he only solved the equation for MJPEG cameras.... the H.264 line still needs some love. You can read about it here:

http://foscam.us/forum/free-generic-browser-interface-for-foscam-ip-h-264-cameras-t2686.html

If you turn to the first post on the second page, he states that there is no easy method to allow automatic authentication.

I have since contacted Foscam technical support and confirmed from them that full control of the camera is not currently possible via embedding a username & password into the initial request to the camera.

The good news is that there is a lot of documentation out there, and one can even access a demo camera.

Demo Camera:
http://www.foscam.com/links.aspx?TypeId=17

Documentation and SDK:
http://ubuntuone.com/2BFcpeGVLrbFadjTw7JOdq

Looks like the SDK has source code examples, and page 16 of the SDK User Manual references how it handles authentication.

Now, if one where to read through all that documentation, one would come across the document "How to watch H.264 VLC Quicktime without public authentication". It explains how to retrieve a video stream via rtsp, but not at full resolution (this method is intended for mobile devices). However, it doesn't have a solution to pan, tilt, and zoom the camera, which brings us back to square one.

Lastly, before anyone spends too much time on this, I recommend we wait to see the results of this thread: http://www.zoneminder.com/forums/viewtopic.php?f=29&t=21089

christophe_y2k claims to be in the final stages of a solution. Once we get a look at his work, it would be nice if we could incorporate his work into the zoneminder source tree.

@bemosior
Copy link

bemosior commented Aug 4, 2013

Ah sorry, I missed what was going on. Hopefully christophe_y2k will have some answers. Foscam's FI8918W h.264 demo seems to be down, but I'll try to take a look at what's involved with writing an authentication middleman/proxy.

All things considered, I'm not sure what the end-goal should be for code that is consumable for the ZoneMinder codebase. If whoever decides that it doesn't belong, the interface script could be open-sourced as its own project (I'm sure ZoneMinder isn't the only use case) and included in the documentation.

@christophey2k
Copy link

Hi, all i send you my topic to use basic authentification in perl that works with my foscam fi8620
i precise i'm not à dev( haven't coded something since 20 or 25 years, and at this time i use assembleur language on Intel 8086/80386 in real mode under ms-dos...)

http://www.zoneminder.com/forums/viewtopic.php?f=9&t=21218

the code for use this basic authentification method in zoneminder:

sub sendCmd
{ 
    my $self = shift;
    my $cmd = shift;
    my $result = undef;
    printMsg( $cmd, "Tx" );
    my $ua = LWP::UserAgent->new();
    my $req = HTTP::Request->new( GET =>"http://".$self->{Monitor}->{ControlAddress}."/web/cgi-bin/hi3510/".$cmd );
    $req->authorization_basic('admin', $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 );
}

@ghost ghost assigned kylejohnson Aug 9, 2013
@kylejohnson
Copy link
Member

Hey @christophey2k, thank you very much for contributing this. I am working on getting it into the ZM source for the next release.

The thread that you linked is quite extensive, the code that you pasted above is but a subset of what is in the thread. There is a large perl script at the bottom of your first post in that thread, and the code that you posted above is only a part of it.

For clarity's sake, should I include the whole script as posted in your thread, or the code above?

@christophey2k
Copy link

Ok this is the entire script, have a probleme with the parser of this web site, the parser can't print my script correctly, have you an idea how i did that ?
for the moment you need to remove all // before # ( //# must be replacer by # )
in perl # is for a comment ...

# V1
#
# ZoneMinder FOSCAM version 1.0 API Control Protocol Module, $Date$, $Revision$
# Copyright (C) 2001-2008  Philip Coombes
#
# 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.
#
# V1.1 ====================================================================================
#
# This module FI8620_Y2k.pm contains the implementation of API camera control
# For FOSCAM FI8620 Dome PTZ Camera (This cam support only H264 streaming)
# V0.1b Le 01 JUIN 2013
# V0.2b Le 11 JUILLET 2013
# V0.5b Le 24 JUILLET 2013
# V0.6b Le 01 AOUT 2013 - 
# V1.0  Le 04 AOUT 2013 - production usable if you do not use preset ptz
# V1.1  Le 11 AOUT 2013 - put a cosmetic update source code
# If you wan't to contact me i understand French and English, precise ZoneMinder in subject
# My name is Christophe DAPREMONT my email is christophe_y2k@yahoo.fr
#
# V1.1 ====================================================================================
package ZoneMinder::Control::FI8620_Y2k;

use 5.006;
use strict;
use warnings;

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

our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ===================================================================================================================================
#
# FI8620 FOSCAM Dome PTZ H264 Control Protocol
# with Firmware version V3.2.2.2.1-20120815 (latest at 04/08/2013)
# based with the latest buggy CGI doc from FOSCAM ( http://foscam.us/forum/cgi-api-sdk-for-mjpeg-h-264-camera-t2986.html )
# This IPCAM work under ZoneMinder V1.25 from alternative source of code 
# from this svn at https://svn.unixmedia.net/public/zum/trunk/zum/
# Many Thanks to "MASTERTHEKNIFE" for the excellent speed optimisation ( http://www.zoneminder.com/forums/viewtopic.php?f=9&t=17652 )
# And to "NEXTIME" for the recent source update and incredible plugins ( http://www.zoneminder.com/forums/viewtopic.php?f=9&t=20587 )
# And all people helping ZoneMinder dev.
#
# -FUNCTIONALITIES:
# -Move camera in 8 direction with arrow, the speed of movement is function
#  of the position of your mouse on the arrow.
#  Extremity of arrow equal to fastest speed of movement
#  Close the base of arrow to lowest speed of movement
#  for diagonaly you can click before the begining of the arrow for low speed
#  In round center equal to stop to move
# -You can clic directly on the image that equal to click on arrow (for the left there is a bug in zoneminder speed is inverted)
# -Zoom Tele/Wide with time control to simulate speed because speed value do not work (buggy firmware or not implemented on this cam)
# -Focus Near/Far with time control to simulate speed because speed value do not work (buggy firmware or not implemented on this cam)
# -Autofocus is automatic when you move again or can be setting by autofocus button
# -8 Preset PTZ are implemented but the firmware is buggy and that do not work
#  You Need to configure ZoneMinder PANSPEED & TILTSEPPED & ZOOMSPEED 1 to 63 by 1 step
# -This Script use for login "admin" this hardcoded and your password must setup in "Control Device" section
# -This script is compatible with the basic authentification method used by mostly new camera
# -AutoStop function is active and you must set up value (in sec exemple 0.5) under AutoStop section
#  or you can set up to 0 for disable it but the camera never stop to move and trust me, she can move all the night...
#  (you need to click to the center arrow for stop)
# -"White In" to control Brightness, "auto" for restore the original value of Brightness
# -"White Out" to control Contrast, "man" for restore the original value of Contrast
# -"Iris Open" to control Saturation , "auto" for restore the original value of Saturation
# -"Iris Close" to control Hue , "man" for restore the original value of Hue
# -Another cool stuff i use the OSD function of this cam for printing the command with the value
#  The button of Focus "Man" is for enable or disable OSD but that do not work ( it's my bug... i'm very very new with perl )
# ===================================================================================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );

# Set $osd to "off" if you wan't disabled OSD i need to place this variable in another script because
# this script is reload at every command ,if i want the button on/off (Focus MAN) for OSD works...
my $osd = "on";

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" );
    # I solve the authentification problem with recent Foscam
    # I use perl Basic Authentification method
    my $ua = LWP::UserAgent->new();
    my $req = HTTP::Request->new( GET =>"http://".$self->{Monitor}->{ControlAddress}."/web/cgi-bin/hi3510/".$cmd );
    $req->authorization_basic('admin', $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 moveStop
{
    my $self = shift;
    Debug( "Move Stop" );
    my $cmd = "ptzctrl.cgi?-step=0&-act=stop";
    $self->sendCmd( $cmd );
        my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=0&-name=.";
        $self->sendCmd( $cmd );
}

sub autoStop
{
    my $self = shift;
    my $autostop = shift;
    if( $autostop )
    {
       Debug( "Auto Stop" );
       usleep( $autostop );
       my $cmd = "ptzctrl.cgi?-step=0&-act=stop";
       $self->sendCmd( $cmd );
       my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=0&-name=.";
       $self->sendCmd( $cmd );
    }
}

sub moveConUp
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    Debug( "Move Up" ); 
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Move Up $tiltspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=up&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} ); 
}

sub moveConDown
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    Debug( "Move Down" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Move Down $tiltspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=down&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConLeft
{
    my $self = shift;
    my $params = shift;
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    # Algorithme pour inverser la table de valeur de la flèche gauche, (for invert the value) 63 ==> 1 et 1 ==> 63 ...
    $panspeed = abs($panspeed - 63) + 1;
    Debug( "Move Left" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Move Left $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=left&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConRight
{
    my $self = shift;
    my $params = shift;
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    Debug( "Move Right" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Move Right $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=right&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConUpLeft
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect value in the database
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    Debug( "Move Con Up Left" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Up $tiltspeed Left $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=up&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    my $cmd = "ptzctrl.cgi?-step=0&-act=left&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConUpRight
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    Debug( "Move Con Up Right" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Up $tiltspeed Right $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=up&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    my $cmd = "ptzctrl.cgi?-step=0&-act=right&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConDownLeft
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    Debug( "Move Con Down Left" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Down $tiltspeed Left $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=down&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    my $cmd = "ptzctrl.cgi?-step=0&-act=left&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub moveConDownRight
{
    my $self = shift;
    my $params = shift;
    my $tiltspeed = $self->getParam( $params, 'tiltspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $tiltspeed > 59 ) {
                $tiltspeed = 63;
                   }
    if ( $tiltspeed < 6 ) {
               $tiltspeed = 1;
                  }
    my $panspeed = $self->getParam( $params, 'panspeed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $panspeed > 59 ) {
               $panspeed = 63;
                  }
    if ( $panspeed < 6 ) {
              $panspeed = 1;
                 }
    Debug( "Move Con Down Right" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Down $tiltspeed Right $panspeed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=down&-speed=$tiltspeed";
    $self->sendCmd( $cmd );
    my $cmd = "ptzctrl.cgi?-step=0&-act=right&-speed=$panspeed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub zoomConTele
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 59 ) {
                $speed = 63;
               }
    if ( $speed < 6 ) {
               $speed = 1;
              }
    Debug( "Zoom-Tele" );
    # I use OSD Function to send the speed used for determining the time before stop the order
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Zoom Tele $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=zoomin";
    $self->sendCmd( $cmd );
    # The variable speed does not work with zoom setting, so I used to set the duration of the order
    # the result is identical
    $self->autoStop( int(10000*$speed) );
}

sub zoomConWide
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 59 ) {
                $speed = 63;
               }
    if ( $speed < 6 ) {
               $speed = 1;
              }
    Debug( "Zoom-Wide" );
    # I use the feature OSD (OnScreenDisplay). Variable speed as a basis for calculating the duration of the zoom order
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Zoom Wide $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=zoomout";
    $self->sendCmd( $cmd );
    # The variable speed does not work with zoom setting, so I used to set the duration of the order
    # the result is identical
    $self->autoStop( int(10000*$speed) );
}

sub focusConNear
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 59 ) {
                $speed = 63;
                   }
    if ( $speed < 6 ) {
               $speed = 1;
              }
    Debug( "Focus Near" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Focus Near $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=focusout&-speed=$speed";
    $self->sendCmd( $cmd );
    # The variable speed does not work with focus setting, so I used to set the duration of the order
    # the result is identical
    $self->autoStop( int(10000*$speed) );
}

sub focusConFar
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 59 ) {
                $speed = 63;
               }
    if ( $speed < 6 ) {
               $speed = 1;
              }
    Debug( "Focus Far" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Focus Far $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-step=0&-act=focusin&-speed=$speed";
    $self->sendCmd( $cmd );
    # The variable speed does not work with focus setting, so I used to set the duration of the order
    # the result is identical
    $self->autoStop( int(10000*$speed) );
}

sub focusAuto
{
    my $self = shift;
    Debug( "Focus Auto" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Focus Auto";
         $self->sendCmd( $cmd );
        }
    my $cmd = "ptzctrl.cgi?-act=auto&-step=1";
    $self->sendCmd( $cmd );
}

sub focusMan
{
    my $self = shift;
    Debug( "Focus Manu=OSD ON OFF" );
    if ( $osd eq "on" )
     {
      $osd = "off";
          my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=OSD $osd";
          $self->sendCmd( $cmd );
          $self->autoStop( int(1000000*0.5) );
     }
    if ( $osd eq "off" )
         {
          $osd = "on";
          my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=OSD $osd";
          $self->sendCmd( $cmd );
          $self->autoStop( int(1000000*0.5) );
         }
}

sub whiteConIn
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 255 ) {
                 $speed = 255;
                }
    if ( $speed < 0 ) {
               $speed = 0;
              }
    Debug( "White ConIn=brightness" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Brightness $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-brightness=$speed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub whiteConOut
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect possible value in the database, and for realise at low and high speed an more precise moving
    if ( $speed > 255 ) {
                 $speed = 255;
                }
    if ( $speed < 0 ) {
               $speed = 0;
              }
    Debug( "White ConOut=Contrast" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Contrast $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-contrast=$speed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub whiteAuto
{
    my $self = shift;
    Debug( "White Auto=Brightness Reset" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Brightness Reset";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-brightness=120";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub whiteMan
{
    my $self = shift;
    Debug( "White Manuel=Contrast Reset" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Contrast Reset";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-contrast=140";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub irisConOpen
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect value in the database
    if ( $speed > 255 ) {
                 $speed = 255;
                }
    if ( $speed < 0 ) {
               $speed = 0;
              }
    Debug( "Iris ConOpen=Saturation" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Saturation $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-saturation=$speed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub irisConClose
{
    my $self = shift;
    my $params = shift;
    my $speed = $self->getParam( $params, 'speed' );
    # Standardization for incorrect value in the database
    if ( $speed > 255 ) {
                 $speed = 255;
                }
    if ( $speed < 0 ) {
               $speed = 0;
              }
    Debug( "Iris ConClose=Hue" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Hue $speed";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-hue=$speed";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub irisAuto
{
    my $self = shift;
    Debug( "Iris Auto=Saturation Reset" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Saturation Reset";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-saturation=150";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub irisMan
{
    my $self = shift;
    Debug( "Iris Manuel=Hue Reset" );
    if ( $osd eq "on" )
    {
         my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=Hue Reset";
         $self->sendCmd( $cmd );
        }
    my $cmd = "param.cgi?cmd=setimageattr&-hue=255";
    $self->sendCmd( $cmd );
    $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}

sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    if ( ( $preset >= 1 ) && ( $preset <= 8 ) ) {
                             Debug( "Clear Preset $preset" );
                             my $cmd = "preset.cgi?-act=set&-status=0&-number=$preset";
                                 $self->sendCmd( $cmd );
                                                 Debug( "Set Preset $preset" );
                             if ( $osd eq "on" )
                            {
                                     my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=PresetSet $preset";
                                         $self->sendCmd( $cmd );
                            }
                                                 my $cmd = "preset.cgi?-act=set&-status=1&-number=$preset";
                                                 $self->sendCmd( $cmd );
                         $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
                            }
}

sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    if ( ( $preset >= 1 ) && ( $preset <= 8 ) ) {
                             Debug( "Goto Preset $preset" );
                             if ( $osd eq "on" )
                            {
                                 my $cmd = "param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=PresetGoto $preset";
                                         $self->sendCmd( $cmd );
                            }
                             my $cmd = "preset.cgi?-act=goto&-number=$preset";
                             $self->sendCmd( $cmd );
                         $self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
                            }
}

1;
__END__
# Below is stub documentation for your module. You'd better edit it!

=head1 FI8620

ZoneMinder::Database - Perl extension for FOSCAM FI8620

=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
![foscam_fi8620_by_christophe_y2k_p5](https://f.cloud.github.com/assets/3194740/944279/3a4e23c4-02a3-11e3-8627-aeb6996f40d5.png)

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

foscam_fi8620_by_christophe_y2k_p2

foscam_fi8620_by_christophe_y2k_p5

@knight-of-ni
Copy link
Member Author

I've read through christophey2k's solution, and if one strips out the Gentoo specific stuff, it looks like we are left with three items:

  1. ffmpeg control patch
  2. rtsp source path for the video stream
  3. custom perl module for the ptz control

Kyle - Can you confirm that item 1 has already been applied to the source tree? I think it has, but I'm not sure I know how to check that myself. Let me know if this is something simple. I'm still going through a github learning curve.

It seems I was mistaken about item 2. After reading through the Foscam documentation, I understood that the method christophey2k used to embed user credentials into the http url would not work. Well, apparently it does, at least for the video stream anyway. My apologies as this was my primary motivator for creating this issue in the first place.

Item 3 should simply be adding his control script to the existing collection of ptz control control scripts.

PS: Like christophey2k mentioned, I too have not yet found the intended way to post or attach code to issues w/o it being parsed. I'd be interested in learning this.

@kylejohnson
Copy link
Member

@knnniggett :

  1. commit bb19e80 allows support for control when monitor source is ffmpeg, is this what you're referring to?
  2. Where is the rtsp source path?
  3. I assume that the script that @christophey2k posted is what you're referring to as the custom perl module.

If you want to post code without it being parsed, you want to surround it in three backticks (opening and closing), like so: ```

And if you want to use syntax highlighting, do this: ```perl

or ```ruby. Here is a perl example:

#!/usr/bin/perl

use strict;
use warnings;

print "foo\n";

Read https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks and https://help.github.com/articles/github-flavored-markdown#syntax-highlighting for more information.

Also if you want to mention someone specific, prepend an @ symbol before their github name, like @kylejohnson = @kylejohnson

@kylejohnson
Copy link
Member

@christophey2k I went ahead and modified your post to use the perl syntax highligher (See https://help.github.com/articles/github-flavored-markdown#syntax-highlighting)

Honestly though, the 'correct' way to submit this would be via a pull request, but as this change is fairly small, I can just copy and paste the code.

@knight-of-ni
Copy link
Member Author

@kylejohnson
Thanks for the github tips.
Yes, commit bb19e80 is the one I was referring to.
The rtsp source path is shown in one of the screen shots. Here is a direct link the screenshot in question:
http://www.gh-pc.com/zm/FOSCAM_FI8620_By_Christophe_Y2k_P2.png

He uses a source path of: rtsp://admin:password@ip_foscam:554/11

11 refers to video stream 1. Changing that value to a 12 would cause the camera to use a second stream.

Oh, and yes, @christophey2k's script was what I was referring to when I mentioned custom perl module. What I meant to say was custom ptz control script.

@christophey2k
Copy link

Thanks for that i'm new with github... i send screenshoot to help to configure the script, all are on ZoneMinder Forum...

@christophey2k
Copy link

Hi, the next script is for similar H264 camera with Chipset HI3510 The FI-8608W
online here http://www.zoneminder.com/forums/viewtopic.php?f=9&t=21244

@knight-of-ni
Copy link
Member Author

I've created a pull request that effectively resolves this issue for the camera in question:
#85

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants