DS-KD8003 - DS-KV8113 - DS-KV8213 - DS-KV6113 - DS-KV8413 and .... integration Hikvision HikConnect Video intercom doorbell

but the docker image does not start, i cannot access it , any idea how i could debug the issue ?

that looks indeed, good, but i think you didnt create the template sensor? you created another sensor based on isapi callstatus , thats something else
you need to create a template sensor for the SDK, so thats why its failing

the rest sensor is for the callstatus with ISAPI, you dont need that one (if the SDK provides the callstatus offcourse)

why doesnt it start? what error do you have?

yes, you had that the error that the lib files were not found? thats why the docker doesnt start, because the hik.py isnt able to start, ok, if you look at the Dockerfile
comment this line
CMD [ "python3", "hik.py" ]

and uncomment
#ENTRYPOINT ["tail", "-f", "/dev/null"]

that way you dockers starts, i also did then when i was testing
then you can access the docker and have a look at the folders, to actually see if the lib folder is missing, you can also strart then the script from within docker

Is there an example script for creating an SDK based sensor?

first of all thanks a lot for your effort, the file is there and running hik.py the issue remains, no idea where the error comes from (maybe something python related )?

I have a hunch that the docker instance that launches within HA is not compatible with the SDK.

I don’t understand either, have you tried the 32bit lib folder? Are you running 32 bit host system? I run a 64 bit system… I don’t think it’s related to the complaine, because the docker image is build on debian, that’s the reason why I need to use a docker in my case… Because my host is alpine (HAssos) doesn’t work either…

Also if it’s a complance error, it should display another error ,it would display somekind of login error, but thats a step further…

Can you play with the path in that second .py file? I believe I now used like ./lib. …

Maybe copy all files to the root instead of using a folder, … You are no inside the docker anyway…
Make sure you change the .py file where it points to the .so file

Is there an example for creating an SDK based sensor? I created a template sensor but it does not seem to receive anything:

My hik.py file (updated):

from hcnetsdk import HCNetSDK, NET_DVR_DEVICEINFO_V30, NET_DVR_DEVICEINFO_V30, NET_DVR_SETUPALARM_PARAM, fMessageCallBack, COMM_ALARM_V30, COMM_ALARM_VIDEO_INTERCOM, NET_DVR_VIDEO_INTERCOM_ALARM, NET_DVR_ALARMINFO_V30, ALARMINFO_V30_ALARMTYPE_MOTION_DETECTION, VIDEO_INTERCOM_ALARM_ALARMTYPE_DOORBELL_RINGING, VIDEO_INTERCOM_ALARM_ALARMTYPE_DISMISS_INCOMING_CALL, VIDEO_INTERCOM_ALARM_ALARMTYPE_TAMPERING_ALARM, VIDEO_INTERCOM_ALARM_ALARMTYPE_DOOR_NOT_CLOSED, COMM_UPLOAD_VIDEO_INTERCOM_EVENT, NET_DVR_VIDEO_INTERCOM_EVENT, VIDEO_INTERCOM_EVENT_EVENTTYPE_UNLOCK_LOG, VIDEO_INTERCOM_EVENT_EVENTTYPE_ILLEGAL_CARD_SWIPING_EVENT, NET_DVR_UNLOCK_RECORD_INFO
from ctypes import POINTER, cast, c_char_p, c_byte

