mezz64 / pyHik

Python wrapper for Hikvision camera event stream
MIT License
181 stars 50 forks source link

TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' #82

Open pete-leese opened 2 years ago

pete-leese commented 2 years ago

Hi,

I am a Home Assistant user, and recently installed a DYN 7608NXI HikVision NVR, however the following error appears during the integration starting, I believe that this maybe an issue with this wrapper.


Traceback (most recent call last):
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 534, in alert_stream
    self.process_stream(tree)
  File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 615, in process_stream
    state = self.fetch_attributes(etype, echid)
  File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 663, in fetch_attributes
    if sensor[1] == int(channel):
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
pete-leese commented 2 years ago

Also only a few sensors are imported, I guess it is breaking part way through the initial bootstrap. Currently integration is not functional for my NVR

mezz64 commented 2 years ago

Can you try to monitor the alertStream endpoint manually and post the output after you've let it run for ~5min, hopefully with a camera trigger captured?

This will let you monitor the alertStream, I'd expect the first one to work, but please try both and let me know what the outputs are.

curl --digest -N http://YOUR_CAM_IP/Event/notification/alertStream
or
curl --digest -N http://YOUR_CAM_IP/ISAPI/Event/notification/alertStream
pete-leese commented 2 years ago

I assume you mean the IP address of the NVR as each camera is on POE address from the NVR.

when I curl Access "curl --digest -N http://YOUR_CAM_IP/ISAPI/Event/notification/alertStream" I get the following error:

Error: 401 -- Unauthorized

mezz64 commented 2 years ago

Yes, NVR IP. Are you using digest or basic authentication? You can drop the --digest if you are using basic.

pete-leese commented 2 years ago

I think both are selected. How do I pass credentials in to authenticate with api?

mezz64 commented 2 years ago

It should ask, but if it isn't you can use the -u flag to include a username, and curl will prompt for a password:

curl -u username --digest -N http://YOUR_NVR_IP/ISAPI/Event/notification/alertStream
pete-leese commented 2 years ago

Just getting a lot of these:

`

192.168.xx.xx 80 HTTP ac:b9:2f:07:f8:85 2022-01-25T12:07:27+00:00 0 videoloss inactive videoloss alarm

--boundary Content-Type: application/xml; charset="UTF-8" Content-Length: 493`

mezz64 commented 2 years ago

That's expected as the videoloss event is used as a keep-alive in the stream. If you have a trigger type setup to notify the surveillance center it should show up in that stream when triggered.

Since your error occurs during setup, let's start by posting what you get as soon as you connect and then a snippet during a trigger. It looks like your NVR may not by posting the camera channel in the same format, but I need to see what an actual trigger looks like to determine that.

pete-leese commented 2 years ago

Gotcha, makes perfect sense.

Here is a trigger event:

<EventNotificationAlert version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
<ipAddress>192.168.xx.xx</ipAddress>
<portNo>80</portNo>
<protocolType>HTTP</protocolType>
<macAddress>ac:b9:2f:07:f8:85</macAddress>
<dynChannelID>2</dynChannelID>
<channelID>2</channelID>
<dateTime>2022-01-26T09:36:58+00:00</dateTime>
<activePostCount>1</activePostCount>
<eventType>VMD</eventType>
<eventState>active</eventState>
<eventDescription>Motion alarm</eventDescription>
<channelName>Side</channelName>
<detectionPictureTransType>url</detectionPictureTransType>
<detectionPicturesNumber>1</detectionPicturesNumber>
<bkgUrl>http://192.168.xx.xx:80/picture/Streaming/tracks/203/?name=ch00002_00010000023000776243200233348&amp;size=233348</bkgUrl>
<URLCertificationType>digest</URLCertificationType>
<targetType>human</targetType>
</EventNotificationAlert>
--boundary
Content-Type: application/xml; charset="UTF-8"
Content-Length: 493
pete-leese commented 2 years ago

Here's another:


