Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Motion Detection events not being received #149

Closed
bradkeifer opened this issue Mar 24, 2024 · 36 comments
Closed

Motion Detection events not being received #149

bradkeifer opened this issue Mar 24, 2024 · 36 comments

Comments

@bradkeifer
Copy link

I have followed the installation instructions and am not receiving motion detection events in Home Assistant. I have validated that the motion detection events are being successfully triggered by the IP cameras (because they are triggering strobe light and audio output on motion detection) and the NVR is recording the events. I have also tried a simple test of redirecting the Alarm Host Port to port 8124 and listening for data using the command "nc -kl 8124" on the raspberry pi that hosts Home Assistant. This receives a combination of binary and ascii data that seems to correspond to the beginning and the end of the motion detection event. I have attached a hex dump of that output.

Details of my devices are:
NVR: DS-7616NI-M2 / 16P
IP Cameras: DS-2CD2387G2H-LISU/SL

config_entry-hikvision_next-74c4ee8d1c755eb59af285a77b41ed7d.json
home_assistant.log
hd.txt

I am happy to assist with fixing and/or testing to resolve this issue, but am new to HIKVision devices so am on a steep learning curve, but happy to learn.

@maciej-or
Copy link
Owner

Hi, thanks for catching details. The integration expects HTTP POST on port 8123 with body like:
<EventNotificationAlert version="2.0" xmlns="http://www.hikvision.com/ver20/XMLSchema"> <ipAddress>192.168.0.222</ipAddress> <portNo>8123</portNo> <protocol>HTTP</protocol> <macAddress>80:7c:62:00:00:00</macAddress> <channelID>1</channelID> <dateTime>2023-01-23T23:27:25+01:00</dateTime> <activePostCount>1</activePostCount> <eventType>duration</eventType> <eventState>active</eventState> <eventDescription>duration alarm</eventDescription> <channelName>yard</channelName> <DurationList> <Duration> <relationEvent>motiondetection</relationEvent> </Duration> </DurationList> <isDataRetransmission>false</isDataRetransmission> </EventNotificationAlert>
it is processed here https://github.com/maciej-or/hikvision_next/blob/main/custom_components/hikvision_next/notifications.py
A couple of users have submitted issues related to that event. I suppose some devices or firmwares send that in different format.

@bradkeifer
Copy link
Author

Thanks very much @maciej-or I will do some debugging later in the week and report back my findings. As I learn more, I will also contact HIKVision technical support to see if we can get these misbehaving firmwares modified in due course - if the firmware is the root cause of this issue. I'm hoping that there is some setting somewhere that I don't have correctly set, but that isn't revealing itself readily from the documentation I've read so far.
I see that it is common for people to point out that the HIKVision software, and documentation of it, is not good quality. From my experience so far, I am also in that camp.

@bradkeifer
Copy link
Author

I have sought assistance from HIKVision Australia on this issue as it seems that the NVR is not posting events for motion detection or any smart events. I have yet to hear back from them and will keep people updated via this issue until we have a resolution.

@maciej-or
Copy link
Owner

What about hex dump? Did you try to decode that? I see NVRs name and serial no, maybe channel and event type are in the next bytes? You could trigger a couple of events on different cameras and compare the dumps. I theory it would be possible to listen tcp and process binary payload alongside http.

@bradkeifer
Copy link
Author

I have not progressed with analysing the hex dump as yet for a couple of reasons.
It feels like it would create a complicated solution and we would not really know for sure if the reverse engineering of the data was correct and the best solution is that we get this working within the scope of the ISAPI protocol.

I found this specification of the ISAPI Core Protocol and have started analysing the hikvision_next code to see which of the three methods are being used for receiving and processing the alarms/events - see Chapter 12 of the protocol specification. From my analysis of the debug log files, I can't find evidence that any of the three specified methods are being used. I would have thought the method defined in section 12.3 Subscribe Alarm/Event in Arming Mode would be the most desirable method, but I could be wrong.

@maciej-or can you please clarify which method you have designed the integration to use?

@maciej-or
Copy link
Owner

maciej-or commented Mar 30, 2024

Hikvision_next uses 12.2 Receive Alarm/Event in Listening Mode method. Older integrations used 12.3 that's why I decided to create a new one than develop existing. Unfortunately they are very limited. Maybe it would by worth to add another method to hikvision_next? I could help a bit, do code reviews and releases. I've shared my research on Hikvision stuff in separate repo.

@bradkeifer
Copy link
Author

