Search code examples
phpxmlputip-camerahikvision

How to set Hikvision camera parameters using PHP curl


I am attempting to automate Hikvision camera configuration using the Hikvision IPMD XML API. I am able to retrieve camera data using any of the documented services, but my attempts to change field values are failing. Here's the code I'm using the deviceInfo to change the System Device Name.

define('_EOL', "\n");

// Set device name
$url='http://192.168.6.12/System/deviceInfo';
$creds='admin:password';
$body='<?xml version="1.0" encoding="UTF-8"?>'.
    '<DeviceInfo xmlns="http://www.hikvision.com/ver10/XMLSchema" version="1.0">'.
    '<deviceName>Cam 7 AAAA</deviceName>'.
    '<deviceID>88</deviceID>'.
    '</DeviceInfo> ';
$tmpFile='temp.txt';
file_put_contents($tmpFile, $body);
$bytes=filesize($tmpFile);
$stream=fopen($tmpFile, 'r');
echo('Bytes='.$bytes.', handle='.$stream._EOL);

$session=curl_init(); // initialize a curl session
curl_setopt($session,CURLOPT_URL, $url);
curl_setopt($session,CURLOPT_USERPWD, $creds);
curl_setopt($session,CURLOPT_HEADER,TRUE);
curl_setopt($session,CURLOPT_RETURNTRANSFER, TRUE);
//curl_setopt($session,CURLOPT_PUT, TRUE);
curl_setopt($session,CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($session,CURLOPT_CUSTOMREQUEST, 'Content-Type: application/xml; charset="UTF-8"');
curl_setopt($session,CURLOPT_INFILE, $stream);  // XML block
curl_setopt($session,CURLOPT_INFILESIZE, $bytes); // size in bytes

$page=curl_exec($session);
$info=curl_getinfo($session);
$err='curl error: '.curl_errno($session).' '.curl_error($session);

curl_close($session);

print_r($info);
echo($err._EOL);
echo($page._EOL);

And here's the curl info on the request. It seems the camera is not responding to the request.

Bytes=185, handle=Resource id #6
Array
(
    [url] => http://192.168.6.12/System/deviceInfo
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 197
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.016
    [namelookup_time] => 0
    [connect_time] => 0.016
    [pretransfer_time] => 0.016
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => 185
    [starttransfer_time] => 0.016
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 192.168.6.12
    [primary_port] => 80
    [local_ip] => 192.168.6.99
    [local_port] => 2903
    [redirect_url] => 
)
curl error: 52 Empty reply from server

By the way, this is the camera response to GET /System/deviceInfo:

<?xml version="1.0" encoding="UTF-8"?>
<DeviceInfo version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<deviceName>Cam 2 DEMO</deviceName>
<deviceID>88</deviceID>
<deviceDescription>IPCamera</deviceDescription>
<deviceLocation>hangzhou</deviceLocation>
<systemContact>Hikvision.China</systemContact>
<model>DS-2CD2042WD-I</model>
<serialNumber>DS-2CD2042WD-I20170519BBWR764768522</serialNumber>
<macAddress>18:68:cb:76:48:ce</macAddress>
<firmwareVersion>V5.4.5</firmwareVersion>
<firmwareReleasedDate>build 170124</firmwareReleasedDate>
<bootVersion>V1.3.4</bootVersion>
<bootReleasedDate>100316</bootReleasedDate>
<hardwareVersion>0x0</hardwareVersion>
</DeviceInfo>

Previously I tried using all three EOL types (Mac, linux, DOS) before I removed them all, as in the code above. I know the authentication works because I can read anything from the camera. I can also successfully send PUT commands that have no data or XML block requirements, such as a reboot. So I suspect some issue with how I am sending the XML via curl. Also, I can change the device name via web browser while logged in. Then when I read the device information, the changes show up in the XML response. Any ideas where I've gone wrong? Thanks.

UPDATE 8/30/2018

I gave up on using the camera API for configuration. I only found a few commands that actually worked (like reboot and some read-only requests). Instead, I used Watir and Ruby to access the camera through its web interface. That has proven to be a very reliable way to automate camera configuration.


Solution

  • Almost two and a half years later, the Hikvision camera model I was using is now obsolete and the API has changed again. Because I bought the cameras from Amazon, Hikvision would not provide any support, not even to point me to a valid document on the API. So I turned to a different solution.

    I switched to using Ruby and Watir to work with the camera through the web interface. Not surprisingly, this proved difficult because the HTML on each configuration page lacked unique information to select form elements. Still, with enough work, I was able to write a script that fully automated camera configuration. Here are a few key snippets from that script.

    require 'watir-webdriver'
    require "watir-webdriver/extensions/alerts"
    
      @browser = Watir::Browser.new :chrome # chrome @browser window
    
      # Select Time Zone, index 1
      @browser.select_list(:index, 1).select_value('CST+0:00:00')
    

    The first two load Watir Webdriver, the core software that interacts with a browser. The middle line opens a chrome browser. The last two show an example of how to select a field and set the value when the field has no unique identifying labels, like an id.

    Go to the Watir website at Watir to get details.