Apexis APM J0233 WS IR (IR, outdoor, IP66)
Sometimes there are distortions when switching from Nightvision to normal and back. Overall nice image quality.
I had to create a new user to access the image (username view, password abc123).
Remote Protocol: HTTP
Remote Method: Simple
Remote Host Name: <ip of camera>
Remote Host Port: 80
Remote Host Path: videostream.cgi?user=<USERNAME>&pwd=<PASSWORD>&resolution=32
Remote Image colors: 24 bit
Capture Width: 640
Capture Height: 480
Apexis J12 IP Camera
Remote Protocol: HTTP
Remote Method: Simple
Remote Host Name: <ip of camera>
Remote Host Port: 80
Remote Host Path: videostream.cgi?user=<USERNAME>&pwd=<PASSWORD>
Remote Image colors: 24 bit
Capture Width: 640
Capture Height: 480
It is recommended to set Max FPS to 20.
Apexis APM-J011-WS IP Camera
Remote Protocol: HTTP
Remote Method: Simple
Remote Host Name: <IP_ADDRESS_OF_CAMERA>
Remote Host Port: 80
Remote Host Path: videostream.cgi?user=<USERNAME>&pwd=<PASSWORD>
Remote Image colors: 24 bit
Capture Width: 640
Capture Height: 480
Maximum frame rate this IP web camera can handle is 15 fps at 640x480. The <USERNAME> and <PASSWORD> are found in the "Users Settings" section of the IP Camera's web setup page.
Pan Tilt Control is not available in Zoneminder 1.25.0 at this time (Feb 2012.) This IP camera does not have a zoom function, only pan and tilt.
Features
- Wired and Wireless Ethernet. 802.11b/g with WEP & WPA WPA2 encryption
- 3x optical zoom
- 355° pan, 90° tilt
- POE
- DDNS
- Supports VLC (apparently!)
- Supports MSN
- Supports Firefox/Chrome (ie: Push-mode)
- Two-way audio capable (microphone and speaker not included)
- FTP uploads
- Email alerts
Settings
Source
|
Remote Protocol
|
HTTP
|
Remote Method
|
Simple
|
Remote Host Name
|
<IP_ADDRESS_OF_CAMERA>
|
Remote Host Port
|
80
|
Remote Host Path
|
videostream.cgi?user=<USERNAME>&pwd=<PASSWORD>
or
snapshot.cgi?user=<USERNAME>&pwd=<PASSWORD>&resolution=32&rate=0
eg: snapshot.cgi?user=zoneminder&pwd=zonepass&resolution=32&rate=0
|
Remote Image colors
|
24 bit
|
Capture Width
|
640
|
Capture Height
|
480
|
|
Control
|
Controllable
|
Error creating thumbnail: Unable to save thumbnail to destination
|
Control Type
|
Apexis Mjpeg IP (Select Edit to access Control Capabilities)
|
Control Address
|
<USERNAME>:<PASSWORD>@<IP_ADDRESS_OF_CAMERA>:<PORT>
eg: admin:@<IP_ADDRESS_OF_CAMERA>:80
eg: zoneminder:zonepass@192.168.1.111
|
Auto Stop Timeout
|
0.10
|
|
- Control Capability - Apexis Mjpeg IP
Main
|
Name
|
Apexis Mjpeg IP
|
Type
|
Remote
|
Protocol
|
ApexisMjpegIP (Refer to control protocol below)
|
Can Reset
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Move
|
Can Move
|
Error creating thumbnail: Unable to save thumbnail to destination
|
Can Move Continuous
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Pan
|
Can Pan
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Tilt
|
Can Tilt
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Zoom
|
Can Zoom
|
Error creating thumbnail: Unable to save thumbnail to destination
|
Can Zoom Continuous
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Presets
|
Has Presets
|
Error creating thumbnail: Unable to save thumbnail to destination
|
Num Presets
|
8 (to be confirmed)
|
Can Set Presets
|
Error creating thumbnail: Unable to save thumbnail to destination
|
|
Control protocol for Apexis MJPEG Cameras
Save the following code as /usr/share/perl5/ZoneMinder/Control/ApexisMjpegIP.pm
Don't forget to set the user and password as I haven't figured that bit out yet ;).
# ==========================================================================
#
# ZoneMinder Apexis MJPEG IP Camera Control Protocol Module
# Copyright (C) 2012 Marcus Brown
# Shamefully copied from the Loftek module by 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.
#
# ==========================================================================
#
# This module contains the implementation of the Apexis MJPEG IP camera control
# protocol
#
package ZoneMinder::Control::ApexisMjpegIP;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
our %CamParams = ();
# ==========================================================================
#
# Apexis MJPEG IP Control Protocol
#
# On ControlAddress use the format :
# USERNAME:PASSWORD@ADDRESS:PORT
# eg : admin:@10.1.2.1:80
# zoneminder:zonepass@10.0.100.1:40000
#
# ==========================================================================
# Change "ZoneMinder::Logger" to "ZoneMinder::Debug" for zoneminder < 1.25.0
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( ) || 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" );
# ############################################################################################
#
# CHANGE THE FOLLOWING LINE IF NECESSARY
# IT SHOULD WORK WITH A DEFAULT CAMERA, BUT SURELY YOU WILL BE SETTING AN ADMIN PASSWORD? :)
#
# ############################################################################################
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd\&user=admin\&pwd=" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed:'".$res->status_line()."'" );
}
return( $result );
}
sub getCamParams
{
my $self = shift;
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/get_params.cgi" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
# Parse results setting values in %FCParams
my $content = $res->decoded_content;
while ($content =~ s/var\s+([^=]+)=([^;]+);//ms) {
$CamParams{$1} = $2;
}
}
else
{
Error( "Error check failed:'".$res->status_line()."'" );
}
}
#autoStop
#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab
sub autoStop
{
my $self = shift;
my $stop_command = shift;
my $autostop = shift;
if( $stop_command && $autostop)
{
Debug( "Auto Stop" );
usleep( $autostop );
my $cmd = "decoder_control.cgi?command=".$stop_command;
$self->sendCmd( $cmd );
}
}
# Reset the Camera
sub reset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "reboot.cgi?";
$self->sendCmd( $cmd );
}
#Up Arrow
sub moveConUp
{
my $self = shift;
my $stop_command = "1";
Debug( "Move Up" );
my $cmd = "decoder_control.cgi?command=0";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Down Arrow
sub moveConDown
{
my $self = shift;
my $stop_command = "3";
Debug( "Move Down" );
my $cmd = "decoder_control.cgi?command=2";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Left Arrow
sub moveConLeft
{
my $self = shift;
my $stop_command = "5";
Debug( "Move Left" );
my $cmd = "decoder_control.cgi?command=4";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Right Arrow
sub moveConRight
{
my $self = shift;
my $stop_command = "7";
Debug( "Move Right" );
my $cmd = "decoder_control.cgi?command=6";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#####################################################################################
# Single-step movements
#
# 'onestep' and 'degree' don't appear to work for the J901
sub moveRelUp
{
my $self = shift;
Debug( "Move Up" );
my $cmd = "decoder_control.cgi?command=0&onestep=1";
$self->sendCmd( $cmd );
}
#~ #~
sub moveRelDown
{
my $self = shift;
Debug( "Move Down" );
my $cmd = "decoder_control.cgi?command=2&onestep=1";
$self->sendCmd( $cmd );
}
#~ #~
sub moveRelLeft
{
my $self = shift;
Debug( "Move Left" );
my $cmd = "decoder_control.cgi?command=4&onestep=1";
$self->sendCmd( $cmd );
}
#~ #~
sub moveRelRight
{
my $self = shift;
Debug( "Move Right" );
my $cmd = "decoder_control.cgi?command=6&onestep=1";
$self->sendCmd( $cmd );
}
#This camera does not have builtin diagonal commands so we emulate them
sub moveRelUpRight
{
my $self = shift;
Debug( "Step Diagonally Up Right" );
$self->stepConUp( );
$self->stepConRight( );
}
#~ #~
sub moveRelDownRight
{
my $self = shift;
Debug( "Step Diagonally Down Right" );
$self->stepConDown( );
$self->stepConRight( );
}
#~ #~
sub moveRelUpLeft
{
my $self = shift;
Debug( "Step Diagonally Up Left" );
$self->stepConUp( );
$self->stepConLeft( );
}
#~ #~
sub moveRelDownLeft
{
my $self = shift;
Debug( "Step Diagonally Down Left" );
$self->stepConDown( );
$self->stepConLeft( );
}
#
#####################################################################################
# Iris/Aperture control ... this is *NOT* 'iris' as 'brightness' ?
#
# Doubt this works on J901
sub irisConClose
{
my $self = shift;
my $stop_command = "8";
Debug( "Focus Near" );
my $cmd = "decoder_control.cgi?command=9";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#~ #~
sub irisConOpen
{
my $self = shift;
my $stop_command = "10";
Debug( "Focus Near" );
my $cmd = "decoder_control.cgi?command=11";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#
#####################################################################################
# Focus control
#
# J901 is manual focus
sub focusConNear
{
my $self = shift;
my $stop_command = "13";
Debug( "Focus Near" );
my $cmd = "decoder_control.cgi?command=12";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#~ #~
sub focusConFar
{
my $self = shift;
my $stop_command = "15";
Debug( "Focus Near" );
my $cmd = "decoder_control.cgi?command=14";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#
#####################################################################################
#Zoom In
sub zoomConTele
{
my $self = shift;
my $stop_command = "19";
Debug( "Zoom Tele" );
my $cmd = "decoder_control.cgi?command=18";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#~ #Zoom Out
sub zoomConWide
{
my $self = shift;
my $stop_command = "17";
Debug( "Zoom Wide" );
my $cmd = "decoder_control.cgi?command=16";
$self->sendCmd( $cmd );
$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#~ #Diagonally Up Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpRight
{
my $self = shift;
Debug( "Move Diagonally Up Right" );
$self->moveConUp( );
$self->moveConRight( );
}
#Diagonally Down Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownRight
{
my $self = shift;
Debug( "Move Diagonally Down Right" );
$self->moveConDown( );
$self->moveConRight( );
}
#~
#Diagonally Up Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpLeft
{
my $self = shift;
Debug( "Move Diagonally Up Left" );
$self->moveConUp( );
$self->moveConLeft( );
}
#~
#Diagonally Down Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownLeft
{
my $self = shift;
Debug( "Move Diagonally Down Left" );
$self->moveConDown( );
$self->moveConLeft( );
}
#Stop
#~ sub moveStop
#~ {
#~ my $self = shift;
#~ Debug( "Move Stop" );
#~ my $cmd = "decoder_control.cgi?command=1";
#~ $self->sendCmd( $cmd );
#~ }
#Set Camera Preset
#Presets must be translated into values internal to the camera
#Those values are: 30,32,34 ... 88,90,92 for presets 1-32 respectively
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
#~
if (( $preset >= 1 ) && ( $preset <= 32 )) {
my $cmd = "decoder_control.cgi?command=".(($preset*2) + 28);
$self->sendCmd( $cmd );
}
}
#Recall Camera Preset
#Presets must be translated into values internal to the camera
#Those values are: 31,33,35 ... 89,91,93 for presets 1-32 respectively
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
#~
if (( $preset >= 1 ) && ( $preset <= 32 )) {
my $cmd = "decoder_control.cgi?command=".(($preset*2) + 29);
$self->sendCmd( $cmd );
}
#~ if ( $preset == 9 ) {
#~ $self->horizontalPatrol();
#~ }
#~ if ( $preset == 10 ) {
#~ $self->horizontalPatrolStop();
#~ }
}
#~ sub presetHome
#~ {
#~ my $self = shift;
#~ Debug( "Home Preset" );
#~ my $cmd = "decoder_control.cgi?command=25";
#~ $self->sendCmd( $cmd );
#~ }
#Horizontal Patrol - Vertical Patrols are not supported
sub horizontalPatrol
{
my $self = shift;
Debug( "Horizontal Patrol" );
my $cmd = "decoder_control.cgi?command=20";
$self->sendCmd( $cmd );
}
#Horizontal Patrol Stop
sub horizontalPatrolStop
{
my $self = shift;
Debug( "Horizontal Patrol Stop" );
my $cmd = "decoder_control.cgi?command=21";
$self->sendCmd( $cmd );
}
# Set Absolute Brightness
#~ sub setAbsBrightness
#~ {
#~ my $self = shift;
#~ my $brightness = shift;
#~ $brightness = 255 if $brightness > 255;
#~ $brightness = 0 if $brightness < 0;
#~ Debug( "Setting brightness to $brightness" };
#~ $CamParams{'brightness'} = $brightness;
#~ my $cmd = "camera_control.cgi?param=1&value=".$brightness;
#~ $self->sendCmd( $cmd );
#~ }
# Increase Brightness
#~ sub irisAbsOpen
#~ {
#~ my $self = shift;
#~ my $params = shift;
#~ $self->getCamParams() unless($CamParams{'brightness'});
#~ my $step = $self->getParam( $params, 'step' );
#~
#~ $CamParams{'brightness'} += $step;
#~ $CamParams{'brightness'} = 255 if ($CamParams{'brightness'} > 255);
#~ Debug( "Iris $CamParams{'brightness'}" );
#~ my $cmd = "camera_control.cgi?param=1&value=".$CamParams{'brightness'};
#~ $self->sendCmd( $cmd );
#~ }
# Decrease Brightness
#~ sub irisAbsClose
#~ {
#~ my $self = shift;
#~ my $params = shift;
#~ $self->getCamParams() unless($CamParams{'brightness'});
#~ my $step = $self->getParam( $params, 'step' );
#~
#~ $CamParams{'brightness'} -= $step;
#~ $CamParams{'brightness'} = 0 if ($CamParams{'brightness'} < 0);
#~ Debug( "Iris $CamParams{'brightness'}" );
#~ my $cmd = "camera_control.cgi?param=1&value=".$CamParams{'brightness'};
#~ $self->sendCmd( $cmd );
#~ }
# Set Absolute Contrast
#~ sub setAbsContrast
#~ {
#~ my $self = shift;
#~ my $contrast = shift;
#~ $contrast = 255 if $contrast > 255;
#~ $contrast = 0 if $contrast < 0;
#~ Debug( "Setting contrast to $contrast" };
#~ $CamParams{'contrast'} = $contrast;
#~ my $cmd = "camera_control.cgi?param=2&value=".$contrast;
#~ $self->sendCmd( $cmd );
#~ }
# Increase Contrast
#~ sub whiteAbsIn
#~ {
#~ my $self = shift;
#~ my $params = shift;
#~ $self->getCamParams() unless($CamParams{'contrast'});
#~ my $step = $self->getParam( $params, 'step' );
#~
#~ $CamParams{'contrast'} += $step;
#~ $CamParams{'contrast'} = 6 if ($CamParams{'contrast'} > 6);
#~ Debug( "Contrast $CamParams{'contrast'}" );
#~ my $cmd = "camera_control.cgi?param=2&value=".$CamParams{'contrast'};
#~ $self->sendCmd( $cmd );
#~ }
# Decrease Contrast
#~ sub whiteAbsOut
#~ {
#~ my $self = shift;
#~ my $params = shift;
#~ $self->getCamParams() unless($CamParams{'contrast'});
#~ my $step = $self->getParam( $params, 'step' );
#~
#~ $CamParams{'contrast'} -= $step;
#~ $CamParams{'contrast'} = 0 if ($CamParams{'contrast'} < 0);
#~ Debug( "Iris $CamParams{'contrast'}" );
#~ my $cmd = "camera_control.cgi?param=2&value=".$CamParams{'contrast'};
#~ $self->sendCmd( $cmd );
#~ }
1;