Thanks @maciej-or , this is great. I will see what I can learn and try to get this working - or get clear evidence of a problem with the HIKVision firmware that I can then report to HIKVision. Unfortunately, I have a lot of travel coming up, so my ability to dedicate time to this issue is going to be a challenge, but I'll do my best.

@maciej-or
Copy link
Owner

no worries, no rush, no deadlines in this project :)

@bradkeifer
Copy link
Author

bradkeifer commented Apr 1, 2024

I have made some progress with debugging the cause of this problem. I've implemented some additional debug logging and also aligned the steps to set the alarm server to explicitly align with those documented in the ISAPI Developer Guide for "Receive Alarm/Event in Listening Mode". Specifically this mean't getting the capability set of the HTTP listening server prior to setting the parameters for it by issuing a GET /ISAPI/Event/notification/httpHosts/capabilities call to the NVR and also added a call to POST /ISAPI/Event/notification/httpHosts/1/test to check if the listening server is working normally.
Both of these additional calls resulted in a HTTPStatusError with Client error '403 Forbidden' for url
Perhaps my code is not good, but if not, it looks to me as though my NVR simply doesn't support ISAP receiving alarms/events in listening mode.
@maciej-or - I'm not great with github, but is there a way I can share my code changes with you to review them and give me some advice as to whether my code is valid and/or what other things I can try?

@maciej-or
Copy link
Owner

maciej-or commented Apr 1, 2024

Create a branch from main and push to this repo or to your own fork.
If you get 403 it might be sth with permissions, see: https://github.com/maciej-or/hikvision_next?tab=readme-ov-file#hikvision-device-setup-checklist

@matthijsberg
Copy link

A quick note, perhaps this might help someone in the future. Had the same, was not receiving any triggers from the camera for events as the alarm server. Hass runs ons httpS in my case, so I re-added the camera / recorder with https:// in stead of http:// and all great now. I run a "official" signed cert on my hass instance.

@bradkeifer
Copy link
Author

A quick note, perhaps this might help someone in the future. Had the same, was not receiving any triggers from the camera for events as the alarm server. Hass runs ons httpS in my case, so I re-added the camera / recorder with https:// in stead of http:// and all great now. I run a "official" signed cert on my hass instance.

Thanks @matthijsberg In your situation, were you receiving camera feeds and did the sensors and switches for motion detection etc work when you first setup the integration with just http?

@bradkeifer
Copy link
Author

If you get 403 it might be sth with permissions, see: https://github.com/maciej-or/hikvision_next?tab=readme-ov-file#hikvision-device-setup-checklist

I've been using the admin user for the moment in order to eliminate permissions as a potential cause. Once I get it working with the admin user, then I plan to create a dedicated hass user to reduce security risks.

@bradkeifer
Copy link
Author

Create a branch from main and push to this repo or to your own fork.

I'm not able to create a branch in your repo, but have done so in my fork and generated a pull request for you to review. It would be helpful if you could test my changes in your environment to see if you get the same 403 Forbidden responses.

I have attached my home_assistant.log file, filename is startup16.log so you can see the what's happening with my NVR. I am thinking that my NVR does not support Receive Alarm/Event in Listening Mode and would like to add an additional method to use Subscribe Alarm/Event in Arming Mode to see if that works.
startup16.log

@matthijsberg
Copy link

matthijsberg commented Apr 2, 2024

A quick note, perhaps this might help someone in the future. Had the same, was not receiving any triggers from the camera for events as the alarm server. Hass runs ons httpS in my case, so I re-added the camera / recorder with https:// in stead of http:// and all great now. I run a "official" signed cert on my hass instance.

Thanks @matthijsberg In your situation, were you receiving camera feeds and did the sensors and switches for motion detection etc work when you first setup the integration with just http?