def callback(command: int, alarmer_pointer, alarminfo_pointer, buffer_length, user_pointer):
    if (command == COMM_ALARM_V30):
        alarminfo_alarm_v30: NET_DVR_ALARMINFO_V30 = cast(
            alarminfo_pointer, POINTER(NET_DVR_ALARMINFO_V30)).contents
        if (alarminfo_alarm_v30.dwAlarmType == ALARMINFO_V30_ALARMTYPE_MOTION_DETECTION):
            print(f"Motion detected")
        else:
            print(
                f"COMM_ALARM_V30, unhandled dwAlarmType: {alarminfo_alarm_v30.dwAlarmType}")
    elif(command == COMM_ALARM_VIDEO_INTERCOM):
        alarminfo_alarm_video_intercom: NET_DVR_VIDEO_INTERCOM_ALARM = cast(
            alarminfo_pointer, POINTER(NET_DVR_VIDEO_INTERCOM_ALARM)).contents        
        if (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DOORBELL_RINGING):
            print("Doorbell ringing")
            # Doorbell ringing sensor
            try:
                print("Sensor Callstatus updating...")
                set_attribute(sensor_name, "Callstatus", "On")
                time.sleep(1)
                set_attribute(sensor_name, "Callstatus", "Off")
            except:
                print("Sensor updating failed")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DISMISS_INCOMING_CALL):
            print("Call dismissed")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_TAMPERING_ALARM):
            print("Tampering alarm")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DOOR_NOT_CLOSED):
            print("Door not closed")
        else:
            print(
                f"COMM_ALARM_VIDEO_INTERCOM, unhandled byAlarmType: {alarminfo_alarm_video_intercom.byAlarmType}")
    elif(command == COMM_UPLOAD_VIDEO_INTERCOM_EVENT):
        alarminfo_upload_video_intercom_event: NET_DVR_VIDEO_INTERCOM_EVENT = cast(
            alarminfo_pointer, POINTER(NET_DVR_VIDEO_INTERCOM_EVENT)).contents
        if (alarminfo_upload_video_intercom_event.byEventType == VIDEO_INTERCOM_EVENT_EVENTTYPE_UNLOCK_LOG):
            print(f"Unlocked by: {list(alarminfo_upload_video_intercom_event.uEventInfo.struUnlockRecord.byControlSrc)}")
            # Door open sensor
            try:
                print("Sensor Door updating...")
                set_attribute(sensor_name, "Door", "On")
                time.sleep(1)
                set_attribute(sensor_name, "Door", "Off")
            except:
                print("Sensor updating failed")
        elif (alarminfo_upload_video_intercom_event.byEventType == VIDEO_INTERCOM_EVENT_EVENTTYPE_ILLEGAL_CARD_SWIPING_EVENT):
            print(f"Illegal card swiping")
        else:
            print(
                f"COMM_ALARM_VIDEO_INTERCOM, unhandled byEventType: {alarminfo_upload_video_intercom_event.byEventType}")
    else:
        print(f"Unhandled command: {command}")

def set_attribute(sensor_name, attribute, value):
    response = requests.get(url_states + sensor_name, headers=headers)
    msg = json.loads(response.text)
    msg['attributes'][attribute] = value
    payload = json.dumps({'state':  msg['state'], 'attributes': msg['attributes']})
    requests.post(url_states + sensor_name, headers=headers, data=payload)


HCNetSDK.NET_DVR_Init()
HCNetSDK.NET_DVR_SetValidIP(0, True)

device_info = NET_DVR_DEVICEINFO_V30()

user_id = HCNetSDK.NET_DVR_Login_V30("192.168.1.61".encode('utf-8'), 8000, "admin".encode('utf-8'),
                                     "*****".encode('utf-8'), device_info)

if (user_id < 0):
    print(
        f"NET_DVR_Login_V30 failed, error code = {HCNetSDK.NET_DVR_GetLastError()}")
    HCNetSDK.NET_DVR_Cleanup()
    exit(1)

alarm_param = NET_DVR_SETUPALARM_PARAM()
alarm_param.dwSize = 20
alarm_param.byLevel = 1
alarm_param.byAlarmInfoType = 1
alarm_param.byFaceAlarmDetection = 1

alarm_handle = HCNetSDK.NET_DVR_SetupAlarmChan_V41(user_id, alarm_param)

if (alarm_handle < 0):
    print(
        f"NET_DVR_SetupAlarmChan_V41 failed, error code = {HCNetSDK.NET_DVR_GetLastError()}")
    HCNetSDK.NET_DVR_Logout_V30(user_id)
    HCNetSDK.NET_DVR_Cleanup()
    exit(2)

# Change HA Variables sensor name + bearer
url_states = "http://192.168.1.39:8123/api/states/sensor.hikvision_test"
sensor_name = "sensor.hikvision_test"
headers = {
    'Authorization: BEARER XXXXXXXX',
    'content-type: application/json',
}

message_callback = fMessageCallBack(callback)
HCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, message_callback, user_id)

input("Press Enter to exit...\n")

HCNetSDK.NET_DVR_CloseAlarmChan_V30(alarm_handle)
HCNetSDK.NET_DVR_Logout_V30(user_id)
HCNetSDK.NET_DVR_Cleanup()

and here is the updated config.yaml I created:


# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:

# Text to speech
tts:
  - platform: google_translate
sensor:
  - platform: template
    sensors:
      hikvision_test:
        value_template: "hikvision_test"
group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
sensor: !include sensor.yaml
frontend:
  themes: !include_dir_merge_named themes
camera:
  - platform: ffmpeg
    still_image_url: http://admin:******@192.168.1.61/jpeg/view.html
    input: "rtsp://admin:*******@192.168.1.61:554/cam1/h264"
        name: Intercom

and the sensor.yaml file:

    sensors:
      hikvision_test:
        value_template: "Hikvision TEST"

??? Why do. You have 2 time sensors? One in your config and one in your sensor file???
Also for the url_states, you added the sensor name at the end of the string? That’s not needed , look again at my original file…

But to test if your rest command works , try the rest API command from terminal/putty with a curl command…

If that works, then you know your rest API works, it should also work then from the script, it’s the same method

try this command from a terminal, offcourse change:
bearer + ip + sensor name