<EventNotificationAlert version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
<ipAddress>192.168.xx.xx</ipAddress>
<portNo>80</portNo>
<protocolType>HTTP</protocolType>
<macAddress>ac:b9:2f:07:f8:85</macAddress>
<dynChannelID>1</dynChannelID>
<channelID>1</channelID>
<dateTime>2022-01-26T10:13:42+00:00</dateTime>
<activePostCount>1</activePostCount>
<eventType>linedetection</eventType>
<eventState>active</eventState>
<eventDescription>linedetection alarm</eventDescription>
<channelName>Front</channelName>
<DetectionRegionList>
<DetectionRegionEntry>
<regionID>0</regionID>
<RegionCoordinatesList>
</RegionCoordinatesList>
<detectionTarget>human</detectionTarget>
<TargetRect>
<X>0.273958</X>
<Y>0.362132</Y>
<width>0.070833</width>
<height>0.237132</height>
</TargetRect>
</DetectionRegionEntry>
</DetectionRegionList>
<detectionPictureTransType>url</detectionPictureTransType>
<detectionPicturesNumber>1</detectionPicturesNumber>
<bkgUrl>http://192.168.xx.xx:80/picture/Streaming/tracks/103/?name=ch00001_00010000476025141708800081676&amp;size=81676</bkgUrl>
<URLCertificationType>digest</URLCertificationType>
</EventNotificationAlert>
--boundary
Content-Type: application/xml; charset="UTF-8"
Content-Length: 493
pete-leese commented 2 years ago

Does this give you the information you need to resolve?

mezz64 commented 2 years ago

Almost, can you define debug logging in HASS for the hikvision parts (example below) and post a full log from startup?

logs:
   pyhik.hikvision: debug
   homeassistant.components.binary_sensor.hikvision: debug
pete-leese commented 2 years ago

Apologies for the delay.

https://pastebin.com/bnQnJqCp

pete-leese commented 2 years ago

Is that all the debug you need now or do you need anything further to get a fix released ?

pete-leese commented 2 years ago

Has this been fixed yet @mezz64 ? Cheers

mezz64 commented 2 years ago

I've not had the free time as of late to implement a fix. I'll see what I can do this coming week to get it taken care of

Mincka commented 2 years ago

Hi, same NVR and same issue. The binary sensors are created for individual channels but they stay off.

image

Since the pastebin is not available anymore, here's my debug log:

2022-06-02 15:19:02 DEBUG (Thread-3) [pyhik.hikvision] Stream Thread Started: NVR, 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx
2022-06-02 15:19:02 DEBUG (Thread-3) [pyhik.hikvision] NVR Connection Successful.
2022-06-02 15:19:20 DEBUG (Thread-3) [pyhik.hikvision] Device alerts namespace: http://www.isapi.org/ver20/XMLSchema
2022-06-02 15:19:20 ERROR (Thread-3) [root] Uncaught thread exception
Traceback (most recent call last):
File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 534, in alert_stream
self.process_stream(tree)
File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 615, in process_stream
state = self.fetch_attributes(etype, echid)
File "/usr/local/lib/python3.9/site-packages/pyhik/hikvision.py", line 663, in fetch_attributes
if sensor[1] == int(channel):
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
2022-06-02 15:24:20 DEBUG (Thread-14) [pyhik.hikvision] NVR Watchdog expired. Resetting connection.
Mincka commented 2 years ago

I have another startup log with more information:

2022-06-02 16:21:50 DEBUG (SyncWorker_3) [pyhik.hikvision] pyHik 0.3.0 initializing new hikvision device at: http://10.0.0.71
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Device info namespace: http://www.isapi.org/ver20/XMLSchema
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Device triggers namespace: http://www.isapi.org/ver20/XMLSchema
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Processed 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx as NVR Device.
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Found events: {'tamperdetection': [1, 2], 'videoloss': [1, 2], 'fielddetection': [1, 2], 'scenechangedetection': [1, 2], 'diskfull': [0]}
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Initialized Dictionary: {'Tamper Detection': [[False, 1, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283316)], [False, 2, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283334)]], 'Video Loss': [[False, 1, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283339)], [False, 2, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283342)]], 'Field Detection': [[False, 1, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283346)], [False, 2, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283348)]], 'Scene Change Detection': [[False, 1, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283352)], [False, 2, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283355)]], 'Disk Full': [[False, 0, 0, datetime.datetime(2022, 6, 2, 16, 21, 51, 283359)]]}
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Device motion namespace: http://www.isapi.org/ver20/XMLSchema
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Tamper Detection 1: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Tamper Detection.1
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Tamper Detection 2: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Tamper Detection.2
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Video Loss 1: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Video Loss.1
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Video Loss 2: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Video Loss.2
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Field Detection 1: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Field Detection.1
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Field Detection 2: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Field Detection.2
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Scene Change Detection 1: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Scene Change Detection.1
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Scene Change Detection 2: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Scene Change Detection.2
2022-06-02 16:21:51 DEBUG (SyncWorker_3) [pyhik.hikvision] Added update callback to <bound method HikvisionBinarySensor._update_callback of <Entity NVR Disk Full 0: off>> on 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Disk Full.0

But I also something more interesting. I added dirty custom debug logs to better understand what could be happening. image

The result is the following:

2022-06-02 17:04:48 DEBUG (Thread-3) [pyhik.hikvision] Device alerts namespace: http://www.isapi.org/ver20/XMLSchema
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] idtype: channelID
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] tree value: <Element '{http://www.isapi.org/ver20/XMLSchema}EventNotificationAlert' at 0xffff6415cae0>
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] tree value: b'<ns0:EventNotificationAlert xmlns:ns0="http://www.isapi.org/ver20/XMLSchema" version="2.0"><ns0:ipAddress>10.0.0.71</ns0:ipAddress><ns0:portNo>80</ns0:portNo><ns0:protocolType>HTTP</ns0:protocolType><ns0:macAddress>24:0f:9b:xx:xx:xx</ns0:macAddress><ns0:dynChannelID /><ns0:channelID /><ns0:dateTime>2022-06-02T17:04:38+02:00</ns0:dateTime><ns0:activePostCount>0</ns0:activePostCount><ns0:eventType>videoloss</ns0:eventType><ns0:eventState>inactive</ns0:eventState><ns0:eventDescription>videoloss alarm</ns0:eventDescription><ns0:channelName /></ns0:EventNotificationAlert>'
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] etype value: Video Loss
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] estate value: inactive
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] echid value: None
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] idtype: dynChannelID
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] tree value: <Element '{http://www.isapi.org/ver20/XMLSchema}EventNotificationAlert' at 0xffff6415cae0>
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] tree value: b'<ns0:EventNotificationAlert xmlns:ns0="http://www.isapi.org/ver20/XMLSchema" version="2.0"><ns0:ipAddress>10.0.0.71</ns0:ipAddress><ns0:portNo>80</ns0:portNo><ns0:protocolType>HTTP</ns0:protocolType><ns0:macAddress>24:0f:9b:xx:xx:xx</ns0:macAddress><ns0:dynChannelID /><ns0:channelID /><ns0:dateTime>2022-06-02T17:04:38+02:00</ns0:dateTime><ns0:activePostCount>0</ns0:activePostCount><ns0:eventType>videoloss</ns0:eventType><ns0:eventState>inactive</ns0:eventState><ns0:eventDescription>videoloss alarm</ns0:eventDescription><ns0:channelName /></ns0:EventNotificationAlert>'
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] etype value: Video Loss
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] estate value: inactive
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] echid value: None
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] idtype: inputIOPortID
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] idtype: dynInputIOPortID
2022-06-02 17:04:48 ERROR (Thread-3) [pyhik.hikvision] fetching attributes for etype Video Loss

As I understand it, the script is unable to get a proper channel id while enumerating the ID_TYPES.

So I just added a fallback channel ID as 0 (cf. my previous screenshot) and... I was able to get a valid event in Home Assistant for one of my field_detection sensor. 😀

Here's the complete log for the event:

2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] idtype: channelID
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] tree value: <Element '{http://www.isapi.org/ver20/XMLSchema}EventNotificationAlert' at 0xffff54c17d10>
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] tree value: b'<ns0:EventNotificationAlert xmlns:ns0="http://www.isapi.org/ver20/XMLSchema" version="2.0"><ns0:ipAddress>10.0.0.71</ns0:ipAddress><ns0:portNo>80</ns0:portNo><ns0:protocolType>HTTP</ns0:protocolType><ns0:macAddress>24:0f:9b:xx:xx:xx</ns0:macAddress><ns0:dynChannelID>1</ns0:dynChannelID><ns0:channelID>1</ns0:channelID><ns0:dateTime>2022-06-02T17:06:05+02:00</ns0:dateTime><ns0:activePostCount>1</ns0:activePostCount><ns0:eventType>fielddetection</ns0:eventType><ns0:eventState>active</ns0:eventState><ns0:eventDescription>fielddetection alarm</ns0:eventDescription><ns0:channelName>Camera 01</ns0:channelName><ns0:DetectionRegionList><ns0:DetectionRegionEntry><ns0:regionID>0</ns0:regionID><ns0:RegionCoordinatesList /><ns0:TargetRect><ns0:X>0.650000</ns0:X><ns0:Y>0.200000</ns0:Y><ns0:width>0.066000</ns0:width><ns0:height>0.176000</ns0:height></ns0:TargetRect></ns0:DetectionRegionEntry></ns0:DetectionRegionList><ns0:detectionPictureTransType>url</ns0:detectionPictureTransType><ns0:detectionPicturesNumber>1</ns0:detectionPicturesNumber><ns0:bkgUrl>http://10.0.0.71:80/picture/Streaming/tracks/103/?name=ch00001_00000000021005417420800xxxxxx&amp;size=721999</ns0:bkgUrl><ns0:URLCertificationType>digest</ns0:URLCertificationType></ns0:EventNotificationAlert>'
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] etype value: Field Detection
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] estate value: active
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] echid value: 1
2022-06-02 17:06:16 ERROR (Thread-3) [pyhik.hikvision] fetching attributes for etype Field Detection
2022-06-02 17:06:16 DEBUG (Thread-3) [pyhik.hikvision] NVR Update: Field Detection, [True, 1, 1, datetime.datetime(2022, 6, 2, 17, 6, 16, 203685)]
2022-06-02 17:06:16 DEBUG (Thread-3) [pyhik.hikvision] Update callback <bound method HikvisionBinarySensor._update_callback of <Entity NVR Field Detection 1: on>> for sensor 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Field Detection.1
[...]
2022-06-02 17:06:25 DEBUG (Thread-3) [pyhik.hikvision] Updating stale event Field Detection on CH(1)
2022-06-02 17:06:25 DEBUG (Thread-3) [pyhik.hikvision] NVR Update: Field Detection, [False, 1, 1, datetime.datetime(2022, 6, 2, 17, 6, 25, 550692)]
2022-06-02 17:06:25 DEBUG (Thread-3) [pyhik.hikvision] Update callback <bound method HikvisionBinarySensor._update_callback of <Entity NVR Field Detection 1: off>> for sensor 484a3534-xxxx-xxxx-xxxx-240f9b31xxxx.Field Detection.1

So some progress made here. ☺

Mincka commented 2 years ago

Ok, while looking for proper videoloss event in this repo, I found out that this was a known issue: https://github.com/mezz64/pyHik/issues/45#issuecomment-556910415

@pete-leese Try to disable "Notify Surveillance Center" for "Video Loss" for all your cameras. image

Mincka commented 2 years ago

Anniversary duplicate of #45 (last activity with the workaround just one year ago), but it was interesting to debug anyway. I think a basic fall back like I did could be enough to fix it. Another better solution would be to avoid fetching the attributes if the channel ID is still None after the discovery loop since we know that the code will fail after. Thanks again for this package and good luck.