rytilahti / python-miio

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

update-firmware on Xiaomi Mi Robot Vacuum V1 fails #818

Closed keros closed 4 years ago

keros commented 4 years ago

Hi

I got today a new Xiaomi Mi Robot Vacuum (V1) and wan't to install a custom firmware (Valetudo). But fail with some errors. I already did this about a year ago with an other cleaner of the same type which worked fine.

The robot is on accesspoint mode (192.168.8.1). I'm connected with an debian laptop.

mirobo --version
mirobo, version 0.5.3

miiocli --version
miiocli, version 0.5.3

At first I get the token which works fine:

mirobo --debug discover --handshake true
INFO:miio.vacuum_cli:Debug mode active
INFO:miio.miioprotocol:Sending discovery to <broadcast> with timeout of 5s..
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\x17y\x85\x00\x00\x07\xf9' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:34:01
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)
INFO:miio.miioprotocol:  IP 192.168.8.1 (ID: 13177985) - token: b'XXXXXXXXXMyTokenXXXXXXXXXXXX'
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\x17y\x85\x00\x00\x07\xf9' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:34:01
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)
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\x17y\x85\x00\x00\x07\xf9' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:34:01
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)

After that I did some simple tests:

miiocli vacuum --ip 192.168.8.1 --token XXXXXXXXXMyTokenXXXXXXXXXXXX status
Running command status
<VacuumStatus state=Charging, error=No error bat=73%, fan=60% cleaned 0.0 m² in 0:00:00>

miiocli vacuum --ip 192.168.8.1 --token XXXXXXXXXMyTokenXXXXXXXXXXXX consumable_status
Running command consumable_status
<ConsumableStatus main: 0:00:00, side: 0:00:00, filter: 0:00:00, sensor dirty: 0:00:00>

But device info and vacuum info fails:

miiocli --debug device --ip 192.168.8.1 --token XXXXXXXXXMyTokenXXXXXXXXXXXX info
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\x17y\x85\x00\x00\x0c\x8d' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:53:33
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)
DEBUG:miio.miioprotocol:Discovered 13177985 with ts: 1970-01-01 00:53:33, token: b'XXXXXXXXXMyTokenXXXXXXXXXXXX'
DEBUG:miio.miioprotocol:192.168.8.1:54321 >>: {'id': 1, 'method': 'miIO.info', 'params': []}
DEBUG:miio.protocol:Unable to parse json '': Expecting value: line 1 column 1 (char 0)
DEBUG:miio.click_common:Exception: Unable to request miIO.info from the device
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 193, in _decode
    return json.loads(decoded)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 182, in info
    return DeviceInfo(self.send("miIO.info"))
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 147, in send
    command, parameters, retry_count, extra_parameters=extra_parameters
  File "/usr/local/lib/python3.6/dist-packages/miio/miioprotocol.py", line 193, in send
    m = Message.parse(data, token=self.token)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 288, in parse
    return self.parse_stream(io.BytesIO(data), **contextkw)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 300, in parse_stream
    return self._parsereport(stream, context, "(parsing)")
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 1981, in _parse
    subobj = sc._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 2439, in _parse
    return self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 3987, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 4265, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 698, in _parse
    return self._decode(obj, context, path)
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 201, in _decode
    ) from ex