curl -X POST -H "Authorization: Bearer YOURTOKENHERE" -d '{"state": "test","attributes": {"call_status": "ON"}}' http://YOURIP:8123/api/states/sensor.NAMEOFYOURSENSOR

and see if your sensor changes, than at least you know you can send rest commands…

then change your hik.py …
BUT if you change something in your addon in code uninstall / reinstall the addon, otherwise, it doesnt take the change, or change the version in the config.json file, and update the addon to that version

Right, but remember there is no reinstall, this is running in windows using command line

ah ok, and does it work now? it should be quite simple

hiko lovelace sensor

But my hik.py incommand line sends nothing to the sensor. It is possible the issue is with the hik.py file.how do I create additional sensors for each thing, like doorbell press, motion alert,. card swipe OK, door unlock and so on.

post your test curl , and also your code modified hik.py , should work…
do you still get sensor updating failed?

you only need 1 sensor, the callstatus is an attribute and also the open door event is an attribute…
i only created those 2 , you can also make attributes for motion detection

if you add more events, just add those parts to the hik.py file , like i did
in example below, the “callstatus” and “door” is an attribute of the hikvision sensor

curl command:

➜  ~ curl -X POST -H "Authorization: Bearer XXXXXXX" -d '{"state": "test","attributes": {"call_status": "yoohoo"}}' http://192.168.1.39:8123/api/states/sensor.hikvision_test
{"entity_id": "sensor.hikvision_test", "state": "test", "attributes": {"call_status": "yoohoo"}, "last_changed": "2021-11-19T16:35:51.183168+00:00", "last_updated": "2021-11-19T16:35:51.183168+00:00", "context": {"id": "22ffd9a3b2b17f57df3cbe955be962e1", "parent_id": null, "user_id": "cb020e0015c94e4d82a035aae2a99f5d"}}#  

hik.py:

from hcnetsdk import HCNetSDK, NET_DVR_DEVICEINFO_V30, NET_DVR_DEVICEINFO_V30, NET_DVR_SETUPALARM_PARAM, fMessageCallBack, COMM_ALARM_V30, COMM_ALARM_VIDEO_INTERCOM, NET_DVR_VIDEO_INTERCOM_ALARM, NET_DVR_ALARMINFO_V30, ALARMINFO_V30_ALARMTYPE_MOTION_DETECTION, VIDEO_INTERCOM_ALARM_ALARMTYPE_DOORBELL_RINGING, VIDEO_INTERCOM_ALARM_ALARMTYPE_DISMISS_INCOMING_CALL, VIDEO_INTERCOM_ALARM_ALARMTYPE_TAMPERING_ALARM, VIDEO_INTERCOM_ALARM_ALARMTYPE_DOOR_NOT_CLOSED, COMM_UPLOAD_VIDEO_INTERCOM_EVENT, NET_DVR_VIDEO_INTERCOM_EVENT, VIDEO_INTERCOM_EVENT_EVENTTYPE_UNLOCK_LOG, VIDEO_INTERCOM_EVENT_EVENTTYPE_ILLEGAL_CARD_SWIPING_EVENT, NET_DVR_UNLOCK_RECORD_INFO
from ctypes import POINTER, cast, c_char_p, c_byte

