Hikvision Camera API - Switching to day/night mode

TWallace

Young grasshopper
Dec 26, 2015
62
12
Shoreline, WA
I'm trying to switch day/night profile for one camera using a NodeJS module. I've found an npm module which looks promising: node-hikvision-api. However, some of the commands it sends are returning 404 responses from the camera.

Here's an example response I get when trying to switch to night mode:
<!DOCTYPE html>
<html><head><title>Document Error: Not Found</title></head>
<body><h2>Access Error: 404 -- Not Found</h2>
<p>Can't locate document: /cgi-bin/configManager.cgi</p>
</body>
</html>

Here's the URL it's hitting to get the above response:
http://{MY_CAMERA_IP}:80/cgi-bin/configManager.cgi?action=setConfig&VideoInMode[0].Config[0]=1

Interestingly when I Google that URL path I get many results about Dahua cameras, but not much regarding Hikvision cameras. Do they use similar APIs?

The reason I'd like to use this is because this particular camera is near a porch light and as a result it never switches to night mode on its own. This causes it to only have night visibility where the porch light shines. I'd like setup a schedule based on sunrise/sunset time to send commands to force it to switch to day/night mode as needed.

Hikvision seems to be very unforthcoming with API details. Maybe this URL no longer exists on this version of the firmware? The camera firmware version is V5.4.0 build 160530 and the model is DS-2CD2132F-IS.
 
I think you found some code that controls Dahua cams. HIKvision's API is quite different.

I found their HTTP API described in this document. I also used Wireshark to see that the web UI for my HIKvision camera uses the same API as in the document.

The odd thing with HIKvision is you can't set the camera to day or night mode with the API. You can only set it to Auto or to Scheduled with a time to start and stop day mode. I have my camera set to scheduled but I didn't write notes as to why I chose that instead of Auto. I suspect the motion sensor security light was making it think day mode at night which would set the exposure time too high and make the image too dark...

EDIT: I see why I used scheduled switch - in Auto switch, you can't have different day and night exposure settings. I want 1/1000 exposure in the day and 1/100 at night. Of course, simply changing to Auto mode and back to scheduled lost my day and night settings... Terrible design.

Unfortunately, as the sunset time changed, my scheduled night mode became increasingly wrong. So it seems like the only solution is to use the API to adjust the schedule. I worry that adjusting it once a day to match sunrise and sunset might wear out the NVRAM the camera uses to save its settings so I think I'll update the schedule maybe twice a month.

This curl command works on my camera (DS-2CD2632F-IS) from a Raspberry Pi (change IP to match IP of your camera):
Code:
curl -s --basic --netrc-file /home/pi/CameraLogins.txt "http://192.168.123.123/ISAPI/Image/channels/1/ISPMode" -X PUT -H "Content-Type: text/xml; charset=UTF-8" -d "<?xml version="1.0" encoding="UTF-8"?><ISPMode><mode>schedule</mode><Schedule><scheduleType>day</scheduleType><TimeRange><beginTime>07:30:00</beginTime><endTime>16:30:00</endTime></TimeRange></Schedule></ISPMode>"

Successful response to the command looks like this, plus you'll see changes in the web UI if you refresh the page:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ResponseStatus version="2.0" xmlns="http://www.hikvision.com/ver20/XMLSchema">
<requestURL>/ISAPI/Image/channels/1/ISPMode</requestURL>
<statusCode>1</statusCode>
<statusString>OK</statusString>
<subStatusCode>ok</subStatusCode>
</ResponseStatus>

/home/pi/CameraLogins.txt should contain (change IP to match IP of your camera):
Code:
machine 192.168.123.123 login admin password <camera password>

Give CameraLogins.txt read-write permission only for pi user:
Code:
chmod 600 /home/pi/CameraLogins.txt
chown pi:pi /home/pi/CameraLogins.txt

See also this thread which has some Python code for sunrise/sunset time.
 
Last edited:
  • Like
Reactions: TWallace
Thanks a lot for looking into this. Strange that someone wrote an npm module (presumably) for interacting with Hikvision cameras and it features code meant for Dahua cameras instead. You can see in the source code here that it's using the configManager endpoints: node-hikvision-api/hikvision.js at master · nayrnet/node-hikvision-api · GitHub. I will give your code a shot soon. I think updating the schedule 1-2 times per month should be adequate, like you said.
 
Here's code I wrote in Perl that works in MisterHouse in case it's useful to anyone. Many of the methods used are only available in MisterHouse (like $Time_Sunrise and my_str2time()) but the general ideas can be adapted. Note that the farther you move from the equator, the faster the sunrise/set times can change each day.

