Page 1 of 1

Hikvision PIR sensor

Posted: Monday 12 September 2016 14:00
by philchillbill
Hi,

Newbie here, just installed Domoticz on my Synology NAS and adding some devices. I have a DS-2CD2432F-IW ip-cam which has a built-in PIR for motion detection. I can read out its status by checking this URL in my local network:

http://192.168.0.15/IO/outputs/1/status/

which will return XML looking like

<?xml version="1.0" encoding="UTF-8"?>
<IOPortStatus xmlns="http://www.hikvision.com/ver10/XMLSchema" version="1.0">
<ioPortID>1</ioPortID>
<ioPortType>output</ioPortType>
<ioState>inactive</ioState>
</IOPortStatus>

where the 'inactive' changes to 'active' when motion is detected.

Any idea how I can set up this PIR as a trigger device in Domoticz? I added the cam as a camera with image URL for snapshots but have no idea where to add the PIR sensor.

Thanks, Phil

Re: Hikvision PIR sensor

Posted: Friday 16 September 2016 17:44
by cogliostrio
Have you seen this post here by the user nayr?

Doesn't seem to be finish with the hikvision support yet, but it might give you something to proceed from.

Re: Hikvision PIR sensor

Posted: Tuesday 06 December 2016 21:43
by philchillbill
I actually got this functionality working myself now, having setup an Intel NUC running Ubuntu as my serious Domotica server. The clue was to run a curl command from a perl script on a crontab schedule to check the ipcam's PIR-url. I did this as follows, with a backtick shell execution from perl:

Code: Select all

curl -s -u username:password http://192.168.0.15/IO/outputs/1/status &> /dev/stdout | grep ioState
and checked for 'active' or 'inactive' in the resulting status using a regex. Depending on this outcome, I used another curl to set the status of the virtual/dummy switch in Domoticz:

Code: Select all

curl -s "http://$domoticz/json.htm?type=command&param=switchlight&idx=$idxvalue&switchcmd=On
or

Code: Select all

curl -s "http://$domoticz/json.htm?type=command&param=switchlight&idx=$idxvalue&switchcmd=Off

depending on the value of ioState returned from the first curl.

Note: $domoticz is the IP-address of my Domoticz server and $idxvalue is the idx assigned to my virtual switch.

If anybody wants to try this themselves I can write it up fully.

Re: Hikvision PIR sensor

Posted: Sunday 18 December 2016 15:26
by Ipsonius
Hi,

Phil, maybe do you know another way to get the PIR status, I'm already using the I/O port with a door contact :?

Ah, if you have the full script it will be usefull, I have limited skills with bash...

Thx in advance!

Re: Hikvision PIR sensor

Posted: Wednesday 21 December 2016 16:07
by philchillbill
Well I actually did it in Perl, not bash. And as crontab jobs only run once a minute I let the perl loop a few times with sleeps in between to achieve more regular updates. Here's my script:

Code: Select all

#!/usr/bin/perl
    use v5.14;
    use LWP::Simple;  
    use JSON qw( decode_json ); 
    use utf8;
    use feature     qw< unicode_strings >;
    # Configuration section, please update to your values
    my $domoticz = "192.168.178.12:8080";  # ip and port of your Domoticz server 
    my $domo_cmd = "http://$domoticz/json.htm?type=devices&filter=all&used=true&order=Name";

    # Hash of (device idx, device name) - I only have one but it can be scaled
    my %switches=(90=>'HallPIR');
    
    my $debug=0;
    
    my $cnt=1;
    do {
     $cnt++;
     my $json = get( $domo_cmd );
     die "Could not get $domo_cmd!" unless defined $json;
     my $decoded = JSON->new->utf8(0)->decode( $json );
     my @results = @{ $decoded->{'result'} };
     my @tab;
     foreach my $f ( @results ) {
      if ($f->{"SwitchType"}) {
            $tab[$f->{"idx"}]=$f->{"Status"};
      }
     }
    
     foreach my $k (keys %switches) {
            my $device=$switches{$k};
            my $res=`curl -s -u username:passwod http://192.168.178.15/IO/outputs/1/status &> /dev/stdout | grep ioState`;
            if ($res=~m/\>active/) {print "Active: $tab[$k]\n"} else {print "Inactive: $tab[$k]\n"};
            if (($res=~m/\>active/)&&($tab[$k] eq 'Off')) {
                    #If device answered to polling and device status is Off, turn it On in Domoticz
                    if ($debug) {print "$k is On\n"};
                   `curl -s "http://$domoticz/json.htm?type=command&param=switchlight&idx=$k&switchcmd=On"`;
            } elsif (($res=~m/inactive/)&&($tab[$k] eq 'On')) {
                    #If device did NOT answer to polling and device status is On, turn it Off in Domoticz
                    if ($debug) {print "$k is Off\n"};
                   `curl -s "http://$domoticz/json.htm?type=command&param=switchlight&idx=$k&switchcmd=Off"`;
            } else {
                    if ($debug) {print "Do nothing: $k is ".$tab[$k]."\n";}
            }
     }
     sleep 5;
    } until ($cnt>10);
    $cnt=1;

Re: Hikvision PIR sensor

Posted: Sunday 26 February 2017 18:01
by philchillbill
The purist in me didn't like going out to the shell from my perl script so I rewrote it using LWP::UserAgent instead and now it's more elegant. It also updates the Domoticz log when it sees motion. I now run it every 15 minutes on a cron job and it sleeps every 5 seconds until it hits the 15 minute mark.

Code: Select all

#!/usr/bin/perl

# Reads the state of the PIR detector in a Hikvision camera and if it sees motion then a switch in Domoticz is set.

use LWP::UserAgent;
no warnings 'uninitialized';

$domo_url = '192.168.178.12:8080';
$idx=90;

$hik_url = '192.168.178.15';
$PIR_uname = 'hallpir';
$PIR_pwd = 'passwordforhikcamera';

$runs=0;

do { # loop 180 times with sleep every 5 seconds

 $runs++;

 $ua=LWP::UserAgent->new;
 $ua->timeout(5);
 $ua->credentials( $hik_url.':80', 'DS-2CD2432F-IW', $PIR_uname, $PIR_pwd );
 $response=$ua->get('http://'.$hik_url.'/IO/outputs/1/status');
 unless ($response->is_success) { 
  $err=$response->status_line;
  $msg_url='http://'.$domo_url.'/json.htm?type=command&param=addlogmessage&message=HIKVISION%20$err';
  $r=$ua->put($msg_url);
  die $response->status_line;
 }

 $res=$response->decoded_content;
 $triggered = ($res=~m/\>active/);
 
 if ( $triggered && !$set ) {
  $msg_url='http://'.$domo_url.'/json.htm?type=command&param=addlogmessage&message=Hikvision%20PIR%20Active';
  $r=$ua->put($msg_url);
  $switch_url='http://'.$domo_url.'/json.htm?type=command&param=switchlight&idx='.$idx.'&switchcmd=On';
  $r=$ua->put($switch_url);
  $set=1;
  }
 else {
  if ( !$triggered && $set ) {
   $msg_url='http://'.$domo_url.'/json.htm?type=command&param=addlogmessage&message=Hikvision%20PIR%20Inactive';
   $r=$ua->put($msg_url);
   $switch_url='http://'.$domo_url.'/json.htm?type=command&param=switchlight&idx='.$idx.'&switchcmd=Off';
   $r=$ua->put($switch_url);
   $set=0;
  }}

 sleep 5;

} while ($runs < 180); # runs for 15 mins on a cron schedule so auto-exits after 180x5 seconds = 15 mins