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

chunmi.cooker.r401 unable to query status #1856

Open
danielszilagyi opened this issue Oct 26, 2023 · 4 comments
Open

chunmi.cooker.r401 unable to query status #1856

danielszilagyi opened this issue Oct 26, 2023 · 4 comments
Labels

Comments

@danielszilagyi
Copy link
Contributor

danielszilagyi commented Oct 26, 2023

Describe the bug
I am trying to use a (not yet supported) joyami Smart Rice Cooker(S1/L1) but python-miio is not able to poll the status. The device seems to have the same status endpoints on miot-spec as i.e. the supported chunmi.cooker.normal1, but the status command returns 9999 errors.

Version information (please complete the following information):

  • OS: Linux
  • python-miio: 0.5.12

Device information:
If the issue is specific to a device [Use miiocli device --ip <ip address> --token <token> info]:

  • Model: chunmi.cooker.r401
  • Hardware version: esp32
  • Firmware version: 2.2.0_0008

To Reproduce
Steps to reproduce the behavior:

  1. $ miiocli -dd cooker --ip 192.168.0.190 --token ax56x status

Expected behavior
Status output
Console output

INFO:miio.cli:Debug mode active
DEBUG:miio.click_common:Unknown model, trying autodetection. None None
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#g\xbf{\x00\x00\x0er' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:38
        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: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#g\xbf{\x00\x00\x0er' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:38
        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 2367bf7b with ts: 1970-01-01 01:01:38, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:192.168.0.190:54321 >>: {'id': 1, 'method': 'miIO.info', 'params': []}
