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

mi smart sensor gateway - check status #762

Closed
pete111 opened this issue Jul 18, 2020 · 21 comments
Closed

mi smart sensor gateway - check status #762

pete111 opened this issue Jul 18, 2020 · 21 comments
Labels

Comments

@pete111
Copy link

pete111 commented Jul 18, 2020

hi does your python library work for smart sensor gateway, too?
I would like to check status of smart sensor alarm gateway - how do do this please?
Also option to arm/disarm alarm would be great.

@pete111 pete111 changed the title mi smart sensor gateway mi smart sensor gateway - check status Jul 18, 2020
@rytilahti
Copy link
Owner

rytilahti commented Jul 18, 2020

You can use Gateway class to access (at least some) gateways, you can access the alarm functionality using alarm property. See https://python-miio.readthedocs.io/en/latest/api/miio.gateway.html#miio.gateway.GatewayAlarm for the list of available methods. Example could look something like this:

from miio import Gateway

gw = Gateway("ipaddr")
alarm = gw.alarm
print("current status: %s" % alarm.status())
print("turning on: %s" % alarm.on())

@pete111
Copy link
Author

pete111 commented Jul 19, 2020

You can use Gateway class ... ```

wow, that is super cool :) Thank you!
Btw, any idea please, why it takes so long to get response from gateway? (usually 5-15 seconds) I hoped it will be very fast to get response, but it takes sometimes up to 15 secods (sometimes 1 second, sometimes time out occures).

@rytilahti
Copy link
Owner

Thanks to @starkillerOG who has been working on the gateway support :-)

To the responsiveness issue, poor network connectivity, maybe? Some devices are also more reluctant to answer to the initial handshake sometimes, I suppose, so there may be some retries going on.

@pete111
Copy link
Author

pete111 commented Jul 19, 2020

I found out, that I can check status of device 3 or 5 times, each next time is response delayed +5 seconds more, and then device stops responding (no response anymore) with:
ERROR:miio.miioprotocol:Got error when receiving: timed out
Error: No response from the device

but in the xiaomi home app everything is working and "ping ip" also works ok with 3ms response. that is strange.

@pete111
Copy link
Author

pete111 commented Jul 20, 2020

After a day I can confirm, that something is corrupted when using your library to get status of gateway (or any other cmd). After approx. 5 times of trials gateway switches to "No response from the device".

@rytilahti
Copy link
Owner

Maybe it's related to the sequence numbers? miiocli doesn't save the last used numbers, so it could be that the device blocks the access after it has answered to the "same" request multiple times inside some time frame.

You could try if the device keep responding to handshakes (e.g., miiocli discover --handshake) multiple times. If that works fine, then it is probably related to either the sequence numbers or the message payloads.

@pete111
Copy link
Author

pete111 commented Jul 20, 2020

miiocli discover --handshake shows Error: No such command 'discover'

@rytilahti
Copy link
Owner

Sorry, I forgot that miiocli didn't have that. You can use this for testing it: mirobo discover --handshake 1

@pete111
Copy link
Author

pete111 commented Jul 20, 2020

thanks, I am getting constantly this:

INFO:miio.miioprotocol:Sending discovery to <broadcast> with timeout of 5s..
INFO:miio.miioprotocol:Discovery done

@rytilahti
Copy link
Owner

Hmh, maybe it is broadcasting over the wrong interface (if you have many), as it is not detecting any devices whatsoever.

You could alternatively try a python script something like this:

from miio import Device
import time
dev = Device("<ip>", "<token>")
while True:
    print(dev.send_handshake())
    time.sleep(1)  # sleep 1 sec between requests

@pete111
Copy link
Author

pete111 commented Jul 21, 2020

hi, thanks, python script works and I am getting this every second (just removed data values):

Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1datavalues' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = unhexlify('another value')
            ts = 2020-07-21 05:23:40
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'another datavalues' (total 16)

@rytilahti
Copy link
Owner

What happens if you call .status() instead of handshake sending? Does it also work? If yes, then it's about the sequence numbers.

@pete111
Copy link
Author

pete111 commented Jul 21, 2020

What happens if you call .status() instead of handshake sending? Does it also work? If yes, then it's about the sequence numbers.

from miio import Device
import time
dev = Device("ip", "token")
while True:
    print(dev.status())
    time.sleep(1) 

AttributeError: 'Device' object has no attribute 'status'

@rytilahti
Copy link
Owner

rytilahti commented Jul 21, 2020

Ah, sorry, info() is the command which will output some device information. You can see the whole API here: https://python-miio.readthedocs.io/en/latest/api/miio.device.html#miio.device.Device.info . Aand for gateway itself here: https://python-miio.readthedocs.io/en/latest/api/miio.gateway.html#miio.gateway.Gateway .

@pete111
Copy link
Author

pete111 commented Jul 21, 2020

ok, so I tried it and here are results:
when I run python3 myscript.py, then every second is received info successfully.

Then after few seconds I kill script. I am able to rerun script 5 times totally (run it, wait for info, then kill it).
On 6th attempt and on every next attempt I am getting "miio.exceptions.DeviceException: No response from the device". So it seems to be an issue witj sequence numbers. What with it? It would be cool to reuse some sequence number from previous session if possible. No idea, if I understand sequence numbers correctly, but reusing of sequence number could solve this issue. I can test it if you tell me how.

@rytilahti
Copy link
Owner

rytilahti commented Jul 21, 2020

It really depends on what is your use case, to be honest. If it is your own python script you are using, you can simply save the sequence number and read it back when the script gets launched again.

That approach used by the mirobo tool (here how it's read back from the file https://github.com/rytilahti/python-miio/blob/master/miio/vacuum_cli.py#L59 and here how it gets written back https://github.com/rytilahti/python-miio/blob/master/miio/vacuum_cli.py#L86). This should probably be made more generic for miiocli, too.

If you have a long running process (like homeassistant), there is no need such as the library handles increments and roll-overs of sequence numbers automatically.

@pete111
Copy link
Author

pete111 commented Jul 21, 2020

I experiemnted with it and tried something like dev = Device("ip", "token", 565) but it does not work
somehow I must initiate connection and print id to console. Then in second script I should probably use the same number. If any sample is available, it is highly appreciated.

@rytilahti
Copy link
Owner

See the links I gave above. A very minimalistic example could be something like this:

from miio import Vacuum
from pathlib import Path

seq_file = Path("filetostorethesequence")
try:
    seq = int(seq_file.read_text())
except FileNotFoundError: # if the file doesn't exist, start with 0
    seq = 0

vac = Vacuum("ip", "token", seq)
vac.start()
seq_file.write_text(vac.raw_id)  # save the current sequence number

@pete111
Copy link
Author

pete111 commented Jul 28, 2020

perfect thanks. This should work for Vacuum.
I serached for raw_id property in API documentation of Gateway/Gatewayalarm/Device but it seems there is not raw_id property. Is there any equivalent for it in this module? I basically work with gatewayalarm. But maybe there is a way how to extract raw_id from another property for this device?

@rytilahti
Copy link
Owner

Good catch! I thought it was part of the device class where it's supposed to be... I just created a PR to fix it: #776, but until then you can simply use dev._protocol.raw_id which is what the raw_id wrapper does as you can see in https://github.com/rytilahti/python-miio/blob/master/miio/vacuum.py#L653

@rytilahti
Copy link
Owner

I'll close this now, please feel to reopen if you still have issues.

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