Code:
if(time_now("03:00")) {
    # HIKvision doesn't let you set day/night mode in the API or
    # the web GUI.  You can only set a schedule for day/night mode.
    # I don't want to adjust that schedule daily because it will
    # wear the NVRAM, so adjust it on the 1st and 15th of each
    # month.
    # When $isdst != $yesterday[8] it means the clock changed at 2am,
    # an hour ago, so we need to update the camera's schedule for
    # tomorrow.  I tested a version of this DST code on the command
    # line that pretended it was Nov 5, 2017 and it evaluated true.
    my @yesterday = localtime(time - 60*60*24);
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    if($mday == 1 || $mday == 15 || $isdst != $yesterday[8]) {
        # 15-day change in sunrise/sunset times in Los Angeles, CA are
        # from http://aa.usno.navy.mil/data/docs/mrst.php
        # I checked only the solstices and equinoxes at first, then found
        # I needed to check the beginning of each month to be sure
        # how far the sunrise/set could shift.  I assume you could find
        # the max shift in your area by just checking Feb 01-15 and
        # Mar 15-29.
            # Jan 01-15: 6:59-6:59 (1min), 16:56-17:08 (12min)
            # Feb 01-15: 6:50-6:38 (-12min), 17:24-17:38 (14min)
            # Mar 01-15: 6:22-6:09 (-13min), 17:50-17:58 (8min)
            # Mar 15-29: 7:03-6:44 (-19min), 19:02-19:12 (10min)
            # Apr 01-15: 6:40-6:22 (-18min), 19:15-19:25 (10min)
            # May 01-15: 6:04-5:52 (-12min, 19:38-19:48 (10min)
            # Jun 01-15: 5:43-5:42 (-1min), 20:00-20:07 (7min)
            # Jun 15-29: 5:42-5:45 (3min), 20:07-20:09 (2min)
            # Jul 01-15: 5:46-5:53 (7min), 20:09-20:05 (-4min)
            # Aug 01-15: 5:38-5:49 (11min), 19:54-19:40 (-14min)
            # Sep 01-15: 6:27-6:37 (10min), 19:19-19:00 (-19min)
            # Sep 15-29: 6:37-6:47 (10min), 19:00-18:40 (-20min)
            # Oct 01-15: 6:48-6:59 (11min), 18:37-18:19 (-18min)
            # Nov 01-15: 6:13-6:26 (13min), 17:00-16:50 (-10min)
            # Dec 01-15: 6:41-6:52 (11min), 16:44-16:46 (2min)
            # Dec 15-29: 6:52-6:59 (7min), 16:46-16:53 (7min)
        # It's now 3am so we'll set the camera's schedule based
        # on sunrise/set for today.  If we just went through a DST
        # change at 2am, $Time_Sunrise/Sunset should definitely be
        # in terms of the new DST setting at this point.
        # The most sunrise/set can change in the next 15 days is +13
        # or -19min so set the schedule to start day mode sunrise +5
        # +19 mins.  The worst that will happen by delaying day
        # mode a little is some unnecessary motion blur.
        # For night mode, sunset will move up to +14 or -20 min,
        # and we'd rather err on the side of an earlier night
        # setting, so use sunset -5 -14 mins.
        my $startTime = strftime("%H:%M:%S", localtime(my_str2time(
            "$Time_Sunrise+0:24")));
        my $endTime = strftime("%H:%M:%S", localtime(my_str2time(
            "$Time_Sunset-0:19")));
   
        main::print_log("\n\n\n ***** Set camera day mode schedule to "
            . $startTime . " to " . $endTime . ".\n\n\n\n\n");
        my $sysCmd = 'curl -s --basic --netrc-file /home/pi/CameraLogins.txt '
            . '"http://192.168.123.123/ISAPI/Image/channels/1/ISPMode" -X PUT '
            . '-H "Content-Type: text/xml; charset=UTF-8" '
            . '-d "<?xml version="1.0" encoding="UTF-8"?><ISPMode>'
            . '<mode>schedule</mode><Schedule><scheduleType>day</scheduleType>'
            . '<TimeRange><beginTime>' . $startTime
            . '</beginTime><endTime>' . $endTime
            . '</endTime></TimeRange></Schedule></ISPMode>" >/dev/null';
        my $sysResult = system($sysCmd);
        if($sysResult != 0) {
            main::print_log("\n\n\n ***** $sysCmd failed with error "
                . ($sysResult >> 8) . "\n\n\n");
        }
    }
}
 
Last edited: