pyEzviz icon indicating copy to clipboard operation
pyEzviz copied to clipboard

UnboundLocalError: local variable 'json_result' referenced before assignment

Open BaQs opened this issue 4 years ago • 13 comments

021-01-30 12:35:39 ERROR (MainThread) [homeassistant.components.ezviz.coordinator] Unexpected error fetching ezviz data: local variable 'json_result' referenced before assignment Traceback (most recent call last): File "/workspaces/core/homeassistant/helpers/update_coordinator.py", line 149, in async_refresh self.data = await self._async_update_data() File "/workspaces/core/homeassistant/components/ezviz/coordinator.py", line 39, in _async_update_data return await self.hass.async_add_executor_job(self._update_data) File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/workspaces/core/homeassistant/components/ezviz/coordinator.py", line 31, in _update_data cameras = self.ezviz_client.load_cameras() File "/usr/local/lib/python3.8/site-packages/pyezviz/client.py", line 270, in load_cameras camera.load() File "/usr/local/lib/python3.8/site-packages/pyezviz/camera.py", line 18, in load self._device = self._client._get_deviceinfo(self._serial) File "/usr/local/lib/python3.8/site-packages/pyezviz/client.py", line 181, in _get_deviceinfo if not json_result: UnboundLocalError: local variable 'json_result' referenced before assignment

Can be reproduced by launching: pyezviz -u [email protected] -p "xxx" devices status

BaQs avatar Jan 30 '21 21:01 BaQs

DEBUG:urllib3.connectionpool:https://ieu.ezvizlife.com:443 "GET /camera/cameraAction!findAllDevices.action HTTP/1.1" 200 14 ERROR:root:OULA req.text: {"devices":[]} ('Impossible to load the devices [%s], here is the returned response: %s ', 'DXXXXXXXX', '{"devices":[]}')

BaQs avatar Jan 30 '21 21:01 BaQs

It seems the /camera/cameraAction!findAllDevices.action endpoint is not compatible with my environment: I use a specific account on which I shared most of my devices.

I see the official app is using:

https://apiieu.ezvizlife.com/v3/userdevices/v1/resources/pagelist?filter=CLOUD%2CTIME_PLAN%2CCONNECTION%2CSWITCH%2CSTATUS%2CWIFI%2CNODISTURB%2CP2P%2CKMS%2CHIDDNS%2CFEATURE%2CUPGRADE%2CDETECTOR%2CVIDEO_QUALITY%2CVTM%2CQOS%2CCHANNEL&groupId=-1&limit=30&offset=0

the result of this request has a "deviceInfos" array that seems to provide most of the necessary information.

What do you think ?

BaQs avatar Jan 30 '21 21:01 BaQs

When using my main account: File "/usr/local/lib/python3.8/site-packages/pyezviz/client.py", line 177, in _get_deviceinfo device['deviceExtStatus']['AlgorithmInfo'] = json.loads(device['deviceExtStatus']['AlgorithmInfo']) KeyError: 'AlgorithmInfo'

BaQs avatar Jan 30 '21 21:01 BaQs

Hi BaQs,

scratch the part of the alarm. I remembered wrong. Used to detect the "ability to " adjust sensibility.

I'm busy optimizing code and looking at the /camera/cameraAction!findAllDevices.action endpoint. It looks like pagelist works for shared devices as well. Just busy looking into what json keys to adjust.

I'm also almost done with pylint fixes on this component. Speeds up the code by a few mili seconds.

RenierM26 avatar Jan 31 '21 05:01 RenierM26

Hi @BaQs,

I modified your push request a bit to fix this bit:

#camera.py

    """load detection sensibility"""
    if self._switch.get(DeviceSwitchType.AUTO_SLEEP.value) is not True:
            self._detection_sensibility = self._client.get_detection_sensibility(
                self._serial,
                self._device.get("supportExt").get("support_sensibility_adjust"),
            )
    if self._switch.get(DeviceSwitchType.AUTO_SLEEP.value) is True:
            self._detection_sensibility = "Hibernate"

    return True

It's used to prevent the querying of "detection sensibility" in cameras with "auto sleep" (Battery cameras mostly). This query is "live" from the device and not just a "last value" from the website. (Hope this makes sense?)

Removed :

in _get_deviceinfo device['deviceExtStatus']['AlgorithmInfo'] = json.loads(device['deviceExtStatus']['AlgorithmInfo']) KeyError: 'AlgorithmInfo'

with net result of:

    for device in json_output["devices"]:
        if device["subSerial"] == serial:
            device["supportExt"] = json.loads(device.get("supportExt"))
            json_result = device
            break

Should fix your issue.

RenierM26 avatar Feb 01 '21 19:02 RenierM26

Hi @BaQs,

I added a json key check with exception for "SupportExt" to both camera and client. Would you mind testing the change?

RenierM26 avatar Feb 02 '21 04:02 RenierM26

Hi, I'm stil lhaving the same error. pretty crazy, I don't see the error stack.

DEBUG:urllib3.connectionpool:https://ieu.ezvizlife.com:443 "GET /camera/cameraAction!findAllDevices.action HTTP/1.1" 200 14 local variable 'json_result' referenced before assignment

When using my main account and not the "shared" one:

header: Connection: keep-alive DEBUG:urllib3.connectionpool:https://ieu.ezvizlife.com:443 "POST /api/device/queryAlgorithmConfig HTTP/1.1" 200 112 'NoneType' object is not iterable

BaQs avatar Feb 02 '21 20:02 BaQs

Don't you think it was safer to use the info from pagelist ? that's how the app is behaving and I believe it's compatible with most of the installations.

BaQs avatar Feb 02 '21 20:02 BaQs

Gist dump of ezviz session here

BaQs avatar Feb 02 '21 21:02 BaQs

Hi BaQs,

Thank you for the gist dump, it helps a lot. The "supportext" is present in the response but it looks like the "support_sensibility_adjust" string isn't. I have removed the check for that string and rather make user of the device category to determine the sensor type. (PIR 1-100 and other 1-6)

Mind testing the change? I think the missing string also caused error in calling the "get_sensibility..." function.

I'm planning to rewrite some of the code this weekend to make use of the pagelist. I have an idea to reduce queries to ezviz cloud. With the pagelist we can get all the camera info for all the devices in 1 query. (excluding the "triggered alarms" and last pic.)

RenierM26 avatar Feb 04 '21 05:02 RenierM26

Indeed, my assumption was to figure out how the app behaves and gets all these informations about cameras. As the app caches a lot of things I struggled getting the sequence. I'll check about the pic because it comes from another endpoint And then I'll update the gist as a reference. I feel the app does not use some of the api calls you implemented, and believe they will be obsolete soon.

Safer to use pagelist I agree.

I'm also thinking about the future HA implementation, that needs to refresh the object. So I included a gist with specific camera calls

BaQs avatar Feb 04 '21 09:02 BaQs

Ok I tested your last commits, and then:

'NoneType' object is not iterable

:(

BaQs avatar Feb 08 '21 20:02 BaQs

Hi @BaQs,

Is is working with the latest version?

RenierM26 avatar Feb 13 '21 08:02 RenierM26