rytilahti / python-miio

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

miiocli viomivacuum status not working for STYJ02YM (viomi.vacuum.v8, fw: 3.5.3_0017) #1003

Closed bkupidura closed 1 year ago

bkupidura commented 3 years ago

Describe the bug miiocli viomivacuum status is broken for STYJ02YM with firmware 3.5.3_0017. Looks like vacuum is returning less properties than expected.

List of available properties can be found https://github.com/nqkdev/home-assistant-vacuum-styj02ym/blob/master/vacuum.py#L122, i see that nqkdev is not using all available - but this can be start point for further investigation.

Version information (please complete the following information):

Device information: Model: viomi.vacuum.v8 Hardware version: Linux Firmware version: 3.5.3_0017

To Reproduce Steps to reproduce the behavior:

  1. Run miiocli viomivacuum status

Expected behavior Status command working

Console output

# miiocli --debug viomivacuum --ip 10.0.150.27 --token <TOKEN> status
INFO:miio.cli:Debug mode active

DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.miioprotocol:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x13\x9f\x9c\xc8`n\xb1\x15' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x13\x9f\x9c\xc8' (total 4)
            ts = 2021-04-08 07:30:29
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' (total 16)
DEBUG:miio.miioprotocol:Discovered 139f9cc8 with ts: 2021-04-08 07:30:29, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:10.0.150.27:54321 >>: {'id': 1, 'method': 'get_prop', 'params': ['battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'm
ap_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade']}
DEBUG:miio.miioprotocol:Retrying with incremented id, retries left: 10
DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.miioprotocol:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x13\x9f\x9c\xc8`n\xb1\x1a' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x13\x9f\x9c\xc8' (total 4)
            ts = 2021-04-08 07:30:34
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' (total 16)
DEBUG:miio.miioprotocol:Discovered 139f9cc8 with ts: 2021-04-08 07:30:34, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:10.0.150.27:54321 >>: {'id': 102, 'method': 'get_prop', 'params': ['battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade']}
DEBUG:miio.miioprotocol:Retrying with incremented id, retries left: 9
DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.miioprotocol:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x13\x9f\x9c\xc8`n\xb1\x1f' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x13\x9f\x9c\xc8' (total 4)
            ts = 2021-04-08 07:30:39
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' (total 16)
DEBUG:miio.miioprotocol:Discovered 139f9cc8 with ts: 2021-04-08 07:30:39, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:10.0.150.27:54321 >>: {'id': 203, 'method': 'get_prop', 'params': ['battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade']}
DEBUG:miio.miioprotocol:Retrying with incremented id, retries left: 8
DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.miioprotocol:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x13\x9f\x9c\xc8`n\xb1%' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x13\x9f\x9c\xc8' (total 4)
            ts = 2021-04-08 07:30:45
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' (total 16)
DEBUG:miio.miioprotocol:Discovered 139f9cc8 with ts: 2021-04-08 07:30:45, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:10.0.150.27:54321 >>: {'id': 304, 'method': 'get_prop', 'params': ['battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade']}
DEBUG:miio.miioprotocol:10.0.150.27:54321 (ts: 2021-04-08 07:30:45, id: 304) << {'result': [66, 1, 2103, 1, 0, '1.0.3', 0, 0, 1, 74, 0, 0, 1, 0, 5, 37.17, 42, 0, 10, 12], 'id': 304}
DEBUG:miio.device:Count (23) of requested properties does not match the count (20) of received values.
Traceback (most recent call last):
  File "/usr/local/bin/miiocli", line 8, in <module>
    sys.exit(create_cli())
  File "/usr/local/lib/python3.8/site-packages/miio/cli.py", line 45, in create_cli
    return cli(auto_envvar_prefix="MIIO")
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 285, in wrap
    result_msg = result_msg_fmt.format(**kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/viomivacuum.py", line 336, in fanspeed
    return ViomiVacuumSpeed(self.data["suction_grade"])
  File "/usr/local/lib/python3.8/enum.py", line 339, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.8/enum.py", line 662, in __new__
    raise ve_exc
ValueError: None is not a valid ViomiVacuumSpeed
rytilahti commented 3 years ago

@bkupidura you may want to check out #1014 which should make it a bit easier to find out which properties are not working for your device :-)

ontaptom commented 3 years ago

@bkupidura do you have any progress with that?

bkupidura commented 3 years ago

@ontaptom Unfortunately no. Didnt had time to look at that. :(

Didel commented 3 years ago

@bkupidura I do have the same device running on the same firmware version. I’m running Home Assistant OS on a Raspberry Pi. If you could explain how I can execute the miiocli command from within an ssh session to Home Assistant I’ll run the command that @rytilahti referred to.

bkupidura commented 3 years ago

@Didel command mentioned by @rytilahti will require manually patching python-miio package (or installing package manualy), as afaik HA is still using older version. If you dont feel comfortable with that, i would suggest not modyfiying anything in HA container - as i will not be able to help with reverting any changes.

Steps bellow will not do any harm to yours HA installation - but probably step 4) will fail because of missing #1014

You can check that with: 1) log over ssh to HA 2) run login command 3) run docker exec -it homeassistant /bin/bash 4) run miio cli test_properties command

Im not using HA OS, so this is based on https://developers.home-assistant.io/docs/operating-system/debugging/ and not on my experience.

ontaptom commented 3 years ago

@bkupidura I had some success today with adding my viomi.vacuum.v8 to HA. However, on the bottom side of my vacuum the model is listed as: STYTJ02YM. Can you verify with yours? I read that .v7 is STYJ.. and .v8 is STYTJ.. Anyways, I have absolutely no success with python-miio, but I managed to add the vacuum to my Home Assistant by importing: https://github.com/KrzysztofHajdamowicz/home-assistant-vacuum-styj02ym repository via HACS and in the configuration.yaml:

vacuum:
  - platform: miio2
    host: 192.168.0.135
    token: 616d465xxxxx
    name: vacuum

Hope that helps :)

rytilahti commented 3 years ago

To improve the support in this library (and in turn help to get out-of-the-box support for homeassistant at some point), it would be useful if anyone with v8 and v9 could use the test properties and report back here:

miiocli device --ip <addr> --token <token> test_properties battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life

This needs to be run with the current git version until there will be a new release:

pip install poetry # if poetry is not already installed
git clone https://github.com/rytilahti/python-miio.git
cd python-miio
poetry install
poetry run miiocli --version  # this should print the installed version if everything went fine, then execute the test_properties command above

poetry installs the git version on its own virtual environment, and shouldn't thus cause any problems to any system-wide installations with the caveat of requiring to run poetry run <command> (to execute a single command) or poetry shell (to open a shell in the environment).

ontaptom commented 3 years ago

@rytilahti hope this helps:

$ poetry run miiocli device --ip 192.168.0.135 --token <token> test_properties battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life
Running command test_properties
Testing properties ('battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade', 'order_time', 'start_time', 'water_percent', 'zone_data', 'sw_info', 'main_brush_hours', 'main_brush_life', 'side_brush_hours', 'side_brush_life', 'mop_hours', 'mop_life', 'hypa_hours', 'hypa_life') for viomi.vacuum.v8
Testing battary_life.. 100 <class 'int'>
Testing box_type.. 1 <class 'int'>
Testing cur_mapid.. Empty response
Testing err_state.. 2105 <class 'int'>
Testing has_map.. 1 <class 'int'>
Testing has_newmap.. Empty response
Testing hw_info.. 1.0.3 <class 'str'>
Testing is_charge.. Empty response
Testing is_mop.. Empty response
Testing is_work.. 1 <class 'int'>
Testing light_state.. 1 <class 'int'>
Testing map_num.. Empty response
Testing mode.. Empty response
Testing mop_route.. Empty response
Testing mop_type.. Empty response
Testing remember_map.. 1 <class 'int'>
Testing repeat_state.. Empty response
Testing run_state.. 5 <class 'int'>
Testing s_area.. 0.77 <class 'float'>
Testing s_time.. 1 <class 'int'>
Testing suction_grade.. 2 <class 'int'>
Testing v_state.. 10 <class 'int'>
Testing water_grade.. 13 <class 'int'>
Testing order_time.. 0 <class 'str'>
Testing start_time.. Empty response
Testing water_percent.. Empty response
Testing zone_data.. 0 <class 'str'>
Testing sw_info.. 3.5.3_0017 <class 'str'>
Testing main_brush_hours.. Empty response
Testing main_brush_life.. Empty response
Testing side_brush_hours.. Empty response
Testing side_brush_life.. Empty response
Testing mop_hours.. Empty response
Testing mop_life.. Empty response
Testing hypa_hours.. Empty response
Testing hypa_life.. Empty response
Found 36 valid properties, testing max_properties..
Testing 36 properties at once.. Got different amount of properties than requested
Testing 35 properties at once.. Got different amount of properties than requested
Testing 34 properties at once.. Got different amount of properties than requested
Testing 33 properties at once.. Got different amount of properties than requested
Testing 32 properties at once.. Got different amount of properties than requested
Testing 31 properties at once.. Got different amount of properties than requested
Testing 30 properties at once.. Got different amount of properties than requested
Testing 29 properties at once.. Got different amount of properties than requested
Testing 28 properties at once.. Got different amount of properties than requested
Testing 27 properties at once.. Got different amount of properties than requested
Testing 26 properties at once.. Got different amount of properties than requested
Testing 25 properties at once.. Got different amount of properties than requested
Testing 24 properties at once.. Got different amount of properties than requested
Testing 23 properties at once.. Got different amount of properties than requested
Testing 22 properties at once.. Got different amount of properties than requested
Testing 21 properties at once.. Got different amount of properties than requested
Testing 20 properties at once.. Got different amount of properties than requested
Testing 19 properties at once.. Got different amount of properties than requested
Testing 18 properties at once.. Got different amount of properties than requested
Testing 17 properties at once.. Got different amount of properties than requested
Testing 16 properties at once.. Got different amount of properties than requested
Testing 15 properties at once.. Got different amount of properties than requested
Testing 14 properties at once.. Got different amount of properties than requested
Testing 13 properties at once.. Got different amount of properties than requested
Testing 12 properties at once.. Got different amount of properties than requested
Testing 11 properties at once.. Got different amount of properties than requested
Testing 10 properties at once.. Got different amount of properties than requested
Testing 9 properties at once.. Got different amount of properties than requested
Testing 8 properties at once.. Got different amount of properties than requested
Testing 7 properties at once.. Got different amount of properties than requested
Testing 6 properties at once.. Got different amount of properties than requested
Testing 5 properties at once.. Got different amount of properties than requested
Testing 4 properties at once.. Got different amount of properties than requested
Testing 3 properties at once.. Got different amount of properties than requested
Testing 2 properties at once.. OK for 2 properties

Please copy the results below to your report
### Results ###
Model: viomi.vacuum.v8
Total responsives: 36
Total non-empty: 36
All non-empty properties:
{'battary_life': 100,
 'box_type': 1,
 'cur_mapid': [],
 'err_state': 2105,
 'has_map': 1,
 'has_newmap': 0,
 'hw_info': '1.0.3',
 'hypa_hours': [],
 'hypa_life': [],
 'is_charge': 0,
 'is_mop': 0,
 'is_work': 1,
 'light_state': 1,
 'main_brush_hours': [],
 'main_brush_life': [],
 'map_num': [],
 'mode': 0,
 'mop_hours': [],
 'mop_life': [],
 'mop_route': [],
 'mop_type': 0,
 'order_time': '0',
 'remember_map': 1,
 'repeat_state': 0,
 'run_state': 5,
 's_area': 0.77,
 's_time': 1,
 'side_brush_hours': [],
 'side_brush_life': [],
 'start_time': 0,
 'suction_grade': 2,
 'sw_info': '3.5.3_0017',
 'v_state': 10,
 'water_grade': 13,
 'water_percent': [],
 'zone_data': '0'}
Max properties: 2
Done

Run against:

$ poetry  run miiocli viomivacuum --ip 192.168.0.135 --token <token> info
Model: viomi.vacuum.v8
Hardware version: Linux
Firmware version: 3.5.3_0017
rytilahti commented 3 years ago

@ontaptom great, thanks! From the looks of it, the logic behind testing how many properties to request at once is a bit broken.. Could you rerun the command with --debug and locate which property gets removed between requests for 3 and 2 at once?

After that, you could re-try the command without the property which should now report with more max properties than 2 :-)

edit: feel free to try the linked PR which makes the command more verbose for easier testing.

ontaptom commented 3 years ago

@rytilahti I had to remove quite few of them to have that command run successfully. Removed properties:

cur_mapid 
map_num 
mop_route
water_percent
main_brush_hours
main_brush_life
side_brush_hours 
side_brush_life
mop_hours 
mop_life 
hypa_hours 
hypa_life

Each of them gave me an error Got different amount of properties than requested during testing max_properties.. phase

The full command and output once those were eliminated:

$ poetry run miiocli device --ip 192.168.0.135 --token <token> test_properties battary_life box_type err_state has_map has_newmap hw_info is_charge is_mop is_work light
_state mode mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time zone_data sw_info
Running command test_properties
Testing properties ('battary_life', 'box_type', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'mode', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade', 'order_time', 'start_time', 'zone_data', 'sw_info') for viomi.vacuum.v8
Testing battary_life.. 100 <class 'int'>
Testing box_type.. 1 <class 'int'>
Testing err_state.. 2105 <class 'int'>
Testing has_map.. 1 <class 'int'>
Testing has_newmap.. Empty response
Testing hw_info.. 1.0.3 <class 'str'>
Testing is_charge.. Empty response
Testing is_mop.. Empty response
Testing is_work.. 1 <class 'int'>
Testing light_state.. 1 <class 'int'>
Testing mode.. Empty response
Testing mop_type.. Empty response
Testing remember_map.. 1 <class 'int'>
Testing repeat_state.. Empty response
Testing run_state.. 5 <class 'int'>
Testing s_area.. 0.77 <class 'float'>
Testing s_time.. 1 <class 'int'>
Testing suction_grade.. 2 <class 'int'>
Testing v_state.. 10 <class 'int'>
Testing water_grade.. 13 <class 'int'>
Testing order_time.. 0 <class 'str'>
Testing start_time.. Empty response
Testing zone_data.. 0 <class 'str'>
Testing sw_info.. 3.5.3_0017 <class 'str'>
Found 24 valid properties, testing max_properties..
Testing 24 properties at once.. OK for 24 properties

Please copy the results below to your report
### Results ###
Model: viomi.vacuum.v8
Total responsives: 24
Total non-empty: 24
All non-empty properties:
{'battary_life': 100,
 'box_type': 1,
 'err_state': 2105,
 'has_map': 1,
 'has_newmap': 0,
 'hw_info': '1.0.3',
 'is_charge': 0,
 'is_mop': 0,
 'is_work': 1,
 'light_state': 1,
 'mode': 0,
 'mop_type': 0,
 'order_time': '0',
 'remember_map': 1,
 'repeat_state': 0,
 'run_state': 5,
 's_area': 0.77,
 's_time': 1,
 'start_time': 0,
 'suction_grade': 2,
 'sw_info': '3.5.3_0017',
 'v_state': 10,
 'water_grade': 13,
 'zone_data': '0'}
Max properties: 24
Done
Skelly82 commented 3 years ago

Hi, i have same device as @ontaptom, output from #1024 is:

poetry run miiocli viomivacuum  --ip ### --token ### info
Model: viomi.vacuum.v8
Hardware version: Linux
Firmware version: 3.5.3_0017
poetry run miiocli viomivacuum  --ip ### --token ### test_properties battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life
Running command test_properties
Testing properties ('battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade', 'order_time', 'start_time', 'water_percent', 'zone_data', 'sw_info', 'main_brush_hours', 'main_brush_life', 'side_brush_hours', 'side_brush_life', 'mop_hours', 'mop_life', 'hypa_hours', 'hypa_life') for viomi.vacuum.v8
Testing battary_life       100 <class 'int'>
Testing box_type           1 <class 'int'>
Testing cur_mapid          [] <class 'list'>
Testing err_state          2105 <class 'int'>
Testing has_map            1 <class 'int'>
Testing has_newmap         0 <class 'int'>
Testing hw_info            1.0.1 <class 'str'>
Testing is_charge          0 <class 'int'>
Testing is_mop             0 <class 'int'>
Testing is_work            1 <class 'int'>
Testing light_state        1 <class 'int'>
Testing map_num            [] <class 'list'>
Testing mode               0 <class 'int'>
Testing mop_route          [] <class 'list'>
Testing mop_type           0 <class 'int'>
Testing remember_map       1 <class 'int'>
Testing repeat_state       0 <class 'int'>
Testing run_state          5 <class 'int'>
Testing s_area             16.76 <class 'float'>
Testing s_time             18 <class 'int'>
Testing suction_grade      3 <class 'int'>
Testing v_state            0 <class 'int'>
Testing water_grade        12 <class 'int'>
Testing order_time         0 <class 'str'>
Testing start_time         0 <class 'int'>
Testing water_percent      [] <class 'list'>
Testing zone_data          0 <class 'str'>
Testing sw_info            3.5.3_0017 <class 'str'>
Testing main_brush_hours   [] <class 'list'>
Testing main_brush_life    [] <class 'list'>
Testing side_brush_hours   [] <class 'list'>
Testing side_brush_life    [] <class 'list'>
Testing mop_hours          [] <class 'list'>
Testing mop_life           [] <class 'list'>
Testing hypa_hours         [] <class 'list'>
Testing hypa_life          [] <class 'list'>
Found 36 valid properties, testing max_properties..
Testing 36 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life): Got different amount of properties (35) than requested (24, removing hypa_life
Testing 35 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours): Got different amount of properties (34) than requested (24, removing hypa_hours
Testing 34 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life): Got different amount of properties (33) than requested (24, removing mop_life
Testing 33 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours): Got different amount of properties (32) than requested (24, removing mop_hours
Testing 32 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life): Got different amount of properties (31) than requested (24, removing side_brush_life
Testing 31 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours): Got different amount of properties (30) than requested (24, removing side_brush_hours
Testing 30 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life): Got different amount of properties (29) than requested (24, removing main_brush_life
Testing 29 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours): Got different amount of properties (28) than requested (24, removing main_brush_hours
Testing 28 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info): Got different amount of properties (27) than requested (24, removing sw_info
Testing 27 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data): Got different amount of properties (26) than requested (23, removing zone_data
Testing 26 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent): Got different amount of properties (25) than requested (22, removing water_percent
Testing 25 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time): Got different amount of properties (24) than requested (22, removing start_time
Testing 24 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time): Got different amount of properties (23) than requested (21, removing order_time
Testing 23 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade): Got different amount of properties (22) than requested (20, removing water_grade
Testing 22 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state): Got different amount of properties (21) than requested (19, removing v_state
Testing 21 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade): Got different amount of properties (20) than requested (18, removing suction_grade
Testing 20 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time): Got different amount of properties (19) than requested (17, removing s_time
Testing 19 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area): Got different amount of properties (18) than requested (16, removing s_area
Testing 18 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state): Got different amount of properties (17) than requested (15, removing run_state
Testing 17 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state): Got different amount of properties (16) than requested (14, removing repeat_state
Testing 16 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map): Got different amount of properties (15) than requested (13, removing remember_map
Testing 15 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type): Got different amount of properties (14) than requested (12, removing mop_type
Testing 14 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route): Got different amount of properties (13) than requested (11, removing mop_route
Testing 13 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode): Got different amount of properties (12) than requested (11, removing mode
Testing 12 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num): Got different amount of properties (11) than requested (10, removing map_num
Testing 11 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state): Got different amount of properties (10) than requested (10, removing light_state
Testing 10 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work): Got different amount of properties (9) than requested (9, removing is_work
Testing 9 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop): Got different amount of properties (8) than requested (8, removing is_mop
Testing 8 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge): Got different amount of properties (7) than requested (7, removing is_charge
Testing 7 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap hw_info): Got different amount of properties (6) than requested (6, removing hw_info
Testing 6 properties at once (battary_life box_type cur_mapid err_state has_map has_newmap): Got different amount of properties (5) than requested (5, removing has_newmap
Testing 5 properties at once (battary_life box_type cur_mapid err_state has_map): Got different amount of properties (4) than requested (4, removing has_map
Testing 4 properties at once (battary_life box_type cur_mapid err_state): Got different amount of properties (3) than requested (3, removing err_state
Testing 3 properties at once (battary_life box_type cur_mapid): Got different amount of properties (2) than requested (2, removing cur_mapid
Testing 2 properties at once (battary_life box_type): OK for 2 properties

Please copy the results below to your report
### Results ###
Model: viomi.vacuum.v8
Total responsives: 36
Total non-empty: 36
All non-empty properties:
{'battary_life': 100,
 'box_type': 1,
 'cur_mapid': [],
 'err_state': 2105,
 'has_map': 1,
 'has_newmap': 0,
 'hw_info': '1.0.1',
 'hypa_hours': [],
 'hypa_life': [],
 'is_charge': 0,
 'is_mop': 0,
 'is_work': 1,
 'light_state': 1,
 'main_brush_hours': [],
 'main_brush_life': [],
 'map_num': [],
 'mode': 0,
 'mop_hours': [],
 'mop_life': [],
 'mop_route': [],
 'mop_type': 0,
 'order_time': '0',
 'remember_map': 1,
 'repeat_state': 0,
 'run_state': 5,
 's_area': 16.76,
 's_time': 18,
 'side_brush_hours': [],
 'side_brush_life': [],
 'start_time': 0,
 'suction_grade': 3,
 'sw_info': '3.5.3_0017',
 'v_state': 0,
 'water_grade': 12,
 'water_percent': [],
 'zone_data': '0'}
Max properties: 2
Done
rytilahti commented 3 years ago

@ontaptom the last commit on the PR considers empty lists (which seem to be those that cause problems) as invalid properties, maybe it works now?

@Skelly82 thanks! We need now someone with v9 to perform the same test so that we can adjust the list of usable properties depending on the device :-) Ping @titilambert

Could you please test if other commands on viomivacuum are working correctly? E.g., miiocli viomivacuum consumable_status?

ontaptom commented 3 years ago

@rytilahti running the full command with last commit on the PR:

 1:09 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ poetry run miiocli device --ip 192.168.0.135 --token <token> test_properties battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life
Running command test_properties
Testing properties ('battary_life', 'box_type', 'cur_mapid', 'err_state', 'has_map', 'has_newmap', 'hw_info', 'is_charge', 'is_mop', 'is_work', 'light_state', 'map_num', 'mode', 'mop_route', 'mop_type', 'remember_map', 'repeat_state', 'run_state', 's_area', 's_time', 'suction_grade', 'v_state', 'water_grade', 'order_time', 'start_time', 'water_percent', 'zone_data', 'sw_info', 'main_brush_hours', 'main_brush_life', 'side_brush_hours', 'side_brush_life', 'mop_hours', 'mop_life', 'hypa_hours', 'hypa_life') for viomi.vacuum.v8
Testing battary_life       100 <class 'int'>
Testing box_type           1 <class 'int'>
Testing cur_mapid          None
Testing err_state          2105 <class 'int'>
Testing has_map            1 <class 'int'>
Testing has_newmap         0 <class 'int'>
Testing hw_info            '1.0.3' <class 'str'>
Testing is_charge          0 <class 'int'>
Testing is_mop             0 <class 'int'>
Testing is_work            1 <class 'int'>
Testing light_state        1 <class 'int'>
Testing map_num            None
Testing mode               0 <class 'int'>
Testing mop_route          None
Testing mop_type           0 <class 'int'>
Testing remember_map       1 <class 'int'>
Testing repeat_state       0 <class 'int'>
Testing run_state          5 <class 'int'>
Testing s_area             0.77 <class 'float'>
Testing s_time             1 <class 'int'>
Testing suction_grade      2 <class 'int'>
Testing v_state            10 <class 'int'>
Testing water_grade        13 <class 'int'>
Testing order_time         '0' <class 'str'>
Testing start_time         0 <class 'int'>
Testing water_percent      None
Testing zone_data          '0' <class 'str'>
Testing sw_info            '3.5.3_0017' <class 'str'>
Testing main_brush_hours   None
Testing main_brush_life    None
Testing side_brush_hours   None
Testing side_brush_life    None
Testing mop_hours          None
Testing mop_life           None
Testing hypa_hours         None
Testing hypa_life          None
Found 24 valid properties, testing max_properties..
Testing 24 properties at once (battary_life box_type err_state has_map has_newmap hw_info is_charge is_mop is_work light_state mode mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time zone_data sw_info): OK for 24 properties

Please copy the results below to your report
### Results ###
Model: viomi.vacuum.v8
Total responsives: 24
Total non-empty: 24
All non-empty properties:
{'battary_life': 100,
 'box_type': 1,
 'err_state': 2105,
 'has_map': 1,
 'has_newmap': 0,
 'hw_info': '1.0.3',
 'is_charge': 0,
 'is_mop': 0,
 'is_work': 1,
 'light_state': 1,
 'mode': 0,
 'mop_type': 0,
 'order_time': '0',
 'remember_map': 1,
 'repeat_state': 0,
 'run_state': 5,
 's_area': 0.77,
 's_time': 1,
 'start_time': 0,
 'suction_grade': 2,
 'sw_info': '3.5.3_0017',
 'v_state': 10,
 'water_grade': 13,
 'zone_data': '0'}
Max properties: 24
Done

Definitely handles better the empty lists :)

As of miiocli viomivacuum commands, I tried:

consumable_status
dnd_status
get_current_position
get_maps
get_rooms
status
info

Unfortunately the most interesting one (I suppose) get_rooms didn't work :/ Results:

1:14 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> consumable_status
Running command consumable_status
<ViomiConsumableStatus filter=1 day, 7:00:00 filter_left=6 days, 5:00:00 main_brush=1 day, 7:00:00 main_brush_left=13 days, 17:00:00 mop=13:00:00 mop_left=AttributeError sensor_dirty=TypeError sensor_dirty_left=AttributeError side_brush=1 day, 7:00:00 side_brush_left=6 days, 5:00:00>

1:15 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> dnd_status
Running command dnd_status
<DNDStatus enabled=True end=09:00:00 start=23:00:00>

1:15 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> get_current_position
Running command get_current_position
None

1:15 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> get_maps
Running command get_maps
ERROR:miio.miioprotocol:Got error when receiving: timed out
Error: No response from the device

1:16 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> get_rooms
Running command get_rooms
ERROR:miio.miioprotocol:Got error when receiving: timed out
Error: No response from the device

1:18 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> status

Traceback (most recent call last):
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/bin/miiocli", line 5, in <module>
    create_cli()
  File "/home/tomek/xiaomi/python-miio/miio/cli.py", line 63, in create_cli
    return cli(auto_envvar_prefix="MIIO")
  File "/home/tomek/xiaomi/python-miio/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/lib/python3.6/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/tomek/.cache/pypoetry/virtualenvs/python-miio-6yipAcUQ-py3.6/lib/python3.6/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/tomek/xiaomi/python-miio/miio/click_common.py", line 285, in wrap
    result_msg = result_msg_fmt.format(**kwargs)
  File "/home/tomek/xiaomi/python-miio/miio/viomivacuum.py", line 336, in fanspeed
    return ViomiVacuumSpeed(self.data["suction_grade"])
  File "/usr/lib/python3.6/enum.py", line 293, in __call__
    return cls.__new__(cls, value)
  File "/usr/lib/python3.6/enum.py", line 535, in __new__
    return cls._missing_(value)
  File "/usr/lib/python3.6/enum.py", line 548, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: None is not a valid ViomiVacuumSpeed

1:18 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$ miiocli viomivacuum --ip 192.168.0.135 --token <token> info
Model: viomi.vacuum.v8
Hardware version: Linux
Firmware version: 3.5.3_0017
1:18 [fix/improve_test_properties] tomek@t1 ~/xiaomi/python-miio$
rytilahti commented 3 years ago

Thanks again for testing!

So these are the extra properties that are supported by v9 and not on v8 (from the currently enabled ones, some of those I gave earlier were commented out): {'map_num', 'cur_mapid', 'mop_route'} Also, the following are not currently queried by viomivacuum, but worked for v8: {'zone_data', 'start_time', 'order_time', 'sw_info'}

Skipping these for v8 should make status work. This will require modifying the code to 1) allow passing the wanted model number and/or 2) doing an info request to obtain the model from the device and adjust the behavior accordingly.

Alas, I don't have any idea about the map/room functionality :-(

patrickg75 commented 3 years ago

To improve the support in this library (and in turn help to get out-of-the-box support for homeassistant at some point), it would be useful if anyone with v8 and v9 could use the test properties and report back here:

miiocli device --ip <addr> --token <token> test_properties battary_life box_type cur_mapid err_state has_map has_newmap hw_info is_charge is_mop is_work light_state map_num mode mop_route mop_type remember_map repeat_state run_state s_area s_time suction_grade v_state water_grade order_time start_time water_percent zone_data sw_info main_brush_hours main_brush_life side_brush_hours side_brush_life mop_hours mop_life hypa_hours hypa_life

..

EDIT: XIAOMI Mi Mop P (viomi v8) Model: STYTJ02YM Pro. Date 06/2020

and "status" is not working for me although : {'map_num', 'cur_mapid', 'mop_route'} are commented out

Results

Model: Total responsives: 24 Total non-empty: 24 All non-empty properties: {'battary_life': 69, 'box_type': 1, 'err_state': 0, 'has_map': 1, 'has_newmap': 0, 'hw_info': '1.0.1', 'is_charge': 1, 'is_mop': 0, 'is_work': 0, 'light_state': 1, 'mode': 0, 'mop_type': 0, 'order_time': '0', 'remember_map': 1, 'repeat_state': 0, 'run_state': 3, 's_area': 5.26, 's_time': 3, 'start_time': 0, 'suction_grade': 1, 'sw_info': '3.5.3_0017', 'v_state': 5, 'water_grade': 12, 'zone_data': '0'} Max properties: 24 Done

nergal commented 3 years ago

As far as I understand, the issue is that the device skips None values in the get_prop command response.

For instance, if you're requesting self.get_properties(['battary_life', 'cur_mapid']) assuming that the cur_mapid property is None, you'll get [100] instead of a [100, None]. Hence it affects property merging and makes values being shifted against its keys in the response of get_properties because of a zip usage in ViomiVacuum.status().

For my Home Assistant integration, I've made a patch for ViomiVacuum class with an override of get_properties method to make it get each of the properties with a separate command call. It allows avoiding that issue however it solidly impacts the performance.