1# ========================================================================== 2# 3# ZoneMinder Dericam P2 Control Protocol Module 4# Copyright (C) Roman Dissertori 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License 8# as published by the Free Software Foundation; either version 2 9# of the License, or (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19# 20# ========================================================================== 21# 22# This module contains the implementation of the Dericam P2 device control protocol 23# 24package ZoneMinder::Control::DericamP2; 25 26use 5.006; 27use strict; 28use warnings; 29 30require ZoneMinder::Control; 31 32our @ISA = qw(ZoneMinder::Control); 33 34our %CamParams = (); 35 36# ========================================================================== 37# 38# Dericam P2 Control Protocol 39# 40# On ControlAddress use the format : 41# USERNAME:PASSWORD@ADDRESS:PORT 42# eg : admin:@10.1.2.1:80 43# zoneminder:zonepass@10.0.100.1:40000 44# 45# ========================================================================== 46 47use ZoneMinder::Logger qw(:all); 48use ZoneMinder::Config qw(:all); 49 50use Time::HiRes qw( usleep ); 51 52sub open 53{ 54 my $self = shift; 55 56 $self->loadMonitor(); 57 58 use LWP::UserAgent; 59 $self->{ua} = LWP::UserAgent->new; 60 $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); 61 62 $self->{state} = 'open'; 63} 64 65sub printMsg 66{ 67 my $self = shift; 68 my $msg = shift; 69 my $msg_len = length($msg); 70 71 Debug( $msg."[".$msg_len."]" ); 72} 73 74sub sendCmd 75{ 76 my $self = shift; 77 my $cmd = shift; 78 my $result = undef; 79 printMsg( $cmd, "Tx" ); 80 81 my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" ); 82 Info( "http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} ); 83 my $res = $self->{ua}->request($req); 84 85 if ( $res->is_success ) 86 { 87 $result = !undef; 88 } 89 else 90 { 91 Error( "Error check failed:'".$res->status_line()."'" ); 92 } 93 94 return( $result ); 95} 96 97sub getCamParams 98{ 99 my $self = shift; 100 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=getimageattr"; 101 102 my $req = $self->sendCmd( $cmd ); 103 my $res = $self->{ua}->request($req); 104 105 if ( $res->is_success ) 106 { 107 # Parse results setting values in %FCParams 108 my $content = $res->decoded_content; 109 110 while ($content =~ s/var\s+([^=]+)=([^;]+);//ms) { 111 $CamParams{$1} = $2; 112 } 113 } 114 else 115 { 116 Error( "Error check failed:'".$res->status_line()."'" ); 117 } 118} 119 120#autoStop 121#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab 122sub autoStop 123{ 124 my $self = shift; 125 my $stop_command = shift; 126 my $autostop = shift; 127 if( $stop_command && $autostop) 128 { 129 Debug( "Auto Stop" ); 130 usleep( $autostop ); 131 my $cmd = "decoder_control.cgi?command=".$stop_command; 132 $self->sendCmd( $cmd ); 133 } 134 135} 136 137# Reset the Camera 138sub reset 139{ 140 my $self = shift; 141 Debug( "Camera Reset" ); 142 # Move to default position 143 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=home"; 144 $self->sendCmd( $cmd ); 145 146 # Reset all other values to default 147 $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-image_type=1&-default=on"; 148 $self->sendCmd( $cmd ); 149} 150 151# Reboot Camera (on Sleep button) 152sub sleep 153{ 154 my $self = shift; 155 Debug( "Camera Reboot" ); 156 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=sysreboot"; 157 $self->sendCmd( $cmd ); 158} 159 160# Stop the Camera 161sub moveStop 162{ 163 my $self = shift; 164 Debug( "Camera Stop" ); 165 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=stop"; 166 $self->sendCmd( $cmd ); 167} 168 169#Up Arrow 170sub moveConUp 171{ 172 my $self = shift; 173 my $stop_command = "1"; 174 Debug( "Move Up" ); 175 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=up&-speed=45"; 176 $self->sendCmd( $cmd ); 177 #$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); 178} 179 180#Down Arrow 181sub moveConDown 182{ 183 my $self = shift; 184 my $stop_command = "3"; 185 Debug( "Move Down" ); 186 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=down&-speed=45"; 187 $self->sendCmd( $cmd ); 188 #$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); 189} 190 191#Left Arrow 192sub moveConLeft 193{ 194 my $self = shift; 195 my $stop_command = "5"; 196 Debug( "Move Left" ); 197 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=left&-speed=45"; 198 $self->sendCmd( $cmd ); 199 #$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); 200} 201 202#Right Arrow 203sub moveConRight 204{ 205 my $self = shift; 206 my $stop_command = "7"; 207 Debug( "Move Right" ); 208 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=right&-speed=45"; 209 $self->sendCmd( $cmd ); 210 #$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} ); 211} 212 213#Zoom In 214sub zoomConTele 215{ 216 my $self = shift; 217 Debug( "Zoom Tele" ); 218 my $cmd = "decoder_control.cgi?command=18"; 219 $self->sendCmd( $cmd ); 220} 221 222#Zoom Out 223sub zoomConWide 224{ 225 my $self = shift; 226 Debug( "Zoom Wide" ); 227 my $cmd = "decoder_control.cgi?command=16"; 228 $self->sendCmd( $cmd ); 229} 230 231#Diagonally Up Right Arrow 232#This camera does not have builtin diagonal commands so we emulate them 233sub moveConUpRight 234{ 235 my $self = shift; 236 Debug( "Move Diagonally Up Right" ); 237 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=upright&-speed=45"; 238 $self->sendCmd( $cmd ); 239} 240 241#Diagonally Down Right Arrow 242#This camera does not have builtin diagonal commands so we emulate them 243sub moveConDownRight 244{ 245 my $self = shift; 246 Debug( "Move Diagonally Down Right" ); 247 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=downright&-speed=45"; 248 $self->sendCmd( $cmd ); 249} 250 251#Diagonally Up Left Arrow 252#This camera does not have builtin diagonal commands so we emulate them 253sub moveConUpLeft 254{ 255 my $self = shift; 256 Debug( "Move Diagonally Up Left" ); 257 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=upleft&-speed=45"; 258 $self->sendCmd( $cmd ); 259} 260 261#Diagonally Down Left Arrow 262#This camera does not have builtin diagonal commands so we emulate them 263sub moveConDownLeft 264{ 265 my $self = shift; 266 Debug( "Move Diagonally Down Left" ); 267 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=downnleft&-speed=45"; 268 $self->sendCmd( $cmd ); 269} 270 271#Set Camera Preset 272#Presets must be translated into values internal to the camera 273#Those values are: 30,32,34,36,38,40,42,44 for presets 1-8 respectively 274sub presetSet 275{ 276 my $self = shift; 277 my $params = shift; 278 my $preset = $self->getParam( $params, 'preset' ); 279 Debug( "Set Preset $preset" ); 280 281 if (( $preset >= 1 ) && ( $preset <= 8 )) { 282 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=preset&-act=set&-number=".(($preset*2) + 28); 283 $self->sendCmd( $cmd ); 284 } 285} 286 287#Recall Camera Preset 288#Presets must be translated into values internal to the camera 289#Those values are: 31,33,35,37,39,41,43,45 for presets 1-8 respectively 290sub presetGoto 291{ 292 my $self = shift; 293 my $params = shift; 294 my $preset = $self->getParam( $params, 'preset' ); 295 Debug( "Goto Preset $preset" ); 296 297 if (( $preset >= 1 ) && ( $preset <= 8 )) { 298 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=preset&-act=goto&-number=".(($preset*2) + 29); 299 $self->sendCmd( $cmd ); 300 } 301 302 if ( $preset == 9 ) { 303 $self->horizontalPatrol(); 304 } 305 306 if ( $preset == 10 ) { 307 $self->verticalPatrol(); 308 } 309} 310 311#Horizontal Patrol 312sub horizontalPatrol 313{ 314 my $self = shift; 315 Debug( "Horizontal Patrol" ); 316 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=hscan"; 317 $self->sendCmd( $cmd ); 318} 319 320#Vertical Patrol 321sub verticalPatrol 322{ 323 my $self = shift; 324 Debug( "Vertical Patrol" ); 325 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=vscan"; 326 $self->sendCmd( $cmd ); 327} 328 329# Increase Brightness 330sub irisAbsOpen 331{ 332 my $self = shift; 333 my $params = shift; 334 $self->getCamParams() unless($CamParams{'brightness'}); 335 my $step = $self->getParam( $params, 'step' ); 336 337 $CamParams{'brightness'} += $step; 338 $CamParams{'brightness'} = 100 if ($CamParams{'brightness'} > 100); 339 Debug( "Increase Brightness" ); 340 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-brightness=".$CamParams{'brightness'}; 341 $self->sendCmd( $cmd ); 342} 343 344# Decrease Brightness 345sub irisAbsClose 346{ 347 my $self = shift; 348 my $params = shift; 349 $self->getCamParams() unless($CamParams{'brightness'}); 350 my $step = $self->getParam( $params, 'step' ); 351 352 $CamParams{'brightness'} -= $step; 353 $CamParams{'brightness'} = 0 if ($CamParams{'brightness'} < 0); 354 Debug( "Decrease Brightness" ); 355 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-brightness=".$CamParams{'brightness'}; 356 $self->sendCmd( $cmd ); 357} 358 359# Increase Contrast 360sub whiteAbsIn 361{ 362 my $self = shift; 363 my $params = shift; 364 $self->getCamParams() unless($CamParams{'contrast'}); 365 my $step = $self->getParam( $params, 'step' ); 366 367 $CamParams{'contrast'} += $step; 368 $CamParams{'contrast'} = 100 if ($CamParams{'contrast'} > 100); 369 Debug( "Increase Contrast" ); 370 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-contrast=".$CamParams{'contrast'}; 371 $self->sendCmd( $cmd ); 372} 373 374# Decrease Contrast 375sub whiteAbsOut 376{ 377 my $self = shift; 378 my $params = shift; 379 $self->getCamParams() unless($CamParams{'contrast'}); 380 my $step = $self->getParam( $params, 'step' ); 381 382 $CamParams{'contrast'} -= $step; 383 $CamParams{'contrast'} = 0 if ($CamParams{'contrast'} < 0); 384 Debug( "Decrease Contrast" ); 385 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-contrast=".$CamParams{'contrast'}; 386 $self->sendCmd( $cmd ); 387} 388 389#TODO Saturation cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=44 [0-255] 390sub satIncrease 391{ 392 my $self = shift; 393 my $params = shift; 394 $self->getCamParams() unless($CamParams{'saturation'}); 395 my $step = $self->getParam( $params, 'step' ); 396 397 $CamParams{'saturation'} += $step; 398 $CamParams{'saturation'} = 255 if ($CamParams{'saturation'} > 255); 399 Debug( "Increase Saturation" ); 400 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=".$CamParams{'saturation'}; 401 $self->sendCmd( $cmd ); 402} 403 404sub satDecrease 405{ 406 my $self = shift; 407 my $params = shift; 408 $self->getCamParams() unless($CamParams{'saturation'}); 409 my $step = $self->getParam( $params, 'step' ); 410 411 $CamParams{'saturation'} -= $step; 412 $CamParams{'saturation'} = 0 if ($CamParams{'saturation'} < 0); 413 Debug( "Decrease Saturation" ); 414 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=".$CamParams{'saturation'}; 415 $self->sendCmd( $cmd ); 416} 417#TODO Sharpness cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=37 [0-100] 418sub sharpIncrease 419{ 420 my $self = shift; 421 my $params = shift; 422 $self->getCamParams() unless($CamParams{'sharpness'}); 423 my $step = $self->getParam( $params, 'step' ); 424 425 $CamParams{'sharpness'} += $step; 426 $CamParams{'sharpness'} = 100 if ($CamParams{'sharpness'} > 100); 427 Debug( "Increase Sharpness" ); 428 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=".$CamParams{'sharpness'}; 429 $self->sendCmd( $cmd ); 430} 431 432sub sharpDecrease 433{ 434 my $self = shift; 435 my $params = shift; 436 $self->getCamParams() unless($CamParams{'sharpness'}); 437 my $step = $self->getParam( $params, 'step' ); 438 439 $CamParams{'sharpness'} -= $step; 440 $CamParams{'sharpness'} = 0 if ($CamParams{'sharpness'} < 0); 441 Debug( "Decrease Sharpness" ); 442 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=".$CamParams{'sharpness'}; 443 $self->sendCmd( $cmd ); 444} 445 446#TODO Hue cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=37 [0-100] 447sub hueIncrease 448{ 449 my $self = shift; 450 my $params = shift; 451 $self->getCamParams() unless($CamParams{'hue'}); 452 my $step = $self->getParam( $params, 'step' ); 453 454 $CamParams{'hue'} += $step; 455 $CamParams{'hue'} = 100 if ($CamParams{'hue'} > 100); 456 Debug( "Increase Hue" ); 457 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=".$CamParams{'hue'}; 458 $self->sendCmd( $cmd ); 459} 460 461sub hueDecrease 462{ 463 my $self = shift; 464 my $params = shift; 465 $self->getCamParams() unless($CamParams{'hue'}); 466 my $step = $self->getParam( $params, 'step' ); 467 468 $CamParams{'hue'} -= $step; 469 $CamParams{'hue'} = 0 if ($CamParams{'hue'} < 0); 470 Debug( "Decrease Hue" ); 471 my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=".$CamParams{'hue'}; 472 $self->sendCmd( $cmd ); 473} 474 4751; 476