I was receiving the camera feeds, but not the sensor updates (that is a push config from the camera?) I had some sensors configured the old way (with config file in yaml) and those did give me updates, but when thinking about it, that seems to be a pull config? Perhaps my firewall is playing up here too? (Update: It's IP based, not port based, so this should not have caused the http vs https difference)

@bradkeifer
Copy link
Author

bradkeifer commented Apr 2, 2024

@maciej-or - I have returned to your suggestion to analyse the hex dump data and have used tcpdump to analyse the packets and I have made an interesting discovery. This is hot off the press and I have not had the time to learn more about how to analyse the data packets in more detail, but it does seem as though the NVR is attempting to send a POST /api/hikvsion to Home Assistant, but the packet is not a HTTP packet.
Attached is the output from tcpdump -X for the offending data packet from the NVR to Home Assistant. If anyone has any suggestions for what additional analysis I can do, I'm all ears.
I think we are getting close to identifying a bug in the NVR firmware.
malformed_packet.log

PS: Actually, after thinking this through, tcpdump might not recognise it as a HTTP packet because it is being sent to port 8123 and not a well known port for HTTP??? Perhaps this is HTTP v HTTPS related, but I tried setting HTTPS for the alarm server, but this generated errors when attempting to set the alarm server.

This is the error I get when trying to specify https for the alarm server, but still using http for the connection to the NVR.

2024-04-02 20:08:40.946 DEBUG (MainThread) [custom_components.hikvision_next.isapi] http://192.168.3.223/ISAPI/Event/notification/httpHosts {'HttpHostNotificationList': {'@version': '2.0', '@xmlns': 'http://www.isapi.org/ver20/XMLSchema', 'HttpHostNotification': {'id': '1', 'url': '/api/hikvision', 'protocolType': 'HTTP', 'parameterFormatType': 'XML', 'addressingFormatType': 'ipaddress', 'ipAddress': '192.168.4.34', 'portNo': '8123', 'httpAuthenticationMethod': 'none', 'Extensions': {'@xmlns': 'urn:selfextension:psiaext-ver10-xsd', 'intervalBetweenEvents': '0'}}}}
2024-04-02 20:08:40.946 DEBUG (MainThread) [custom_components.hikvision_next.isapi] [PUT] http://192.168.3.223/ISAPI/Event/notification/httpHosts request data is <?xml version="1.0" encoding="utf-8"?>
<HttpHostNotificationList version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema"><HttpHostNotification><id>1</id><url>/api/hikvision</url><protocolType>HTTPS</protocolType><parameterFormatType>XML</parameterFormatType><addressingFormatType>ipaddress</addressingFormatType><ipAddress>192.168.4.34</ipAddress><portNo>8123</portNo><httpAuthenticationMethod>none</httpAuthenticationMethod><Extensions xmlns="urn:selfextension:psiaext-ver10-xsd"><intervalBetweenEvents>0</intervalBetweenEvents></Extensions></HttpHostNotification></HttpHostNotificationList>
2024-04-02 20:08:41.010 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry Point Ave NVR for hikvision_next
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 504, in async_setup
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/hikvision_next/__init__.py", line 76, in async_setup_entry
    await isapi.set_alarm_server(entry.data[DATA_ALARM_SERVER_HOST], ALARM_SERVER_PATH)
  File "/config/custom_components/hikvision_next/isapi.py", line 826, in set_alarm_server
    response = await self.isapi.Event.notification.httpHosts(method=PUT, data=xml)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/hikvisionapi/hikvisionapi.py", line 311, in common_request
    response.raise_for_status()
  File "/usr/local/lib/python3.12/site-packages/httpx/_models.py", line 761, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'http://192.168.3.223/ISAPI/Event/notification/httpHosts'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400

When I Enable HTTPS Browsing on the NVR and use https for the NVR connection details, I get this error:

2024-04-02 19:59:02.908 ERROR (MainThread) [custom_components.hikvision_next.config_flow] Unexpected exception [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)
2024-04-02 19:59:55.494 ERROR (MainThread) [custom_components.hikvision_next.config_flow] ISAPI error Client error '401 Unauthorized' for url 'http://192.168.3.223/ISAPI/System/status'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401

So, it seems that I'm snookered. Suggestions welcomed.

@bradkeifer
Copy link
Author

I was receiving the camera feeds, but not the sensor updates (that is a push config from the camera?) I had some sensors configured the old way (with config file in yaml) and those did give me updates, but when thinking about it, that seems to be a pull config? Perhaps my firewall is playing up here too? (Update: It's IP based, not port based, so this should not have caused the http vs https difference)

I am receiving sensor updates when using HTTP, but these updates all happen because Home Assistant polls the NVR, so I guess Home Assistant is the one initiating the HTTP session with the NVR. You might be onto something about HTTPS. This is not an area of detailed knowledge that I have, but perhaps Home Assistant is only accepting HTTPS sessions on it's 8123 port and when the NVR is the one attempting to initiate a session, it is trying to do so using HTTP. I'll try to do some more analysis, but am quickly running out of time.

@matthijsberg
Copy link

Afaik the plugin creates a Alarm Server (Network / Advanced / Alarm Server) entry that connects to my HASS IP and port number over either http or https. I think this indicates that the camera initiates the connection (need the correct firewall entry) and that Hass needs to accept the connection on the right port number (in my case 8123) over httpS.

I run public signed (LetsEncrypt) certificates, and HASS only works over HTTPS in my case (also on my LAN). So HTTPS when first configuring this plugin.

Again, not sure this is your issue, but just some pointers. Feel free to ignore.

@bradkeifer
Copy link
Author

I think your on the money here @matthijsberg Thank you for your input, it is definitely helping me get to the bottom of my issue.

I also only have HASS working over HTTPS, including on my LAN, and I use LetsEncrypt for the certificate on my HASS machine. I need to work out how to get a certificate for the NVR. I don't want any traffic from the NVR to be going directly outside my LAN.

@matthijsberg
Copy link

matthijsberg commented Apr 2, 2024 via email

@bradkeifer
Copy link
Author

Thanks @matthijsberg
I've tried adding the self signed certificate from the NVR as a trusted certificate on the raspberry pi hosting HASS. I have HASS running in a docker container, and have added the self signed certificate to both the docker image and also the base OS of the pi and run update-ca-certificates on both and can see that they have processed the certificate file.
However, I get this error message from HASS when I use https in the URL field for the NVR when setting up the integration.

2024-04-03 15:26:28.691 ERROR (MainThread) [custom_components.hikvision_next.config_flow] Unexpected exception [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000

If I don't use https in the URL field, and only use https in the Alarm Server field, I get this error:

2024-04-03 15:34:06.897 ERROR (MainThread) [custom_components.hikvision_next.config_flow] Unexpected exception

I'm lost for ideas on how to resolve this. I recognise that I must find a way to use https between HASS and the NVR, just struggling to work out how.

@matthijsberg
Copy link

He, I'm afraid this is a bit too remote for me to be of any good help. In my case: I use a publicly signed cert (let's encrypt) on my HASS instance, and I did not need to fiddle around with any private certs. https://:8123 did the trick for me.

On the camera it creates a alarm server:
Scherm­afbeelding 2024-04-09 om 15 24 45

I use an IP (officially I think you need FQDN matching the cert, but it still works).

@maciej-or
Copy link
Owner

If you let integration to setup alarm server using checkbox 'Set alarm server using following address' it sets HTTP or HTTPS according to URL you pass in following input. Then alarm server should send notifications over proper protocol.

@Mark7714
Copy link

Suffering from this exact issue.
LetsEncrypt / own cert
Everything else in the integration working, just no alerts - always clear. Tried everything in this post.
DS-7732/NI/14-16P NVR
Motion alerts working via the app. Might try pointing alarm server to a new port (77) and installing NGINX HA add-on to convert http on internal IP:77 to https on 8123 and set Hik NVR to port 77 on HA server? It shouldnt be this hard!

@matthijsberg
Copy link

No it should not, and in my experience, is not that hard. Configure it as https, point it to port 8123 and go. No firewall in between?

@maciej-or
Copy link
Owner

Here is a simple web server which accepts POST requests and dumps them in files. Maybe it will help debugging that issue.
server.py.txt
rename it to server.py and run:
python3 server.py
in Alarm Server settings set your machine ip, port 8080 and trigger some event

@bradkeifer
Copy link
Author

I have solved this issue by doing the following:

  1. Implemented a nginx reverse proxy to allow the NVR to communicate using http and Home Assistant to communicate using https. I set the alarm server in the Hikvision Next integration to be http://<nginx_hostname>:8124/
  2. I configured nginx to listen on port 8124 and then to forward all data onto the external_url: as defined in homeassistant using the proxy_pass directive of nginx
  3. I upgraded my NVR firmware to V5.03.010 build 240606

The reasons I chose to use the reverse proxy are:

  1. I did not want to spend money to buy a certificate for the NVR
  2. My Raspberry Pi, running Home Assistant containerised, would not accept https connections using self-signed certificates and I could not work out how to make the NVR self-signed certificate trusted by both the Raspberry Pi and the Docker image.
  3. Even though I tried defining a http internal_url, my Home Assistant instance would not accept http connections via this internal_url.

So my solution is very much along the lines as proposed by @Mark7714 above.

@Mark7714
Copy link

Mark7714 commented Jul 12, 2024 via email

@bradkeifer
Copy link
Author

I'd be happy to help @Mark7714
I run HA containerised and did my nginx install directly in the raspberry pi OS, so I am mot familiar with the add-on. Is there a URL you can share for the documentation of the add-on?
I added a virtual server, listening on port 8124, inside a server block and then specified the reverse proxy config inside a location block inside that server block.
Maybe you could share a copy of your config with me and I can probably point you in the right direction.

@markatprecision
Copy link

Sorry, I'm in GUI land...
image
image
image

@Mark7714
Copy link

*NB posted those from a different account.
I've tried a few different combinations and couldn't even get it working as to the point I could browse to it manually.

@bradkeifer
Copy link
Author

I suspect you can put pure nginx configurtion into the advanced tab. Try putting this in:

server {
        server_name <hostname>;

        listen 8124;

        # Restrict access to only the NVR
        allow <IP address of your NVR>;
        deny all;

        location / {
                proxy_pass https://<your HA fully qualified domain name>:8123/;
        }
}

Replace everything between the <> brackets (including the brackets) with the appropriate hostnames and IP addresses for your configuration. The hostname you use should resolve to the same IP address that you have defined in your Alarm Server IP setting in the Hikvision NVR / IP Camera integration. You should also define your Alarm Server Port to be 8124.

If you have problems, please send me a screen shot of what you have entered into the Custom Nginx Configuration and also a screenshot of the Diagnostic sensors for your NVR from the Hikvision NVR / IP Camera integration.

@Mark7714
Copy link

Thanks. I have now got the redirect in place from http://<LOCAL_IP> to https://my.domain.com and it looks like its working. It also doesnt seem to trigger MFA when it goes to the /api/hikvision path. But my alarms aren't triggering. I upgraded the NVR firmare to the latest I could find.
image
But no luck in getting the intrusion or line crossing triggering the HA sensors within the integration. They're turned on in HA.

@bradkeifer
Copy link
Author

I've only configured and tested motion detection. Perhaps try that to see if it works?

@Mark7714 if you can get to a shell in HASSIO, check the nginx access log. If you look at the configuration files (which will probably be somewhere under /etc/nginx, you might be able to see where the access log is maintained. The default is /var/logl/nginx/access.log

If you can find that, it will show whether there has been exchange between the NVR and nginx.

Below is an extract from my log for one motion detection event:

192.168.3.223 - - [12/Jul/2024:00:38:50 +1000] "POST /api/hikvision HTTP/1.1" 200 0 "-" "HTTP_USER_AGENT"
192.168.3.223 - - [12/Jul/2024:00:38:50 +1000] "#\x00\x00\x00\xFF\x00\x02\xDF\x03\xA8\xC0" 400 157 "-" "-"

@Mark7714
Copy link

I found a tonne of these. Do they look healthy?

[12/Jul/2024:18:04:01 +1000] 301 - POST http xx.xx.xx.xx "/api/hikvision" [Client HIK_NVR] [Length 162] [Gzip -] "HTTP_USER_AGENT" "-"
[12/Jul/2024:18:04:04 +1000] 301 - POST http xx.xx.xx.xx "/api/hikvision" [Client HIK_NVR] [Length 162] [Gzip -] "HTTP_USER_AGENT" "-"
[12/Jul/2024:18:05:01 +1000] 301 - POST http xx.xx.xx.xx "/api/hikvision" [Client 1HIK_NVR] [Length 162] [Gzip -] "HTTP_USER_AGENT" "-"
[12/Jul/2024:18:05:03 +1000] 301 - POST http xx.xx.xx.xx "/api/hikvision" [Client HIK_NVR] [Length 162] [Gzip -] "HTTP_USER_AGENT" "-"
[12/Jul/2024:18:05:15 +1000] 301 - POST http xx.xx.xx.xx "/api/hikvision" [Client HIK_NVR] [Length 162] [Gzip -] "HTTP_USER_AGENT" "-"
[7/12/2024] [6:06:10 PM] [Nginx ] › ℹ info Reloading Nginx

@bradkeifer
Copy link
Author

bradkeifer commented Jul 12, 2024

I am not sure @Mark7714
I would say that they look partly positive, but I don't really know much about http exchanges to provide an informed comment.
From my Googling, code 301 is the HTTP response status code for Moved Permanently and I do not think that is good.
The format of our access logs is slightly different, but I don't think that is a problem per se.

I guess the good news is that this log is indicating that the nvr is sending data and it is being received by nginx. Perhaps have a look at the nginx error log to see if it gives you anything helpul. Mine is at /var/log/nginx/error.log

Are you using two different port numbers? One for communication between nginx and the nvr and then 8123 between nginx and home assistant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants