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

Working with water purifier #48

Closed
nutinshell opened this issue Sep 2, 2017 · 43 comments
Closed

Working with water purifier #48

nutinshell opened this issue Sep 2, 2017 · 43 comments
Labels

Comments

@nutinshell
Copy link

hello, it's working with miio command like: miio --control 10.0.1.8 --token a3d7f95***3 --method get_prop , has working data output, but using mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info failed with error:

INFO:mirobo.vacuum_cli:Debug mode active
ERROR:mirobo.vacuum_cli:Unable to read the stored msgid: [Errno 2] No such file or directory: '/tmp/python-mirobo.seq'
DEBUG:mirobo.vacuum_cli:Connecting to 10.0.1.8 with token a3d7f95***3
ERROR:mirobo.device:Unable to discover a device at address 10.0.1.8
Traceback (most recent call last):
  File "/usr/local/bin/mirobo", line 11, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/mirobo/vacuum_cli.py", line 339, in info
    res = vac.info()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 183, in info
    return DeviceInfo(self.send("miIO.info", []))
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 120, in send
    self.do_discover()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 72, in do_discover
    raise DeviceException("Unable to discover the device %s" % self.ip)
mirobo.device.DeviceException: Unable to discover the device 10.0.1.8

Any idea to get water purifier working? Thanks.

@syssi
Copy link
Collaborator

syssi commented Sep 2, 2017

Your provided commands are doing different things. The first one (miio) sends the command "get_prop" to the device. The second command (via mirobo) sends the command "miIO.info". It looks like your device doesn't support the command. Could you try the same via miio?

miio --control 10.0.1.8 --token a3d7f95***3 --method miIO.info

Do you get a response?

@nutinshell
Copy link
Author

@syssi thanks for the quick response :)

Yes, it has resp.

 INFO  Got result:
{
  "life": 40681,
  "token": "a3d7f95***3",
  "mac": "28:6C:07:xx:xx:xx",
  "fw_ver": "1.2.8",
  "hw_ver": "ESP8266",
  "uid": 166*****,
  "model": "yunmi.waterpuri.v2",
  "mcu_fw_ver": "0019",
  "wifi_fw_ver": "1.4.0(30e0bd0)",
  "ap": {
    "rssi": -56,
    "ssid": "myssid",
    "bssid": "00:A2:EE:xx:xx:xx"
  },
  "netif": {
    "localIp": "10.0.1.8",
    "mask": "255.255.0.0",
    "gw": "10.0.0.1"
  },
  "mmfree": 10976
}

@syssi
Copy link
Collaborator

syssi commented Sep 2, 2017

Cool. This response is good! I'm a bit confused now. ;-) I will read the code again.

@syssi
Copy link
Collaborator

syssi commented Sep 2, 2017

Got it. The CLI tool calls vac.info(). Before DeviceInfo(self.send("miIO.info", [])) can be processed we must discover the device. The discovery fails because the device doesn't respond to the helobytes on port 54321 oddly enough. Hmm.. the discover method of miio and mirobo is equal.

@syssi
Copy link
Collaborator

syssi commented Sep 2, 2017

It looks like a timeout. This is the method call which returns None and raises the Exception:

https://github.com/rytilahti/python-mirobo/blob/master/mirobo/device.py#L58

The called method L77 should output additional debug messages most of the time. There is just one code path which doesn't produce additional outputs: If "is_broadcast" is false and we hit the except block for a socket.timeout. The method will return None now.

Could you execute

mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info

a few times? You can also increase the timeout at L79.

@nutinshell
Copy link
Author

hmm, tried both, but still failed Unable to discover the device

P.S. miio exec time about 5s, increased device.py's timeout to 15.

@syssi
Copy link
Collaborator

syssi commented Sep 3, 2017

I'm out of ideas. Do you have some Teemu? @rytilahti

@rytilahti
Copy link
Owner

Alas not really. @nutinshell are you controlling the device with some other library/device at the same time you are trying to access it with mirobo, maybeb there is a problem with multiple concurrent connections? You could also use -d multiple times (or just do -dd) to get a bit more debug output.

@nutinshell
Copy link
Author

nutinshell commented Sep 3, 2017

@rytilahti tried many times, no one worked. -dd like:

ERROR:mirobo.vacuum_cli:Unable to read the stored msgid: [Errno 2] No such file or directory: '/tmp/python-mirobo.seq'
DEBUG:mirobo.vacuum_cli:Connecting to 10.0.1.8 with token a3d7f95***3
ERROR:mirobo.device:Unable to discover a device at address 10.0.1.8
Traceback (most recent call last):
  File "/usr/local/bin/mirobo", line 11, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/mirobo/vacuum_cli.py", line 339, in info
    res = vac.info()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 183, in info
    return DeviceInfo(self.send("miIO.info", []))
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 120, in send
    self.do_discover()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 72, in do_discover
    raise DeviceException("Unable to discover the device %s" % self.ip)
mirobo.device.DeviceException: Unable to discover the device 10.0.1.8

It's not the concurrent connection issue, just want to make a hass custom sensor by using mirobo, but no luck, hass report the same error like mirobo cli. I found an interesting phenomenon, the hass custom script works one time only this afternoon, and then never works...

@syssi
Copy link
Collaborator

syssi commented Sep 3, 2017

Could you try the same from another host/system? Just for fun. ;-)

@nutinshell
Copy link
Author

@syssi yes, tried on mac, same :) miio worked, mirobo failed :(

@nutinshell
Copy link
Author

Got it. The CLI tool calls vac.info(). Before DeviceInfo(self.send("miIO.info", [])) can be processed we must discover the device. The discovery fails because the device doesn't respond to the helobytes on port 54321 oddly enough. Hmm.. the discover method of miio and mirobo is equal.

@syssi I had a look at https://github.com/aholstenson/miio/, seems quite different with mirobo (I am not very familiar with js or py)

@syssi
Copy link
Collaborator

syssi commented Sep 6, 2017

The question is: Why is miio working for you and mirobo is not? The executed code is the same.

@nutinshell
Copy link
Author

@syssi hmm, no idea, mirobo works with my air purifier but not water purifier, maybe some diffs in handle other devices like water purifier's data. Also, doesn't find mimo send helobytes, am I right?

@syssi
Copy link
Collaborator

syssi commented Sep 6, 2017

@nutinshell
Copy link
Author

@rytilahti
Copy link
Owner

@nutinshell you could try to capture the network traffic caused by miio(js) and see how it compares to python-mirobo. As far as I know miio also uses handshakes (and those are required for some devices like the vacuum to function, as it is the way to gain the timestamp of the device for further requests).

@syssi
Copy link
Collaborator

syssi commented Sep 6, 2017

Good suggestion. I would evalute the capture if you can provide one. Wireshark/tcpdump should be used.

@syssi
Copy link
Collaborator

syssi commented Sep 6, 2017

I compared the javascript implemention of the discovery. It's very similar. The important parts:

https://github.com/aholstenson/miio/blob/master/lib/discovery.js#L97-L108
https://github.com/aholstenson/miio/blob/master/lib/packet.js#L7-L16

There is just one funny thing: The helobytes are a bit different:

Mirobo: 21310020ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
MiioJs: 21310000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff

@rytilahti
Copy link
Owner

rytilahti commented Sep 6, 2017

Hmmm, interesting. Now I'm curious what the official app does. That difference there could be explained by some sort of a flag, which used to work / works in some cases but not in others, iirc I extracted the handshake from the communication of my vacuum..

@nutinshell could you try changing the hello bytes to see if that helps? If yes, maybe we need to adjust that procedure.

@nutinshell
Copy link
Author

Good suggestion. I would evalute the capture if you can provide one. Wireshark/tcpdump should be used.

sure, should I email you directly? :)

@syssi
Copy link
Collaborator

syssi commented Sep 7, 2017

Yes! basti at linkt.de

@nutinshell
Copy link
Author

@nutinshell could you try changing the hello bytes to see if that helps? If yes, maybe we need to adjust that procedure.

change hello bytes not help, in wireshark, it seems miio seeds same hello bytes 21310020

@nutinshell
Copy link
Author

Yes! basti at linkt.de

Sent :D

@rytilahti
Copy link
Owner

@nutinshell could you try to run mirobo discover --handshake 1 before the other commands?

@nutinshell
Copy link
Author

@nutinshell could you try to run mirobo discover --handshake 1 before the other commands?

OK

here is the result:

INFO:mirobo.device:Sending discovery to <broadcast> with timeout of 5s..
INFO:mirobo.device:  IP 10.0.1.8: 758 - token: b'a3d7f9***3'
INFO:mirobo.device:Discovery done

@syssi
Copy link
Collaborator

syssi commented Sep 9, 2017

The request was something like this:

mirobo discover --handshake 1; mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info

Could you give it a try?

@nutinshell
Copy link
Author

@syssi OK

root@hass ~ # ❯❯❯ mirobo discover --handshake 1;mirobo --ip 10.0.1.8 --token a3d7f95*****3 -d info                ✘ 1 
INFO:mirobo.device:Sending discovery to <broadcast> with timeout of 5s..
INFO:mirobo.device:  IP 10.0.1.8: 758 - token: b'a3d7f95****3'
**my many other devices**
INFO:mirobo.device:Discovery done
INFO:mirobo.vacuum_cli:Debug mode active
DEBUG:mirobo.vacuum_cli:Read stored sequence ids: {'manual_seq': 0, 'seq': 6}
DEBUG:mirobo.vacuum_cli:Connecting to 10.0.1.8 with token a3d7****3
ERROR:mirobo.device:Unable to discover a device at address 10.0.1.8
Traceback (most recent call last):
  File "/usr/local/bin/mirobo", line 11, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/mirobo/vacuum_cli.py", line 339, in info
    res = vac.info()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 183, in info
    return DeviceInfo(self.send("miIO.info", []))
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 120, in send
    self.do_discover()
  File "/usr/local/lib/python3.5/dist-packages/mirobo/device.py", line 72, in do_discover
    raise DeviceException("Unable to discover the device %s" % self.ip)
mirobo.device.DeviceException: Unable to discover the device 10.0.1.8

@syssi
Copy link
Collaborator

syssi commented Sep 9, 2017

A pity. It doesn't help.

@nutinshell
Copy link
Author

@syssi @rytilahti I finally found the problem, change https://github.com/rytilahti/python-mirobo/blob/adfa737579f75fb09446a99a6e43775bca293358/mirobo/device.py#L140 range(3) to range(1) solve the problem, seems device doesn't like flood discovery.

To work with water purifier: 1, send a broadcast first; 2, then the IP of request machine free to send any raw command(I still don't know is it forever)

P.S. Another issue, when I send raw_command like get_prop '["mode","press"]', it returns ['idle', 'error'], no matter how much params sent, only the first value is OK, JS miio works fine.

@syssi
Copy link
Collaborator

syssi commented Sep 10, 2017

Do you know which properties are supported?

@nutinshell
Copy link
Author

Do you know which properties are supported?

known currently: ["press","temperature","uv_state","filter_state","elecval_state","uv_life","mode"]

@rytilahti
Copy link
Owner

@nutinshell awesome! So, a broadcast is necessary (and the default "handshake" only on that device is not enoguh) even after you modified the flooding of those requests, if I understood it correctly? IIRC there was no specific reason why I decided to make it send three packets, only "just to be sure they will go through". Maybe this also causes the problem some people are having with the vacuum not answering to discoveries always..

As a side note, different manufacturers have different kind of implementations. E.g. the vacuum cleaner does not advertise over mDNS if the device has no connectivity to the internet. @syssi I recall philips ones did not either, are yours connected to the internet?

@syssi
Copy link
Collaborator

syssi commented Sep 10, 2017

My philips light has internet access. It doesn't advertise over mDNS nevertheless.

@nutinshell
Copy link
Author

So, a broadcast is necessary (and the default "handshake" only on that device is not enoguh) even after you modified the flooding of those requests, if I understood it correctly?

It appears so, have to do mirobo discover --handshake 1 command first.

@syssi
Copy link
Collaborator

syssi commented Sep 11, 2017

I will try to write some proof of concept code tomorrow.

@syssi
Copy link
Collaborator

syssi commented Sep 11, 2017

@nutinshell Sorry I need to ask again: Are you sure about the need of mirobo discover --handshake 1 in front of every command? Just change the to range(1) is not sufficient, right? Could you check it twice? It will involve some overhead per request.

@nutinshell
Copy link
Author

Sorry I need to ask again: Are you sure about the need of mirobo discover --handshake 1 in front of every command?

No, only need to do it one time for the new machine.

@syssi
Copy link
Collaborator

syssi commented Sep 11, 2017

Got it: If you "reboot" your water purifier and call mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info afterwards the device cannot be discovered? If you publish a multicast broadcast by mirobo discover --handshake 1 your host is well known afterwards and you can execute mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info multiple times with success? Could you wait 15 minutes and execute the command (mirobo --ip 10.0.1.8 --token a3d7f95***3 -d info) again? I want to make sure the water purifier doesn't forget about your host.

@nutinshell
Copy link
Author

@syssi after reboot, it still works. I did lot of successful tests after a sleep :)

@syssi syssi added the bug label Sep 14, 2017
@rytilahti
Copy link
Owner

rytilahti commented Jan 20, 2018

Is this still an issue? If not, please close this.

@nutinshell
Copy link
Author

@rytilahti latest mirobo cli still failed, compare to JS miio working fine.

@syssi
Copy link
Collaborator

syssi commented Apr 1, 2018

Cp. #284. We should request all properties by get_prop []. It looks like some firmware version doesn't respond properly to a list of requested properties.

@syssi syssi closed this as completed Apr 1, 2018
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

3 participants