rytilahti / python-miio

Python library & console tool for controlling Xiaomi smart appliances
https://python-miio.readthedocs.io
GNU General Public License v3.0
3.52k stars 542 forks source link

fix json decode quirk for xiaomi e10 #1922

Closed matan-h closed 2 months ago

matan-h commented 3 months ago

Version: Firmware version: 2.2.4_0050 Hardware version: esp32

some commands (e.g. genericmiot call map:rename-map '[0,"string"]') generate json-like string like this:

{"id":2,"result":,"exe_time":0}

and this produce the error:

ERROR:miio.protocol:Unable to parse json 'b'{"id":2,"result":,"exe_time":0}'': Expecting value: line 1 column 18 (char 17)
ERROR:miio.click_common:Exception: Unable to parse message payload

I fix that by removing the nonsense result":,.

codecov[bot] commented 3 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 81.45%. Comparing base (8643a57) to head (0eec5d8). Report is 1 commits behind head on master.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #1922 +/- ## ========================================== + Coverage 81.41% 81.45% +0.03% ========================================== Files 193 196 +3 Lines 18636 18891 +255 Branches 4045 4111 +66 ========================================== + Hits 15173 15387 +214 - Misses 3180 3211 +31 - Partials 283 293 +10 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

rytilahti commented 3 months ago

Is the command still working, but just returning invalid json? Otherwise looks fine for me, thanks for the PR!

matan-h commented 3 months ago

@rytilahti this is an interesting story. e10 is a cheap model that don't support maps. However, it still has the maps commands, just in a way no one can access them: there is only one map called "hello" with index 0, and according to the spec, map indexes start from one. So this corrupted json is the robot confused and returning empty result. (probably something like f"results:get_results(),exec_time:get_time()")

rytilahti commented 3 months ago

Heh, yeah, some firmware behave weirdly on error states, likely for the reason you mention. Would you mind adding a unit test similar as https://github.com/rytilahti/python-miio/blob/master/miio/tests/test_protocol.py#L129 for this quirk?