miio.exceptions.PayloadDecodeException: Unable to parse message payload

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 280, in wrap
    kwargs["result"] = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 245, in command_callback
    return miio_command.call(miio_device, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 193, in call
    return method(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 186, in info
    ) from ex
miio.exceptions.DeviceInfoUnavailableException: Unable to request miIO.info from the device
Error: Unable to request miIO.info from the device
miiocli --debug vacuum --ip 192.168.8.1 --token XXXXXXXXXMyTokenXXXXXXXXXXXX info
INFO:miio.cli:Debug mode active
DEBUG:miio.vacuum:Read stored sequence ids: {'seq': 749, 'manual_seq': 0}
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\x17y\x85\x00\x00\x0cc' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:52:51
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)
DEBUG:miio.miioprotocol:Discovered 13177985 with ts: 1970-01-01 00:52:51, token: b'XXXXXXXXXMyTokenXXXXXXXXXXXX'
DEBUG:miio.miioprotocol:192.168.8.1:54321 >>: {'id': 750, 'method': 'miIO.info', 'params': []}
DEBUG:miio.protocol:Unable to parse json '': Expecting value: line 1 column 1 (char 0)
DEBUG:miio.click_common:Exception: Unable to request miIO.info from the device
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 193, in _decode
    return json.loads(decoded)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 182, in info
    return DeviceInfo(self.send("miIO.info"))
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 147, in send
    command, parameters, retry_count, extra_parameters=extra_parameters
  File "/usr/local/lib/python3.6/dist-packages/miio/miioprotocol.py", line 193, in send
    m = Message.parse(data, token=self.token)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 288, in parse
    return self.parse_stream(io.BytesIO(data), **contextkw)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 300, in parse_stream
    return self._parsereport(stream, context, "(parsing)")
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 1981, in _parse
    subobj = sc._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 2439, in _parse
    return self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 3987, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 4265, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 698, in _parse
    return self._decode(obj, context, path)
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 201, in _decode
    ) from ex
miio.exceptions.PayloadDecodeException: Unable to parse message payload

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 280, in wrap
    kwargs["result"] = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 245, in command_callback
    return miio_command.call(miio_device, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 193, in call
    return method(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 186, in info
    ) from ex
miio.exceptions.DeviceInfoUnavailableException: Unable to request miIO.info from the device
Error: Unable to request miIO.info from the device

Also the firmware update fails:

mirobo --debug --ip 192.168.8.1 --token XXXXXXXXXMyTokenXXXXXXXXXXXX update-firmware v11_004018.pkg 
INFO:miio.vacuum_cli:Debug mode active
DEBUG:miio.vacuum_cli:Read stored sequence ids: {'seq': 749, 'manual_seq': 0}
DEBUG:miio.vacuum_cli:Connecting to 192.168.8.1 with token XXXXXXXXXMyTokenXXXXXXXXXXXX
Going to update from v11_004018.pkg
INFO:miio.updater:Serving on 0.0.0.0:35375, timeout 10
INFO:miio.updater:Using local v11_004018.pkg (md5: 270d06419cb00300fac8b15a0619ccfc)
DEBUG:miio.updater:available interfaces: ['enp0s31f6', 'enp0s20f0u9c2', 'wlp2s0']
DEBUG:miio.updater:enp0s31f6 has no ipv4 addresses, skipping
DEBUG:miio.updater:enp0s20f0u9c2 has no ipv4 addresses, skipping
DEBUG:miio.updater:Got addr: 192.168.8.150
Hosting file at http://192.168.8.150:35375/v11_004018.pkg
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\x17y\x85\x00\x00\x0e\x00' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 1970-01-01 00:59:44
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'zBKBIF7b8IUd53zl' (total 16)
DEBUG:miio.miioprotocol:Discovered 13177985 with ts: 1970-01-01 00:59:44, token: b'XXXXXXXXXMyTokenXXXXXXXXXXXX'
DEBUG:miio.miioprotocol:192.168.8.1:54321 >>: {'id': 750, 'method': 'miIO.ota', 'params': {'mode': 'normal', 'install': '1', 'app_url': 'http://192.168.8.150:35375/v11_004018.pkg', 'file_md5': '270d06419cb00300fac8b15a0619ccfc', 'proc': 'dnld install'}}
DEBUG:miio.protocol:Unable to parse json '': Expecting value: line 1 column 1 (char 0)
DEBUG:miio.click_common:Exception: Unable to parse message payload
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 193, in _decode
    return json.loads(decoded)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/vacuum_cli.py", line 610, in update_firmware
    update_res = vac.update(url, md5)
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 197, in update
    return self.send("miIO.ota", payload)[0] == "ok"
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 147, in send
    command, parameters, retry_count, extra_parameters=extra_parameters
  File "/usr/local/lib/python3.6/dist-packages/miio/miioprotocol.py", line 193, in send
    m = Message.parse(data, token=self.token)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 288, in parse
    return self.parse_stream(io.BytesIO(data), **contextkw)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 300, in parse_stream
    return self._parsereport(stream, context, "(parsing)")
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 1981, in _parse
    subobj = sc._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 2439, in _parse
    return self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 3987, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 4265, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 698, in _parse
    return self._decode(obj, context, path)
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 201, in _decode
    ) from ex
miio.exceptions.PayloadDecodeException: Unable to parse message payload
Error: Unable to parse message payload
ERROR:miio.updater:No request was made..

Do I something wrong? Is maybe the firmware version to new? (How do I get the current firmware version?) If the firmware is to new, is there info I can provide to fix this?

rytilahti commented 4 years ago

The update response is odd, but looks like the debug printout happens before the parsing happens. If this device is the new hardware revision of the gen1 vacuum, there may have been some incompatible changes.

If v1 is the first generation rockrobo/xiaomi, it is a known problem that it doesn't respond to info correctly when not connected to the cloud service, so that's expected. Why the update is not working, I don't unfortunately know an answer.

keros commented 4 years ago

Thanks for the infos. After connecting the robot to the cloud info works:

miiocli vacuum --ip 192.168.101.101 --token XXXXXXXXXMyTokenXXXXXXXXXXXX info
Model: rockrobo.vacuum.v1
Hardware version: Linux
Firmware version: 3.5.4_004010
Network: {'localIp': '192.168.101.101', 'mask': '255.255.255.0', 'gw': '192.168.101.1'}
AP: {'ssid': 'test', 'bssid': 'FE:EC:DA:93:21:47', 'rssi': -46}

But the update still fails:

mirobo --ip 192.168.101.101 --token XXXXXXXXXMyTokenXXXXXXXXXXXX --debug update-firmware v11_004018.pkg
INFO:miio.vacuum_cli:Debug mode active
DEBUG:miio.vacuum_cli:Read stored sequence ids: {'seq': 756, 'manual_seq': 0}
DEBUG:miio.vacuum_cli:Connecting to 192.168.101.101 with token XXXXXXXXXMyTokenXXXXXXXXXXXX
Going to update from v11_004018.pkg
INFO:miio.updater:Serving on 0.0.0.0:39185, timeout 10
INFO:miio.updater:Using local v11_004018.pkg (md5: 270d06419cb00300fac8b15a0619ccfc)
DEBUG:miio.updater:available interfaces: ['enp0s31f6', 'enp0s20f0u9c2', 'wlp2s0']
DEBUG:miio.updater:enp0s31f6 has no ipv4 addresses, skipping
DEBUG:miio.updater:enp0s20f0u9c2 has no ipv4 addresses, skipping
DEBUG:miio.updater:Got addr: 192.168.101.100
Hosting file at http://192.168.101.100:39185/v11_004018.pkg
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\x17y\x85_d\xe6\xe8' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('13177985')
            ts = 2020-09-18 16:57:12
        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 13177985 with ts: 2020-09-18 16:57:12, token: b'ffffffffffffffffffffffffffffffff'
DEBUG:miio.miioprotocol:192.168.101.101:54321 >>: {'id': 757, 'method': 'miIO.ota', 'params': {'mode': 'normal', 'install': '1', 'app_url': 'http://192.168.101.100:39185/v11_004018.pkg', 'file_md5': '270d06419cb00300fac8b15a0619ccfc', 'proc': 'dnld install'}}
DEBUG:miio.protocol:Unable to parse json '': Expecting value: line 1 column 1 (char 0)
DEBUG:miio.click_common:Exception: Unable to parse message payload
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 193, in _decode
    return json.loads(decoded)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/miio/vacuum_cli.py", line 610, in update_firmware
    update_res = vac.update(url, md5)
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 197, in update
    return self.send("miIO.ota", payload)[0] == "ok"
  File "/usr/local/lib/python3.6/dist-packages/miio/device.py", line 147, in send
    command, parameters, retry_count, extra_parameters=extra_parameters
  File "/usr/local/lib/python3.6/dist-packages/miio/miioprotocol.py", line 193, in send
    m = Message.parse(data, token=self.token)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 288, in parse
    return self.parse_stream(io.BytesIO(data), **contextkw)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 300, in parse_stream
    return self._parsereport(stream, context, "(parsing)")
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 1981, in _parse
    subobj = sc._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 2439, in _parse
    return self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 3987, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 4265, in _parse
    obj = self.subcon._parsereport(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 312, in _parsereport
    obj = self._parse(stream, context, path)
  File "/usr/local/lib/python3.6/dist-packages/construct/core.py", line 698, in _parse
    return self._decode(obj, context, path)
  File "/usr/local/lib/python3.6/dist-packages/miio/protocol.py", line 201, in _decode
    ) from ex
miio.exceptions.PayloadDecodeException: Unable to parse message payload
Error: Unable to parse message payload
ERROR:miio.updater:No request was made..

But at leat i have now the firmware version 3.5.4_004010. Has someone already tried this with this version or newer? Should it work?

gitcob commented 4 years ago

I have version 3.5.8_004018, I think it's a early model of V1, and info doesn't work either. Not sure how to connect to both the cloud service and still have an access point? I get "unable to parse message payload" for info and update-firmware. Didn't try any of the other commands yet.

gitcob commented 4 years ago

I did a full factory reset like here, got a new token and tried again. Info still didn't work, but uploading the firmware did! Valetudo works for me now.

keros commented 4 years ago

Read the docs and everything gets clear. https://valetudo.cloud/pages/knowledge_base/supported-roborock-devices.html

Does not work on version >= 4004 (I think this is the firmware version part after the _) Because my device is to new (factory date 05.2020) a factory reset will also not work (only brings me back to the version I already have which is to new) So on this approach I'm screwed.

But Dennis Giese made an excellent how to hack it anyway tutorial. https://www.youtube.com/watch?v=sn1tia80nT4&list=PL9PoaNtZCJRZc61c792VCr_I6jQK_IdSb I just have to find my UART cable and also some time to remove about 100 screws from my robot

Thanks for all the help.

mmoscher commented 3 years ago

@keros did you managed to get your Vacuum V1 rooted? My device is too new (factory date 09.2020) as well, not yet sure if I really would try to root it using a UART.

Thanks for your response :+1:

keros commented 3 years ago

Hi yes I rooted my Vacuum V1. The process is nearly the same as in the video for the (Roborock S6/T6).

On the disassemble part:

You don't need to remove all the parts. The wheels can stay in place Also the motor for the side brush can stay in place. If I remember correctly the mainbrush can also stay in place (not sure about that) There are 2 very long screws -> remember the position (they fit also in other holes) Try not to pull on the cables to much when you remove the connetors from the motherboard (was harder than it sounds)

On the flash part:

I did not solder the wires (I did it solderless by holding)

From The cheat sheet: https://builder.dontvacuum.me/x6cheatsheet.txt

I did not do the following (I did not find the string in these two files -> both partitions):

sed -i -E 's/dport 22/dport 29/g' /opt/rockrobo/watchdog/WatchDoge
sed -i -E 's/dport 22/dport 29/g' /opt/rockrobo/rrlog/rrlogd

After I disabled the firewall and had the root password written down I reassembled everything. Then I started the vaccum wlan (reset wlan settings) and connected via ssh to the robot. Then everything runs the same way as in the video (get the firmware, copy it on the robot, ...)