mezz64 / pyHik

Python wrapper for Hikvision camera event stream

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

namespace for EventTriggerList differs from DeviceInfo one

thingie opened this issue · comments

Hi, I may have a weird hikvision dvr, but it uses different XML namespace in the EventTriggerList than it uses in DeviceInfo, so it cannot be properly queried.

(unimportant/personal data deleted)

€ curl http://@redacted/ISAPI/System/deviceInfo --digest 
<?xml version="1.0" encoding="UTF-8" ?>
<DeviceInfo version="1.0" xmlns="http://www.hikvision.com/ver20/XMLSchema">
<deviceName>Embedded Net DVR</deviceName>
<model>iDS-7204HUHI-K1/4S</model>
<firmwareVersion>V4.20.000</firmwareVersion>
<firmwareReleasedDate>build 181129</firmwareReleasedDate>
<hardwareVersion>0xc3520</hardwareVersion>
</DeviceInfo>

However, note that a slightly different namespace is used in the next response.

€ curl http://@redacted/ISAPI/Event/triggers --digest    
<?xml version="1.0" encoding="UTF-8" ?>
<EventTriggerList version="1.0" xmlns="http://www.hikvision.com/ver20/XMLSchema">
<EventTrigger version="1.0" xmlns="http://www.hikvision.com/ver20/mmmm/XMLSchema">
<id>IO-1</id>
<eventType>IO</eventType>
<inputIOPortID>1</inputIOPortID>
<EventTriggerNotificationList version="1.0" xmlns="http://www.hikvision.com/ver20/mmmm/XMLSchema">
</EventTriggerNotificationList>
</EventTrigger>
<EventTrigger version="1.0" xmlns="http://www.hikvision.com/ver20/mmmm/XMLSchema">
<id>IO-2</id>
<eventType>IO</eventType>
<inputIOPortID>2</inputIOPortID>
<EventTriggerNotificationList version="1.0" xmlns="http://www.hikvision.com/ver20/mmmm/XMLSchema">
</EventTriggerNotificationList>
</EventTrigger>
...

I have no idea why is this. When using the mmmm schema, it works.

Thanks for reporting. I should be able to handle this, just need to think of the best way to do it. I'll post back here when I have something to test.

I've managed to stumble on same issue using DS-7108HQHI-K1 nvr device (fw: 190722) with HassIO, which prevents creation of any binary sensors on ha. I've checked the code and managed to create rel. simple workaround, so can make PR if you're interested.

@elpiaffo PR's are always welcome. I've explored this a little bit, but haven't identified anything elegant just yet to incorporate a fix. I've been considered just doing a bit of a monkey patch on the element tree library to allow lookups without using a namespace, but would need to have that approach tested pretty well to ensure no unintended consequences.

Honestly, I just hardcoded the mmmm namespace into element_query when called from get_event_triggers because I simply wanted it to work for me and my dvr. And it does. I guess this approach can be generalized by checking for the EventTrigger namespace there in the same way as in get_device_info and using that instead. I can try and test it if you'd like. Though simply ignoring namespaces seems just fine too.

(I'd also like to understand why is the namespace different, but hikvision.)

@mezz64 yes, I know what you mean :) What I made is by no means elegant and similar to what @thingie did. I've added additional check on get_event_triggers when looking for for EventTrigger nodes with this namespace, and if it succeeds with it, then it will use that namespace for the rest of function.

...
                # This is either an NVR or a rebadged camera
                event_xml = content.findall(
                    self.element_query('EventTrigger'))
            elif content.find(self.element_query('EventTrigger', XML_NAMESPACE_M)):
                event_ns = XML_NAMESPACE_M
                event_xml = content.findall(
                    self.element_query('EventTrigger', event_ns))
...

Also expanded element_query to accepts optional namespace argument.

    def element_query(self, element, namespace=None):
        """Build tree query for a given element."""
        return '{%s}%s' % (namespace if namespace else self.namespace, element)

However, then noticed that get_motion_detection is also affected and then started looking for that elegant solution :) Started investigating device type returned, maybe it can be related to that... On device I mentioned it returns IPC, but not having many devices I can test, and as @thingie said - 'but hikvison', that device type value is not mentioned in docs :D

Yeah you start to go down a rabbit hole when adding a workaround for this specific problem because of the way it manifest itself. I don't want to add extra namespace checks everywhere to slow things down so I think a patch on ElementTree to ignore the namespace altogether (or abandon XML parsing entirely) is probably the way to go.

I'll try to get a test branch setup with the needed changes soon and gather some testers.

Please give this branch a try: https://github.com/mezz64/pyHik/tree/namespace_fix

Let me know if that fixes the issue.

Fix has been implemented in the latest release. Closing this issue.