DEBUG:miio.miioprotocol:send (timeout 5): Container:
    data = Container:
        data = b'\x10w\x02\xb3\x85\xc5\xda\xfc\xe6\x8bt\x1d\xa5J\xb8\x83'... (truncated, total 48)
        value = {'id': 1, 'method': 'miIO.info', 'params': []}
        offset1 = 32
        offset2 = 80
        length = 48
    header = Container:
        data = b'!1\x00P\x00\x00\x00\x00#g\xbf{\x00\x00\x0es' (total 16)
        value = Container:
            length = 80
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:39
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'_\xd3\xc6J\xc0\xbb\x1c\xe91\x96 \xda\xdc\x90-\xf7' (total 16)
DEBUG:miio.miioprotocol:recv from 192.168.0.190: Container:
    data = Container:
        data = b'.\xfa|&\x81\x8c\xc7\x13=R\xbe\xc0\xcfl\xaeK'... (truncated, total 448)
        value = {'id': 1, 'result': {'life': 3698, 'uid': 1597550502, 'model': 'chunmi.cooker.r401', 'token': 'yy', 'ipflag': 1, 'fw_ver': '2.2.0_0008', 'miio_ver': '0.0.9', 'hw_ver': 'esp32', 'mmfree': 59144, 'mac': 'CC:B5:D1:93:68:76', 'wifi_fw_ver': 'v4.0.1-476-g71f0ccb', 'ap': {'ssid': 'xx', 'bssid': 'yy', 'rssi': -36, 'primary': 9}, 'netif': {'localIp': '192.168.0.190', 'mask': '255.255.255.0', 'gw': '192.168.0.254'}}, 'exe_time': 0}
        offset1 = 32
        offset2 = 480
        length = 448
    header = Container:
        data = b'!1\x01\xe0\x00\x00\x00\x00#g\xbf{\x00\x00\x0er' (total 16)
        value = Container:
            length = 480
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:38
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xfb\x91\xcf\xdb}\xbe\x89x\xb0\x1c\x88\xbb/\xd7k\x17' (total 16)
DEBUG:miio.miioprotocol:192.168.0.190:54321 (ts: 1970-01-01 01:01:38, id: 1) << {'id': 1, 'result': {'life': 3698, 'uid': 1597550502, 'model': 'chunmi.cooker.r401', 'token': 'yy', 'ipflag': 1, 'fw_ver': '2.2.0_0008', 'miio_ver': '0.0.9', 'hw_ver': 'esp32', 'mmfree': 59144, 'mac': 'CC:B5:D1:93:68:76', 'wifi_fw_ver': 'v4.0.1-476-g71f0ccb', 'ap': {'ssid': 'xx', 'bssid': 'yy', 'rssi': -36, 'primary': 9}, 'netif': {'localIp': '192.168.0.190', 'mask': '255.255.255.0', 'gw': '192.168.0.254'}}, 'exe_time': 0}
DEBUG:miio.device:Detected model chunmi.cooker.r401
WARNING:miio.device:Found an unsupported model 'chunmi.cooker.r401' for class 'Cooker'. If this is working for you, please open an issue at https://github.com/rytilahti/python-miio/
DEBUG:miio.miioprotocol:192.168.0.190:54321 >>: {'id': 2, 'method': 'get_prop', 'params': ['all']}
DEBUG:miio.miioprotocol:send (timeout 5): Container:
    data = Container:
        data = b'\xa4\xf5)2FJ\xb2\xc7\xcb\xb5\x82R\xfc<o\xbf'... (truncated, total 64)
        value = {'id': 2, 'method': 'get_prop', 'params': ['all']}
        offset1 = 32
        offset2 = 96
        length = 64
    header = Container:
        data = b'!1\x00`\x00\x00\x00\x00#g\xbf{\x00\x00\x0es' (total 16)
        value = Container:
            length = 96
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:39
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\x84>\x08\xaa\rA\xd7\xbfI!5\x9e\xa9[Y\x7f' (total 16)
DEBUG:miio.miioprotocol:recv from 192.168.0.190: Container:
    data = Container:
        data = b'\tG\xd0\x04\xc7\x0b#|\x95\xa2I\xccfS\xca\xa9'... (truncated, total 80)
        value = {'id': 2, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
        offset1 = 32
        offset2 = 112
        length = 80
    header = Container:
        data = b'!1\x00p\x00\x00\x00\x00#g\xbf{\x00\x00\x0ev' (total 16)
        value = Container:
            length = 112
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:42
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xc7\xa3\x85\xfd\xff\x18\xb3\xc8`,\x1d?=\x80vg' (total 16)
DEBUG:miio.miioprotocol:192.168.0.190:54321 (ts: 1970-01-01 01:01:42, id: 2) << {'id': 2, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
DEBUG:miio.miioprotocol:Retrying to send failed command, retries left: 3
DEBUG:miio.miioprotocol:192.168.0.190:54321 >>: {'id': 3, 'method': 'get_prop', 'params': ['all']}
DEBUG:miio.miioprotocol:send (timeout 5): Container:
    data = Container:
        data = b' ]i\x9f\x8d\xbb6"~\xe1\x1f\'t\x14\x1b\x03'... (truncated, total 64)
        value = {'id': 3, 'method': 'get_prop', 'params': ['all']}
        offset1 = 32
        offset2 = 96
        length = 64
    header = Container:
        data = b'!1\x00`\x00\x00\x00\x00#g\xbf{\x00\x00\x0ew' (total 16)
        value = Container:
            length = 96
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:43
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b"'/a\xd8\xc9\xef\x8fD\xdeE08\xf6:)\xa4" (total 16)
DEBUG:miio.miioprotocol:recv from 192.168.0.190: Container:
    data = Container:
        data = b'#\xc3\x82j\xb6.\x1c?\x16\xf9\x95\xe6\xf31\xd3\xfe'... (truncated, total 80)
        value = {'id': 3, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
        offset1 = 32
        offset2 = 112
        length = 80
    header = Container:
        data = b'!1\x00p\x00\x00\x00\x00#g\xbf{\x00\x00\x0ez' (total 16)
        value = Container:
            length = 112
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:46
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\x1f?\x7ft\xa3\x1a\x7f\xa9\xf6\x9f\x05>\x9f\x07\x050' (total 16)
DEBUG:miio.miioprotocol:192.168.0.190:54321 (ts: 1970-01-01 01:01:46, id: 3) << {'id': 3, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
DEBUG:miio.miioprotocol:Retrying to send failed command, retries left: 2
DEBUG:miio.miioprotocol:192.168.0.190:54321 >>: {'id': 4, 'method': 'get_prop', 'params': ['all']}
DEBUG:miio.miioprotocol:send (timeout 5): Container:
    data = Container:
        data = b'\xacDVk\x19@\x90\x13\xcf\xd4\xb6\xb9\x9d\xe4\xf5\x7f'... (truncated, total 64)
        value = {'id': 4, 'method': 'get_prop', 'params': ['all']}
        offset1 = 32
        offset2 = 96
        length = 64
    header = Container:
        data = b'!1\x00`\x00\x00\x00\x00#g\xbf{\x00\x00\x0e{' (total 16)
        value = Container:
            length = 96
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:47
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\x80\xbd\xd2\x16\x11J\x12\xd0\xd1\xd4F}\x8d<\xef\x93' (total 16)
DEBUG:miio.miioprotocol:recv from 192.168.0.190: Container:
    data = Container:
        data = b'\xe1&\x8cwo\x1e\x0e\xad\xd2\x98\x15\xbb\t\x0e\xb2\x15'... (truncated, total 80)
        value = {'id': 4, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
        offset1 = 32
        offset2 = 112
        length = 80
    header = Container:
        data = b'!1\x00p\x00\x00\x00\x00#g\xbf{\x00\x00\x0e~' (total 16)
        value = Container:
            length = 112
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:50
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b"i\xcf\x17+,\xd4\x94\xa9aE'B\x96j\x03\xb3" (total 16)
DEBUG:miio.miioprotocol:192.168.0.190:54321 (ts: 1970-01-01 01:01:50, id: 4) << {'id': 4, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
DEBUG:miio.miioprotocol:Retrying to send failed command, retries left: 1
DEBUG:miio.miioprotocol:192.168.0.190:54321 >>: {'id': 5, 'method': 'get_prop', 'params': ['all']}
DEBUG:miio.miioprotocol:send (timeout 5): Container:
    data = Container:
        data = b'\xa2\xa2\xbd\xfdFS\xcf%\xd1\xa1\xf6Fp\xeb!Z'... (truncated, total 64)
        value = {'id': 5, 'method': 'get_prop', 'params': ['all']}
        offset1 = 32
        offset2 = 96
        length = 64
    header = Container:
        data = b'!1\x00`\x00\x00\x00\x00#g\xbf{\x00\x00\x0e\x7f' (total 16)
        value = Container:
            length = 96
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:51
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'A\xf4\xfbM\xf9\xd0\xa5\xd6\xc8\xf2\xfdK\x1e\xb4\xfas' (total 16)
DEBUG:miio.miioprotocol:recv from 192.168.0.190: Container:
    data = Container:
        data = b'\xce\xd4\x1f\x80\xe7o\xeb\x15X\x986\xc6(\xc9\xfe\xed'... (truncated, total 80)
        value = {'id': 5, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
        offset1 = 32
        offset2 = 112
        length = 80
    header = Container:
        data = b'!1\x00p\x00\x00\x00\x00#g\xbf{\x00\x00\x0e\x82' (total 16)
        value = Container:
            length = 112
            unknown = 0
            device_id = unhexlify('2367bf7b')
            ts = 1970-01-01 01:01:54
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'5\xd8\xd2\x13\xe82-\xd8N\xf8L\xb4\xb5\x87b\x18' (total 16)
DEBUG:miio.miioprotocol:192.168.0.190:54321 (ts: 1970-01-01 01:01:54, id: 5) << {'id': 5, 'error': {'code': -9999, 'message': 'user ack timeout'}, 'exe_time': 4000}
ERROR:miio.miioprotocol:Got error when receiving: {'code': -9999, 'message': 'user ack timeout'}
DEBUG:miio.click_common:Exception: Unable to recover failed command
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 214, in send
    self._handle_error(payload["error"])
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 274, in _handle_error
    raise RecoverableError(error)
miio.exceptions.RecoverableError: {'code': -9999, 'message': 'user ack timeout'}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 214, in send
    self._handle_error(payload["error"])
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 274, in _handle_error
    raise RecoverableError(error)
miio.exceptions.RecoverableError: {'code': -9999, 'message': 'user ack timeout'}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 214, in send
    self._handle_error(payload["error"])
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 274, in _handle_error
    raise RecoverableError(error)
miio.exceptions.RecoverableError: {'code': -9999, 'message': 'user ack timeout'}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 214, in send
    self._handle_error(payload["error"])
  File "/usr/lib/python3.11/site-packages/miio/miioprotocol.py", line 274, in _handle_error
    raise RecoverableError(error)
miio.exceptions.RecoverableError: {'code': -9999, 'message': 'user ack timeout'}

Querying the PIIDs listed on the miot-spec site returns values.

Running command raw_command
[{'did': '', 'siid': 2, 'piid': 1, 'code': 0, 'value': 2}]
Running command raw_command
[{'did': '', 'siid': 2, 'piid': 2, 'code': 0, 'value': 0}]
Running command raw_command
[{'did': '', 'siid': 2, 'piid': 3, 'code': 0, 'value': 1}]
Running command raw_command
[{'did': '', 'siid': 2, 'piid': 6, 'code': -4001}]
@rytilahti
Copy link
Owner

rytilahti commented Oct 26, 2023

Have you already tried using miiocli genericmiot (available only on git master, see #1808)? That integration uses the miot-spec files to provide support for modern devices.

@danielszilagyi
Copy link
Contributor Author

Hi @rytilahti and thank you for the response! genericmiot seems to return data, I upgraded to the version in the master branch already since fiddling with this.

Running command status
Service [bold]Cooker (cooker)[/bold]
        Status (cooker:status, access: R): Idle (value: 1)
        Device Fault (cooker:fault, access: R): No Faults (value: 0)
        Auto Keep Warm (cooker:auto-keep-warm, access: RW): En-Keepwarm (value: 1) (<class 'int'>, choices: En-Keepwarm (1), Dis-Keepwarm (2))
Service [bold]custom (custom)[/bold]
        status (custom:status, access: R): Waiting (value: 1)
        phase (custom:phase, access: R): 0
        menu (custom:menu, access: R): "0404000000000000000000000000000000000005"
        t-cook (custom:t-cook, access: R): 1:00:00
        t-left (custom:t-left, access: R): 3600 None
        t-pre (custom:t-pre, access: R): 0 None
        t-kw (custom:t-kw, access: R): 0:00:00
        taste (custom:taste, access: R): Soft (value: 0)
        rice (custom:rice, access: R): 0
        akw (custom:akw, access: R): Enkeepwarm (value: 1)
        version (custom:version, access: R): 8
        e-code (custom:e-code, access: R): N-fault (value: 0)
        temp (custom:temp, access: R): 75 None
        push (custom:push, access: R): En-push (value: 0)
        boil (custom:boil, access: R): N-boil (value: 0)
        show-led (custom:show-led, access: R): En-show-led (value: 0)

I am not yet sure how this will bring me closer to my original goal (integrate this device into Home Assistant) but will do some research, this seems a better start.

Before that I tried to do packet captures while controlling the device from the app in Android emulator , but it looks like the device is controlled via the cloud in this case, not locally and parse-pcap returned nothing from my dumps (I supplied the token). I also tried to do a pcap on my router/AP controller, and the packets going to the device were from a TLS stream. Is this also in relation with this being a "modern" device?

@rytilahti
Copy link
Owner

rytilahti commented Oct 26, 2023

For the time being, here are custom components for home assistant that use the miot protocol, see the readme file. The built-in component will eventually get converted to use genericmiot, but it will likely take some time.

The devices themselves often communicate over the cloud instead of using local connections like the genericmiot does, that's why you are seeing those encrypted connections in your pcap :)

@danielszilagyi
Copy link
Contributor Author

I just did the basic setup for this cooker with al-one/hass-xiaomi-miot.
Not all sensors that I saw with miiocli genericmiot are exposed by the integration but this is already a huge progress.
Thank you for pointing me in the right direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants