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

Python 3.9 broke this component #3

Open
leranp opened this issue Jul 22, 2021 · 11 comments
Open

Python 3.9 broke this component #3

leranp opened this issue Jul 22, 2021 · 11 comments

Comments

@leranp
Copy link

leranp commented Jul 22, 2021

I upgraded HA docker couple of weeks ago so and the python version was changed to 3.9.5 and now there is a problem with the date conversation.
The camera is working, but the sensors aren't working at all.
Looks like there is a fix for it in the zeep github #mvantellingen/python-zeep#1240

[zeeep.xsd.elements.attribute] Error during xml -> python translation
Traceback (most recent call last):
File "/config/custom_components/onvif/zeeep/xsd/elements/attribute.py", line 22, in parse
return self.type.pythonvalue(value)
File "/config/custom_components/onvif/zeeep/xsd/types/builtins.py", line 44, in _wrapper
return func(self, re.sub(r"[\n\r\t ]", " ", value).strip())
File "/config/custom_components/onvif/zeeep/xsd/types/builtins.py", line 176, in pythonvalue
return isodate.parse_datetime(value)
File "/usr/local/lib/python3.9/site-packages/isodate/isodatetime.py", line 55, in parse_datetime
tmpdate = parse_date(datestring)
File "/usr/local/lib/python3.9/site-packages/isodate/isodates.py", line 201, in parse_date
return date(sign * int(groups['year']),
ValueError: month must be in 1..12
@slydiman
Copy link
Owner

I have found the same error on some my HA instances.
But I cannot reproduce this issue on my PC with python 3.9.5.
I tried Home Assistant core-2021.6.2 and core-2021.7.4
What camera causes such issue?
Please be sure the camera is set to the correct datetime.
If the camera uses NTP service to update the time be sure NTP is available and reports the correct datetime.

You can try to change onvif/zeeep/xsd/types/builtins.py , line 176 to something like this

        try:
            return isodate.parse_datetime(value)
        except (ValueError):
            print("!!! isodate.parse_datetime('" + value + "') failed !!!")
            return None

to figure out what string cannot be parsed.
Then we need to understand what is the source of that invalid datetime string and how to fix it.

@leranp
Copy link
Author

leranp commented Jul 22, 2021

I figure how to fix it ,
removing this lines in the file onvif/zeeep/xsd/types/builtins.py :

    @treat_whitespace("collapse")
    def pythonvalue(self, value):

        # Determine based on the length of the value if it only contains a date
        # lazy hack ;-)
        # if len(value) == 10:
            # value += "T00:00:00"
        # elif (len(value) == 19 or len(value) == 26) and value[10] == " ":
            # value = "T".join(value.split(" "))
        return isodate.parse_datetime(value)

and add to onvif/zeeep/exceptions.py this lines:

class DTDForbidden(Error):
    def __init__(self, name, sysid, pubid):
        super(DTDForbidden, self).__init__()
        self.name = name
        self.sysid = sysid
        self.pubid = pubid

    def __str__(self):
        tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})"
        return tpl.format(self.name, self.sysid, self.pubid)


class EntitiesForbidden(Error):
    def __init__(self, name, content):
        super(EntitiesForbidden, self).__init__()
        self.name = name
        self.content = content

    def __str__(self):
        tpl = "EntitiesForbidden(name='{}', content={!r})"
        return tpl.format(self.name, self.content)

@leranp leranp closed this as completed Jul 22, 2021
@leranp leranp reopened this Jul 22, 2021
@leranp
Copy link
Author

leranp commented Jul 22, 2021

the error is still there , but the binary sensor is working again , maybe is because I deleted all the cache folders (pycache) ?

@leranp
Copy link
Author

leranp commented Jul 22, 2021

this is anther error :

2021-07-22 21:32:43 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/config/custom_components/onvif/event.py", line 171, in async_pull_messages
dt_util.as_utc(response.TerminationTime) - dt_util.utcnow()
File "/usr/src/homeassistant/homeassistant/util/dt.py", line 74, in as_utc
if dattim.tzinfo == UTC:
AttributeError: 'NoneType' object has no attribute 'tzinfo'

@slydiman
Copy link
Owner

slydiman commented Jul 22, 2021

I don't see the purpose to add classes DTDForbidden and EntitiesForbidden to onvif/zeeep/exceptions.py. Where and how are they used?

the error is still there , but the binary sensor is working again , maybe is because I deleted all the cache folders (pycache) ?

No. It is necessary to log the invalid datetime string to figure out what is wrong.

this is another error :

It means that response.TerminationTime is not a datetime at all.
You can add the following lines

                if not isinstance(response.TerminationTime, dt.datetime):
                    raise Fault(message="Invalid TerminationTime '%s'" % response.TerminationTime)