def callback(command: int, alarmer_pointer, alarminfo_pointer, buffer_length, user_pointer):
    if (command == COMM_ALARM_V30):
        alarminfo_alarm_v30: NET_DVR_ALARMINFO_V30 = cast(
            alarminfo_pointer, POINTER(NET_DVR_ALARMINFO_V30)).contents
        if (alarminfo_alarm_v30.dwAlarmType == ALARMINFO_V30_ALARMTYPE_MOTION_DETECTION):
            print(f"Motion detected")
        else:
            print(
                f"COMM_ALARM_V30, unhandled dwAlarmType: {alarminfo_alarm_v30.dwAlarmType}")
    elif(command == COMM_ALARM_VIDEO_INTERCOM):
        alarminfo_alarm_video_intercom: NET_DVR_VIDEO_INTERCOM_ALARM = cast(
            alarminfo_pointer, POINTER(NET_DVR_VIDEO_INTERCOM_ALARM)).contents        
        if (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DOORBELL_RINGING):
            print("Doorbell ringing")
            # Doorbell ringing sensor
            try:
                print("Sensor Callstatus updating...")
                set_attribute(sensor_name, "Callstatus", "On")
                time.sleep(1)
                set_attribute(sensor_name, "Callstatus", "Off")
            except:
                print("Sensor updating failed")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DISMISS_INCOMING_CALL):
            print("Call dismissed")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_TAMPERING_ALARM):
            print("Tampering alarm")
        elif (alarminfo_alarm_video_intercom.byAlarmType == VIDEO_INTERCOM_ALARM_ALARMTYPE_DOOR_NOT_CLOSED):
            print("Door not closed")
        else:
            print(
                f"COMM_ALARM_VIDEO_INTERCOM, unhandled byAlarmType: {alarminfo_alarm_video_intercom.byAlarmType}")
    elif(command == COMM_UPLOAD_VIDEO_INTERCOM_EVENT):
        alarminfo_upload_video_intercom_event: NET_DVR_VIDEO_INTERCOM_EVENT = cast(
            alarminfo_pointer, POINTER(NET_DVR_VIDEO_INTERCOM_EVENT)).contents
        if (alarminfo_upload_video_intercom_event.byEventType == VIDEO_INTERCOM_EVENT_EVENTTYPE_UNLOCK_LOG):
            print(f"Unlocked by: {list(alarminfo_upload_video_intercom_event.uEventInfo.struUnlockRecord.byControlSrc)}")
            # Door open sensor
            try:
                print("Sensor Door updating...")
                set_attribute(sensor_name, "Door", "On")
                time.sleep(1)
                set_attribute(sensor_name, "Door", "Off")
            except:
                print("Sensor updating failed")
        elif (alarminfo_upload_video_intercom_event.byEventType == VIDEO_INTERCOM_EVENT_EVENTTYPE_ILLEGAL_CARD_SWIPING_EVENT):
            print(f"Illegal card swiping")
        else:
            print(
                f"COMM_ALARM_VIDEO_INTERCOM, unhandled byEventType: {alarminfo_upload_video_intercom_event.byEventType}")
    else:
        print(f"Unhandled command: {command}")

def set_attribute(sensor_name, attribute, value):
    response = requests.get(url_states + sensor_name, headers=headers)
    msg = json.loads(response.text)
    msg['attributes'][attribute] = value
    payload = json.dumps({'state':  msg['state'], 'attributes': msg['attributes']})
    requests.post(url_states + sensor_name, headers=headers, data=payload)


HCNetSDK.NET_DVR_Init()
HCNetSDK.NET_DVR_SetValidIP(0, True)

device_info = NET_DVR_DEVICEINFO_V30()

user_id = HCNetSDK.NET_DVR_Login_V30("192.168.1.61".encode('utf-8'), 8000, "admin".encode('utf-8'),
                                     "*********".encode('utf-8'), device_info)

if (user_id < 0):
    print(
        f"NET_DVR_Login_V30 failed, error code = {HCNetSDK.NET_DVR_GetLastError()}")
    HCNetSDK.NET_DVR_Cleanup()
    exit(1)

alarm_param = NET_DVR_SETUPALARM_PARAM()
alarm_param.dwSize = 20
alarm_param.byLevel = 1
alarm_param.byAlarmInfoType = 1
alarm_param.byFaceAlarmDetection = 1

alarm_handle = HCNetSDK.NET_DVR_SetupAlarmChan_V41(user_id, alarm_param)

if (alarm_handle < 0):
    print(
        f"NET_DVR_SetupAlarmChan_V41 failed, error code = {HCNetSDK.NET_DVR_GetLastError()}")
    HCNetSDK.NET_DVR_Logout_V30(user_id)
    HCNetSDK.NET_DVR_Cleanup()
    exit(2)

# Change HA Variables sensor name + bearer
url_states = "http://192.168.1.39:8123/api/states/"
sensor_name = "sensor.hikvision_test"
headers = {
    'Authorization: BEARER XXXXXX',
    'content-type: application/json',
}

message_callback = fMessageCallBack(callback)
HCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, message_callback, user_id)

input("Press Enter to exit...\n")

HCNetSDK.NET_DVR_CloseAlarmChan_V30(alarm_handle)
HCNetSDK.NET_DVR_Logout_V30(user_id)
HCNetSDK.NET_DVR_Cleanup()

That looks good, and do you see an event in the log when you open door / call ?

Do you see sensor update failed message?

Maybe your PC is blocked in HA? Do you see an error in your log of HA ? When you see sensor failed?
Try the same script on a Linux , it’s possible windows behaves different then Linux…

Alternative is to actually use the curl command inside the python script instead of working with that JSON… Just fire the curl as an OS command

Or use a webhook , that instantly runs your automation

Options enough :slight_smile:

ran a telnet test and can sucessfully connect to HA from windows.

I wish to try linux but I dont have a linux box handy at the moment.

I need to look into webhook/curl.

Any thoughts on where to get a good example script?

Thank you for all the help. When we get this all working, may I please assist you with the writing of a step-by-step guide for implementation? at the moment it is fairly hard to organize.

Further research indicates that the issue may be within the python script portion that is gathering the state and sending it off to a http end point or rest api.

I believe that there is a component missing there in order to get it working right.

Can you share one that is successful at passing along the events to HA?