to /config/custom_components/onvif/event.py, line 170:

                # Renew subscription if less than two hours is left
                if not isinstance(response.TerminationTime, dt.datetime):
                    raise Fault(message="Invalid TerminationTime '%s'" % response.TerminationTime)
                if (
                    dt_util.as_utc(response.TerminationTime) - dt_util.utcnow()
                ).total_seconds() < 7200:
                    await self.async_renew()

to get detailed logs.

@leranp
Copy link
Author

leranp commented Jul 23, 2021

I don't see the purpose to add classes DTDForbidden and EntitiesForbidden to onvif/zeeep/exceptions.py. Where and how are they used?

the error is still there , but the binary sensor is working again , maybe is because I deleted all the cache folders (pycache) ?

No. It is necessary to log the invalid datetime string to figure out what is wrong.

this is another error :

It means that response.TerminationTime is not a datetime at all.
You can add the following lines

                if not isinstance(response.TerminationTime, dt.datetime):
                    raise Fault(message="Invalid TerminationTime '%s'" % response.TerminationTime)

to /config/custom_components/onvif/event.py, line 170:

                # Renew subscription if less than two hours is left
                if not isinstance(response.TerminationTime, dt.datetime):
                    raise Fault(message="Invalid TerminationTime '%s'" % response.TerminationTime)
                if (
                    dt_util.as_utc(response.TerminationTime) - dt_util.utcnow()
                ).total_seconds() < 7200:
                    await self.async_renew()

to get detailed logs.

This is the error log after the change:

2021-07-23 21:49:05 DEBUG (MainThread) [custom_components.onvif] Restarted ONVIF PullPoint subscription for '00:12:41:ED:50:80'
2021-07-23 23:05:55 WARNING (MainThread) [custom_components.onvif] Failed to fetch ONVIF PullPoint subscription messages for '00:12:41:ED:50:80': Invalid TerminationTime 'None'
2021-07-23 23:05:56 DEBUG (MainThread) [custom_components.onvif] Restarted ONVIF PullPoint subscription for '00:12:41:ED:50:80'

@slydiman
Copy link
Owner

slydiman commented Jul 23, 2021

This is the error log after the change:

2021-07-23 21:49:05 DEBUG (MainThread) [custom_components.onvif] Restarted ONVIF PullPoint subscription for '00:12:41:ED:50:80'
2021-07-23 23:05:55 WARNING (MainThread) [custom_components.onvif] Failed to fetch ONVIF PullPoint subscription messages for '00:12:41:ED:50:80': Invalid TerminationTime 'None'
2021-07-23 23:05:56 DEBUG (MainThread) [custom_components.onvif] Restarted ONVIF PullPoint subscription for '00:12:41:ED:50

So HA sent ONVIF PullPoint subscription request to the camera and got the response without TerminationTime at all.
It means that this camera is not up to ONVIF standards.
BTW, I asked the camera model.
You can install HA on Windows PC and use WireShark to record the communication between HA and the camera. Then we can see the real PullPoint subscription request and response and decide whether it is possible to fix it and how.

@leranp
Copy link
Author

leranp commented Jul 24, 2021

I didn't change anything (firmware version or configuration) in the last week's, only HA update.
It was working fine for couples of months so the only thing that can broke this is the HA update.
My Camera is Chinese brand

https://a.aliexpress.com/_vntz4D

@slydiman
Copy link
Owner

I think it does not depend on python version at all.

This camera is XM (Xiong Mai tech).
You can use XMEye and/or iCSee software for Android. I have no idea about iOS.
Note iCSee may update the camera firmware!
Note a lot of camera settings is unavailable in the mobile software.
It is possible to check/adjust all camera or DVR/NVR/HVR settings using CMS software.
You can download the XM CMS software for Windows here http://www.xiongmaitech.com/en/index.php/service/down_detail/83/198

You can also test the camera using ONVIF Device Manager https://sourceforge.net/projects/onvifdm/

Note about the model and firmware:
For example
I'm using this camera https://aliexpress.ru/item/1005001446624233.html
The model on the box is A5-F30RJ.
But the correct model is XM530_RF50X30_8M.
The version of the camera shown by the software is V5.00.R02.00030746.10010.348517.ONVIF 16.12
00030746 here is the model ID and the latest firmware for that model is available here https://download.xm030.cn/d/MDAwMDEzMjk=

Here is the list of some XM camera models and firmwares (Russian lang) https://www.cctvsp.ru/articles/obnovlenie-proshivok-dlya-ip-kamer-ot-xiong-mai

@leranp
Copy link
Author

leranp commented Jul 24, 2021 via email

@leranp
Copy link
Author

leranp commented Jul 26, 2021

Update: Disable NTP didn't fixed the problem

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

2 participants