python-miio
python-miio copied to clipboard
Add support for 'lumi.gateway.mieu01' subdevices
The EU version of the gateway is supported in the current versión of the library and can be intergated in HA.
Some tests had been made to evaluate subdevices resolution with no success:
(venv)$ python /tmp/test_miio_gateway/gateway_devices.py
Traceback (most recent call last):
File "/tmp/test_miio_gateway/gateway_devices.py", line 5, in <module>
gateway.discover_devices()
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 168, in discover_devices
devices_raw = self.get_prop("device_list")
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 207, in get_prop
return self.send("get_device_prop", ["lumi.0", property])
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/device.py", line 147, in send
command, parameters, retry_count, extra_parameters=extra_parameters
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 203, in send
self._handle_error(payload["error"])
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 263, in _handle_error
raise DeviceError(error)
miio.exceptions.DeviceError: {'code': -5005, 'message': 'params error'}
where gateway_devices.py:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken")
gateway.discover_devices()
devices = gateway.devices
for dev in devices:
dev.update()
print(dev)
@starkillerOG sugest (home-assistant/core#22078) a new approach with the get_device_list command.
@javicalle alright lets see if we can get this working:
- try testing this code as a start:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken")
print(gateway.info())
That will print basic information about your gateway and that will confirm that the communication is okay. (although since it works with the HomeAssistant integration this schould not be a problem)
-
open the
gateway.pyfile of the miio library that schould be located in your virtuel python enviroment (in my case venv) at a path simular to:venv/lib/python3.7/site-packages/miio/gateway.py -
scroll down to line 151 and add this function in between the
def devices(self):anddef discover_devices(self):functions (actually the postion where you add it does not matter that much):
@property
def test(self):
return self.send("get_device_list")
- now try running this test code:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken")
print(gateway.test())
Hopefully that will print a list of your subdevices..... fingers crossed....
@javicalle actually now that I think of it, steps 2 till 4 can simply be replaced by running this test code:
from miio import Gateway gateway = Gateway("192.168.1.IP", "tokentokentoken") print(gateway.send("get_device_list"))
Here are the results (some values have been obfuscated):
lumi.gateway.mieu01 v3.5.8_147 (AA:BB:CC:DD:EE:FF) @ 192.168.0.166 - token: 12345678901234567890123456789012
and the gateway.send("get_device_list") part:
Got error when receiving: timed out
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/tmp/test_miio_gateway/gateway_devices.py", line 8, in <module>
print(gateway.send("get_device_list"))
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/device.py", line 147, in send
command, parameters, retry_count, extra_parameters=extra_parameters
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 230, in send
raise DeviceException("No response from the device") from ex
miio.exceptions.DeviceException: No response from the device
Also tested with same results:
gateway = Gateway("192.168.0.166", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
Also tested with same results:
gateway = Gateway("192.168.0.166", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
That was indeed what I was going to sugest ;)
Well it does look like your gateway is recognizing the "get_device_list" command.
If I run the same command on my gateway.v3 I get a replay of:
miio.exceptions.DeviceError: {'code': -32601, 'message': 'Method not found.'}
Could you try running some random fake command like "test123" and see if you then also get the Method not found error, that would comfirm that your gateway recognizes the "get_device_list" command.
How many subdevices do you have connected to your gateway? The timeout error seems to be very simular to the issue we are currently having with PR: https://github.com/rytilahti/python-miio/issues/650
Unfortuanately I do not yet have an idea how to resolve that timeout issue.... Is your gateway updated to the latest firmware available?
@rezmus do you have an idea where this timeout is comming from, is it indeed because too many devices are connected and the response message grows too big for the gateway?
Do you have any ideas how to resolve that? (sorry for involving you, but you seem to know a lot about these gateways)
lumi.gateway.miXXXX and lumi.gateway.aqhm0X do not provide a way to get subdevices list. you need to define them yourself.
I get the same error.
Now the file content is:
from miio import Gateway
gateway = Gateway("192.168.0.166", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
print(gateway.info())
print('-----')
print(gateway.send("no_method"))
And there are 5 devices connected to gateway.
@javicalle apperently you cannot obtain the device list on the 'lumi.gateway.mieu01' according to @rezmus which is quite a dissapointment... We could at some point see if sniffing traffic using bluestack and wireshark provides us with some way to discover which devices are connected, but since @rezmus knows a lot about the firmware I guess there is no command.
Although I do find it strage that the gateway does not simply give the "method not found" as response to the "get_device_list" so maybe there is still some hope...
For now lets first test if the subdevices actually work the same way, otherwise it is going to be a big effort to get 'lumi.gateway.mieu01' support.
@javicalle do you know the sid and devicetype of your 5 connected subdevices? For me I can see them In the MiHome app -->gateway--> ... --> About --> Hub info (the same place where I can find the gateway token).
If so you can try:
from miio import gateway
hub = gateway.Gateway("192.168.0.166", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
sid = "lumi.SidSidSidSid"
device_type = 19
subdevice_cls = gateway.AqaraHT
dev_info = gateway.SubDeviceInfo(sid, device_type, 1, 1, 3)
dev = subdevice_cls(hub, dev_info)
dev.update()
print(dev)
where sid is the sid of the subdevice
dev_type is the number representing the subdevice type (can be looked up from the model in the gateway.py file in the list on lines 39 to 90 class DeviceType(IntEnum):)
and the subdevice class can also be found in this same list, in the example I used the AqaraHT temperature sensor (lumi.weather.v1)
I only have 3 different types of devices:
- Mi Window and Door sensor
- Mi Motion Sensor
- Mi Wireless Switch
My "Xiaomi Home" app don't have this option (no 'About' option available), and I have get the device info from others sources.
- modified "Xiaomi Home" app from 'vevs': https://www.kapiba.ru/2017/11/mi-home.html
- HA zha integration: I have a sensor integrated through a ZHA bridge and not from the Xiaomi Hub
The modified app gives to me this info:
Did: lumi.158d000396cb70
Name: Mi Window and Door Sensor
Model: lumi.sensor_magnet.v2
Did: lumi.158d0003a40c79
Name: Mi Motion Sensor 2
Model: lumi.sensor_motion.v2
Did: lumi.158d0003a476f6
Name: Mi Wireless Switch
Model: lumi.sensor_switch.v2
If my interpretation is correct, it does not fit with any of the currently implemented models.
Anyway, I have tested the 2 available implementations with the motion sensor:
- Motion = 2 # lumi.sensor_motion
- AqaraMotion = 52 # lumi.sensor_motion.aq2
(I had to overwrite my venv's gateway class with the last one from the repository)
In both cases I have had the same error:
(venv)$ python /tmp/test_miio_gateway/gateway_subdevices.py
lumi.gateway.mieu01 v3.5.8_147 (AA:BB:CC:DD:EE:FF) @ 192.168.0.166 - token: 12345678901234567890123456789012
-----
Got error when receiving: timed out
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 182, in send
data, addr = s.recvfrom(1024)
socket.timeout: timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 777, in send
return self._gw.send(command, [self.sid])
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/device.py", line 147, in send
command, parameters, retry_count, extra_parameters=extra_parameters
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 226, in send
extra_parameters=extra_parameters,
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/miioprotocol.py", line 230, in send
raise DeviceException("No response from the device") from ex
miio.exceptions.DeviceException: No response from the device
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/tmp/test_miio_gateway/gateway_subdevices.py", line 20, in <module>
print(dev)
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 725, in __repr__
self.get_battery(),
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 850, in get_battery
self._battery = self.send("get_battery").pop()
File "/opt/DevelopmentSpace/hassio/home-assistant/venv/lib/python3.7/site-packages/miio/gateway.py", line 781, in send
) from ex
miio.gateway.GatewayException: Got an exception while sending command get_battery
I continue doing some tests
I have modified my gateway.py this way:
class DeviceType(IntEnum):
"""DeviceType matching using the values provided by Xiaomi."""
Unknown = -1
Gateway = 0 # lumi.0
Switch = 1 # lumi.sensor_switch
Motion = 2 # lumi.sensor_motion
MotionV2 = 222 # lumi.sensor_motion.v2 for testing purposes
.../...
@command()
def discover_devices(self):
"""
Discovers SubDevices
and returns a list of the discovered devices.
"""
# from https://github.com/aholstenson/miio/issues/26
device_type_mapping = {
DeviceType.Switch: Switch,
DeviceType.Motion: Motion,
DeviceType.MotionV2: MotionV2, # probably not necessary
class MotionV2(SubDevice):
"""Subdevice Motion specific properties and methods."""
properties = []
_zigbee_model = "lumi.sensor_motion.v2"
_model = "RTCGQ01LM"
_name = "Motion sensor v2"
The _model value is written on the physical device, so I'm sure it's correct.
Now, my test class is the next one:
from miio import gateway
hub = gateway.Gateway("192.168.0.166", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
print(hub.info())
print('-----')
sid = "lumi.158d0003a40c79"
device_type = 222
subdevice_cls = gateway.MotionV2
dev_info = gateway.SubDeviceInfo(sid, device_type, 1, 1, 3)
dev = subdevice_cls(hub, dev_info)
dev.update()
print(dev)
print('+++++')
With these changes I get exactly the same error.
get_battery method is not supported by these hubs.
I just commented the print(dev) commands and no errors are generated.
But I can't find a send or get_property to validate it's really working against device.
@javicalle the motion sensor, door sensor and button do not have specific properties you can get. (only subscriptions to events but that still needs to be implemented).
Besides the get_battery there only are two other general commands known at this point:
dev.get_property("fw_ver") (get the firmware version of the subdevice)
dev.send("remove_device") (unpair the device from the gateway, may not want to try this...)
You could try those...
In general there are 5 functions to interact with the device:
dev.send("test_command")
dev.send_arg("test_command", ["argument1", "argument2"])
dev.get_property("property")
dev.get_property_exp(["property"])
dev.set_property("property", "value")
So you can play around with those functions, but you will need to know or be very lucky to guess the commands/properties....
If you truly want to figure out commands/properties you will need to sniff the trafic of the MiHome app and see if you can discover commands/properties that work with this gateway.
I was able to sniff trafic using BlueStack (an android emulator for windows), install MiHome App and then capture packets using wireshark --> export as json and use the miio tool https://github.com/aholstenson/miio to decode the packets.
dev.get_property("voltage") dev.get_property("lqi")
dev.get_property("voltage") dev.get_property("lqi")
@rezmus on my gateway 'lumi.gateway.v3' those two give my empty responses [], the same as if I issue a random non existing property like dev.get_property("this_does_not_exist")
@javicalle but you can certainly try those on your gateway.
My results:
dev.get_property("fw_ver")--> ERRORdev.get_property("voltage")--> OK: [2995]dev.get_property("lqi")--> ERROR
aqara hubs can read lqi, mi hubs can't.
@rezmus my hub 'lumi.gateway.v3' which is to my knowladge an chinese aqara hub gives an empty response on dev.get_property("lqi").
@javicalle intresting that the voltage works on 'lumi.gateway.mieu01' but does not on 'lumi.gateway.v3'
At this point it is pretty clear that the 'lumi.gateway.mieu01' supports different commands than the 'lumi.gateway.v3'. So someone who has acces to a 'lumi.gateway.mieu01' will have to do some development to get it supported with one of the biggest isues beeing there is no way to get the device_list.
If the device_list was the only problem I could have made a workaround by letting users configure a manual device_list, but since there are more commands that differ, that method is going to run into problems. withouth having acces to the device ('lumi.gateway.mieu01') I can therefore not easily implement support.... I am sorry @javicalle.
Of course it would be awesom if you could implement support @javicalle and I am open to helping and giving feedback on PR's for that, but that will be some effort.
lumi.gateway.v3 - mi cn (called 2nd gen)
lumi.gateway.miXXXX - mi global hubs lumi.gateway.aqhm0X - aqara hubs
in contrast to mi cn, aqara and mi global have almost similar hardware/firmware and run embedded linux (arm), but aqara is way better supported (new devices).
all 3 hubs should work more or less the same for core methods to get/set props and invoke actions on subdevices, however they may vary on the list of supported models and minor stuff.
This schould prevent some errors on the 'lumi.gateway.mieu01': https://github.com/rytilahti/python-miio/pull/732
@rezmus do you have any sugestion to get a list of connected devices for 'lumi.gateway.mieu01' (does not matter if we get zigbee_id or the integer mapping values)? Would it be hard/possible to get the device list from the cloud (is there some python libary to do this)?
i took a look at firmware and i doubt there is such method. also never seen xiaomi cloud api reverse engineered. i think only solution is custom mi home version which dumps whole devices list to file.
There are some pieces of the cloud api used by openhab (namely for the token extraction, https://www.openhab.org/addons/bindings/miio/#tokens), so it could be possible to obtain other information the same way.
I don't know about other open source implementations for the API, porting the cloud access would require some serious effort, especially to keep the details similar to openhab's to avoid getting blocked by the servers. As like to keep this library offline-only, such functionality should be externalized to another project.
Thanks for the hint @rytilahti! I looked at the source code of the openhab miio addon and indeed they figured out a cloud connection using the acount name and password that you also use in the app. From the looks of it there is already code to get the tokens and device list (not only for the gateway but also for other general miio devices) The source code is here:
- https://github.com/openhab/openhab-addons/tree/2.5.x/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud
- https://github.com/openhab/openhab-addons/blob/2.5.x/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudConnector.java
Unfortunately the code is written in java which I don't know. I don't have time to deceiver the java and make a python lib from it, but someone will probably have to do that to get the 'lumi.gateway.mieu01' properly supported.
@javicalle do you happen to know java?
@rytilahti I agree that online cloud connection code would be best implemented in a separate python library. Would it be alright with you if such a separate library would be used within python-miio as a dependency?
@starkillerOG I don't think it's a good idea to make python-miio to be directly dependent, if such library would be created. I think a proper way would be to make it possible to feed a list of available devices to the gateway class, then it wouldn't be dependent on any potential issues with the cloud access. The device list could simply be a simple ini/json configuration file with list of devices (and other things, if needed), which could also be manually filled, e.g., based on the information shown by the official app.
Apologize for being absent all this time. Right now my work has me very busy and I do not have the tranquility to dedicate time to hobbies.
@javicalle do you happen to know java? Yes, I'm more a Java boy than a Python one. But my knowledge is far from being able to create a complete library. I can read and interpret the code, but migrate the library with its dependencies to Python is something that is too big for me.
I want to thank everyone for their dedication in this matter and I regret not being on par with other contributions
Let me know if I can contribute on this subject. I'm in the same position with @javicalle. Integration works only with "Arm Away" option. I also successfully controlled the LED on the gateway with miiicli. I'm sure that feature can be integrated on home assistant as well. I'm also able to access firmware of the device, as I was using it with hacked "miio_client" into the device. I also have all of the SID's of my subdevices. In addition to @javicalle, I also have the combined temperature/humdity sensor, which may be of help. @starkillerOG
@serhatozkara you could try:
from miio import gateway
hub = gateway.Gateway("192.168.1.IP", "tokentokentoken")
sid = "lumi.SidSidSidSid"
device_type = 19
subdevice_cls = gateway.AqaraHT
dev_info = gateway.SubDeviceInfo(sid, device_type, 1, 1, 3)
dev = subdevice_cls(hub, dev_info)
dev.update()
print(dev)
where you need to fill in the IP, token and sid of one of your temperature sensors. If that works and prints the info including the temperature of the sensor we know that device commands are the same for the lumi.gateway.mieu01
The gateway light can be integrated into HomeAssistant quite easily, just did not have time to clean-up the code and add it to HomeAssistant.
The big problem for the lumi.gateway.mieu01 is to get the subdevice list in order to add all the devices. See this comment: https://github.com/rytilahti/python-miio/issues/728#issuecomment-645856902. Someone will need to convert that java code to python in order to get the subdevice list from the cloud. As a bonus that will also give us the ability to obtain tokens from the cloud with just the xiaomi account credentials, that would make setting up the integration a lot easier for users and I think that does not only hold for the gateway, but also for all other xiaomi products...
Oh boy!
Here's the response from sensor:
device AqaraHT: lumi.158d00045ad7cd, model: WSDCGQ11LM, zigbee: lumi.weather.v1, fw: 3, bat: None, vol: 3.025, props: {'temperature': 26.02, 'humidity': 66.21, 'pressure': 0.0}>
@starkillerOG I don't know java either but many people from work does. Let's see if can get it done there...
@serhatozkara great, that means subdevices can indeed be controlled and read with a lumi.gateway.mieu01! So basically we only need to get the subdevice list of connected zigbee devices (probably from the cloud) and we would be good to go.
@starkillerOG i dont know if its what you need:
in Mi app go to gateway/.../About click 5 times in empty space go to last Chinese writing with 4 charakter and there is view with settings and list of devices.
So how you add Aqara bulbs to HA?
@arekkwi yes that is basically the list that I need, but I need to get that list using python code. The MiHome app gets that list from the cloud (not through communication with the gateway), so bassicaly the code needs to be written to do the same as the MiHome app and get that list from the cloud. This comment: #728 refers to some Java code that is capable of doing exactly that, so that needs to be rewritten in python to use with HomeAssistant.
Regarding the Aqara bulb, the AqaraSmartBulbE27 is already implemented in the python-miio library. So only the code to add it in HomeAssistant needs to be written (fairly simple to do). Than it would work with the chinese gateways, for the lumi.gateway.mieu01 the above mentioned device list code first needs to be written.
@starkillerOG I've made some digging on the Java example and retrieved some useful info. Actual sign in is done on: https://github.com/openhab/openhab-addons/blob/7628135323df6f07e3c2993d7b816a16e334d849/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/MiCloudConnector.java
With some mitmproxying and inspecting java code, I've successfully signed in to my account with postman. Not only cloud connection gives device list, it also lists the necessary tokens for all of the devices! I've limited knowledge on python, but can provide insight on the development needed. Simple libraries are needed: http client, cookie handling, and HMAC encoding. Hope this points us in the right direction...
@serhatozkara That is greath news!
I probably will not have time to write a python lib for this is the near future. But it would greatly help if you could post a list of HTTP commands and responses that you used with postman to get the device list and necesarry tokens!
@starkillerOG here is a sample response from device_list service. I'll add simple py codes to sign in to cloud if I can :)
"code": 0,
"message": "",
"result": {
"list": [
{
"did": "27xxx",
"uid": 1791xxx,
"token": "TOKEN",
"name": "Mi Control Hub",
"pid": 0,
"localip": "192.168.255.255",
"mac": "FF:EC:FF:EE:FF:FF",
"ssid": "SSID",
"bssid": "FF:FF:27:83:53:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"show_mode": 1,
"model": "lumi.gateway.mieu01",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:gateway:0000A019:lumi-mieu01:1",
"extra": {
"isSetPincode": 0,
"fw_version": "3.5.8_147",
"mcu_version": "0143",
"isSubGroup": false
},
"orderTime": 1594794957
},
{
"did": "lumi.158d000xxx",
"uid": 1791xxx,
"token": "",
"name": "Yatak odası",
"pid": 3,
"mac": "",
"ssid": "sozkara",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_magnet.v2",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:magnet-sensor:0000A016:lumi-v2:1",
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587138824
},
{
"did": "lumi.158d000xxx",
"uid": 179xxx,
"token": "",
"name": "Salon Hareket Sensörü",
"pid": 3,
"mac": "",
"ssid": "sozkara",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_motion.v2",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:motion-sensor:0000A014:lumi-v2:1",
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587138824
},
{
"did": "lumi.158d000xxx",
"uid": 179xxx,
"token": "",
"name": "Switch",
"pid": 3,
"mac": "",
"ssid": "sozkara 2.4 ghz",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_switch.v2",
"permitLevel": 16,
"isOnline": true,
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587138824
},
{
"did": "lumi.158d000xxx",
"uid": 179xxx,
"token": "",
"name": "Giriş Kapı",
"pid": 3,
"mac": "",
"ssid": "sozkara",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_magnet.v2",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:magnet-sensor:0000A016:lumi-v2:1",
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587138824
},
{
"did": "lumi.158d00xxx",
"uid": 179xxx,
"token": "",
"name": "Yatak odası Hareket Sensörü",
"pid": 3,
"mac": "",
"ssid": "sozkara",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_motion.v2",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:motion-sensor:0000A014:lumi-v2:1",
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587138824
},
{
"did": "lumi.158d00xxx",
"uid": 179xxx,
"token": "",
"name": "Temperature and Humidity Sensor",
"pid": 3,
"mac": "",
"ssid": "sozkara",
"bssid": "FF:EC:FF:EE:FF:FF",
"longitude": "0.00000000",
"latitude": "0.00000000",
"parent_id": "275955172",
"show_mode": 0,
"model": "lumi.sensor_ht.v1",
"permitLevel": 16,
"isOnline": true,
"spec_type": "urn:miot-spec-v2:device:temperature-humidity-sensor:0000A00A:lumi-v1:1",
"extra": {
"isSetPincode": 0,
"isSubGroup": false
},
"orderTime": 1587139338
}
],
"next_start_did": "lumi.158d000xxxx",
"has_more": false
}
}
edited by @rytilahti: added triple-backtips for formatting, and masked the uid & the dids that are connected to your account.
@serhatozkara looks greath, that contains all the information we currently need. Would be greath if you could make some simple python code to get this dict.
@starkillerOG Hello again, I successfully signed in to Xiaomi Cloud and get the service token needed for every request to the device API's with python. Code is very crude and primitive so excuse me for that but still, this can pave way to a library. I started with http.client and proceeded with requests library to have both. I need to find a way to generate _nonce cookie values to proceed. It is done here on Openhab connector: https://github.com/openhab/openhab-addons/blob/7628135323df6f07e3c2993d7b816a16e334d849/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudUtil.java#L119 Also here's official implementation: https://github.com/xiaomi-passport/oauth-python-sdk/blob/81a1e2859f11d2bfcd4c1daae5138459d1a457d8/python/XMUtils.py It would be great if someone with better Python knowledge can help me on this as I don't have enough time to dedicate.
To Do: Exception and error handling To Do: Generate random device ID To Do: Use requests sessions. To Do: Generate _nonce, signed _nonce, signature To Do: cloud country server selector To Do: Domain name generator based on country selection
After this, we can finally make requests to cloud servers regarding devices. A sample request would be:
import requests
url = "https://sg.api.io.mi.com/app/v2/user/get_device_cnt"
payload = "_nonce=JgzXhBfls0oBlZQf&data=%7B%22fetch_own%22%3Atrue%2C%22fetch_share%22%3Atrue%2C%22accessKey%22%3A%22IOS00026747c5acafc2%22%7D&signature=KfGAAHAr%2Bm9ZOsMZngvGDkePg6syv2UafbDj/fG5gDE%3D"
headers = {
'User-Agent': ' iOS-13.5.1-4.32.2-iPhone9,3--A5F96298791853B3E596085281DDB3C2ACE489C7-1791780321-054089ED3F43247A',
'Content-Type': 'application/x-www-form-urlencoded'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
xiaomi.py.txt Best!
when it will be possible to access the new platform via cloud for xiaomi gateways
@matteos1 Please doesn't spam multiple repos and issues.
I've implemented a simple python module to connect to Xiaomi cloud. I'm new to python and it's very early in development. Currently you can only login and get the list of devices and their information/tokens. Feel free to use any code or tell me what you need to get the gateway working.
https://github.com/squachen/micloud
@Squachen perfect, looks exactly like what we need. Unfortunately I cannot test it out because I am currently moving and all my equipment is in boxes... But with this it schould not be difficult anymore to get the lumi.gateway.mieu01 fully supported.
I am currently looking into getting the lumi.gateway.mgl03 working see https://github.com/rytilahti/python-miio/issues/807 That requires a very simular way of setting up the subdevices (match the zigbee_model to the type_id and then initialize the subdevice). @Oleg-I is testing this out for me so if that works I will see if I can write some code for the lumi.gateway.mieu01, but it will be buggy because I can't test it myself...
I could use @Squachen script successfully and got the list. I could then probe my own subdevices for things like voltage. Thanks all and especially @Squachen for this big advancement.
But without event subscription, there is not much I can do with those as personally I'm looking into getting the state of door and motion sensors (and the gateway alarm but that's another problem). Any lead on that?
I can help with the code for subdevice support, but could maybe @starkillerOG help with those design question:
- micloud should not be a dependency of python-miio, right? So systems like home assistant would use micloud and pass the JSON (or just sids + type?) to python-miio? Or is the inclusion of micloud acceptable?
- How far should support go into home assistant given that most subdevice are useless without sensors? Would be pretty much useless to have the list of sub-devices as entities that only have the voltage, basically...?
Great work @Squachen, it's great to have yet another way to obtain the tokens besides using an old version of mi home or some other tricks!
But without event subscription, there is not much I can do with those as personally I'm looking into getting the state of door and motion sensors (and the gateway alarm but that's another problem). Any lead on that?
PR #709 is aiming to allow python-miio to act as an event sink for separate devices.
- micloud should not be a dependency of python-miio, right? So systems like home assistant would use micloud and pass the JSON (or just sids + type?) to python-miio? Or is the inclusion of micloud acceptable?
I have been contemplating on this, and I'd like to keep this library independent from any sort of cloud activities.
That being said, having a "device database" inside python-miio to allow keeping device-specific data (last used sequence id, ip address, token, model, etc.) in json/some other serialization format has been for a long time on my todo list. This store could definitely be populated by discovery, or other means, like using the micloud, or importing the data from the data stores of other implementations (openhab, javascript miio), so I'm not hardly against some sort of optional integration for this.
- How far should support go into home assistant given that most subdevice are useless without sensors? Would be pretty much useless to have the list of sub-devices as entities that only have the voltage, basically...?
Are you sure that they don't have any other sensors (maybe battery at least)? I think the decision should be done case-by-case basis, but for some people even having the battery information can be useful to have.
@tbarbette @rytilahti I think motion and door sensors etc schould wait untill PR #709 is finished before they get added to HomeAssistant. However there are many more devices like plug sockets, wall switches, light bulbs etc that can already be integrated in HomeAssistant withouth the need for events of PR #709. Moreover PR https://github.com/rytilahti/python-miio/pull/782 will open up the possiblibty to integrate all of those kind of devices in HomeAssistant.
@rytilahti personally I would like to have the cloud credentials configurable though the options flow of HomeAssistant. Then users can chose if they want to use the cloud or not to get the device list and tokens. For the lumi.gateway.mieu01 the cloud would be the only way of getting subdevices, but for other gateways you would not have to use the cloud.
I would then preffer to have micloud as a dependency of python-miio if @rytilahti allows it.
The Gateway class would then simply have optional parameters for the credentials, if those are supplied the discover_devices function of the gateway class would then use micloud to get the device list, if that fails it would fall back on the current way of getting the device list (not working for lumi.gateway.mieu01).
If those cloud credentials are not supplied the discover_devices function of the gateway class would then skip micloud and go straight to the fall back which is the current way of gettting the device list.
If no credentials are given with a lumi.gateway.mieu01 an error message could be shown to allert users that the cloud credentials are the only way of getting subdevices with their model of gateway.
Wow @Squachen perfect! You adressed most to do's in https://github.com/rytilahti/python-miio/issues/728#issuecomment-667596758 A welcome addition will be the server selector because not all people use the same country's servers, just like openhab implementation. @starkillerOG country selection should be configurable from HA integration config too, what do you think about it?
@starkillerOG @rytilahti I'm glad you found the code useful. As I said, feel free to use it in any way you want. You could add it as your own micloud class in this project (you may remove my copyright comments) if you don't want to add it as a dependency. I made it a proper module mostly to learn how to do it. If you do want it as a dependency tho I'll maintain it and add what's needed to make it work.
@serhatozkara You can query different servers by supplying the 'country' argument: (I'll add this to the readme)
mc = MiCloud("USERNAME", "PASSWORD")
mc.login()
mc.get_devices(country="cn")
Or do you mean something else?
@starkillerOG see my earlier comment on device database/configuration store. In the bigger picture the cloud information can also be useful for other devices besides these gateways. So to me it would make sense to have a generic support for synchronizing the available devices, tokens, and in some cases, such as for these gateways, the list of available subdevices from the cloud account, and so on.
In that sense, micloud could be used by python-miio for updating the local device database. Others ways for interacting with it would manual configuration, discovery-based or even importing from other miio implementations (openhab, miiojs).
Just an idea how this could work:
- We have the device store (or whatever it will be called), with information like addresses, tokens, device models, and other configuration data. This is useful for both cli and homeassistant users. The data structure could be something like this:
mybulb:
host: 192.168.1.1
token: 123123213
model: some.light.model
variables:
sequence_id: 2
mygateway:
host: 192.168.1.1
token: 12341243
model: lumi.gateway.mieu01
variables:
- subdevices:
- subdevice.id
- subdevice.something_else
- We have different ways to manage this store: discovery process, cloud sync using micloud, miiojs/openhab import, manually editing the file...
- We expose the configuration data (e.g., the list of subdevices) to
Deviceinstances over a common API, what's the best approach here needs some thinking (allow passingConfigurationcontaining the data via constructor? Reading the configuration from the database insideDeviceclass?). - We add API to allow listing known devices, creating
Device-subclassed instances based on the configuration and so on. - We can add API to to allow using
micloudto update the store, which could then be used by homeassistant to refresh the available devices.
@Squachen
I'm glad you found the code useful. As I said, feel free to use it in any way you want. You could add it as your own micloud class in this project (you may remove my copyright comments) if you don't want to add it as a dependency. I made it a proper module mostly to learn how to do it. If you do want it as a dependency tho I'll maintain it and add what's needed to make it work.
I really do applaud your efforts to make it more approachable to get the tokens and I appreciate your proposal for incorporating this inside python-miio, however, I want deliberately to keep this library cloud-free for various reasons. At the same time, I can see the value of having the ability to interact with the cloud, so I'm not strongly against adding an optional support using your library for fetching the token/device information.
Btw, you may want to take a look into typer or click to provide a simple cli interface. I haven't tested your library yet as I'm not actively using the official app, but my understanding is that you can also get tokens for other devices besides the gateway and a cli tool would make it more approachable for many users for the time being :-)
https://typer.tiangolo.com/tutorial/package/#add-a-script shows how to add an entrypoint using poetry (to get ready-to-run script), but similar approach works for setuptools as shown in click's documentation.
I just made some code that schould allow the lumi.gateway.mieu01 to work with python_miio for subdevice support: https://github.com/starkillerOG/python-miio/tree/EU_gateway
I did no properly add micloud to the dependancies yet, so please make sure you have micloud installed. Furthermore that branch is based on the unmerged PR https://github.com/rytilahti/python-miio/pull/782 so I cannot make a PR yet because #782 first needs to be merged.
Could someone test out the code? My system is down so I can't test it myself.
You can use this test_code:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken", cloud_username = "USERNAME", cloud_password = "PASSWORD")
gateway.discover_devices()
devices = gateway.devices
for dev in devices:
dev.update()
print(dev)
You lack a comma at line 171 of gateway/gateway.py, then I got:
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of Xiaomi gateway with ip: 192.168.1.57
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_switch.v2' of Xiaomi gateway with ip: 192.168.1.57
Traceback (most recent call last):
File "testm.py", line 9, in <module>
dev.update()
AttributeError: 'str' object has no attribute 'update'
Not looked into that yet, but I guess the error is pretty much self-descriptive. But it clearly gets my devices etc, so good job! At your service to solve this, if need be.
Thanks!
@tbarbette I fixed the missing comma and edited the zigbee_models of the magnet and motion sensor.
There was a small mistake in the test script I provided (missing the .values()), this schould be the correct one:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken", cloud_username = "USERNAME", cloud_password = "PASSWORD")
gateway.discover_devices()
devices = gateway.devices
for dev in devices.values():
dev.update()
print(dev)
Could you try this again?
@tbarbette regarding your devices, is it correct that: 'lumi.sensor_magnet.v2' == model "MCCGQ01LM" 'lumi.sensor_motion.v2' == model "RTCGQ01LM"
What is the model of the 'lumi.sensor_switch.v2'? I could not figure out which one that schould be.... The ones that I know are in this file: https://github.com/starkillerOG/python-miio/blob/EU_gateway/miio/gateway/devices/switch.py
Edit: I think the 'lumi.sensor_switch.v2' is the "WXKG01LM" which is actually in this file: https://github.com/starkillerOG/python-miio/blob/EU_gateway/miio/gateway/devices/remote_switch.py
The model numbers schould be written on the back of the device itself and also in the (small) manual that comes with the device.
<Subdevice Magnet: lumi.158d0003cfebb3, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.035, props: {}>
<Subdevice Magnet: lumi.158d0003cfebf0, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice AqaraMagnet: lumi.158d00045c80e2, model: MCCGQ11LM, zigbee: lumi.sensor_magnet.aq2, fw: -1, bat: None, vol: 2.985, props: {}>
<Subdevice Magnet: lumi.158d00052b2446, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.025, props: {}>
<Subdevice Magnet: lumi.158d00052d8ddc, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.015, props: {}>
<Subdevice Motion: lumi.158d000397ad53, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Motion: lumi.158d0003d36c9c, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.035, props: {}>
<Subdevice AqaraMotion: lumi.158d000466783a, model: RTCGQ11LM, zigbee: lumi.sensor_motion.aq2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Switch: lumi.158d0003d13c18, model: WXKG01LM, zigbee: lumi.sensor_switch.v2, fw: -1, bat: None, vol: 3.012, props: {}>
Seems good. I'm not sure about the exact model number, but it looks correct.
I just saw the cloud actually gives back the time of the last opening and closing events for magnet and last motion for motion detector. Wouldn't it be imaginable to poll the cloud like every 10 seconds? Events subscription still look like a long way to go.
@tbarbette Nice, thanks for testing!
Looks good to me, so this actually makes lumi.gateway.mieu01 subdevice support possible.
If you can find time I would appriciate it if you could check the model numbers on the device itself, just to be sure if it is now correct.
About the cloud polling, in principle I am not against it, but that would be even a big step further than only using the cloud to get the device list. Doing that would completly mix the micloud and python_miio libraries and realy make python_miio dependend on micloud.... I dont think that is the way @rytilahti wants to go...
Anyway the order in which things need to be done:
- PR https://github.com/rytilahti/python-miio/pull/782 needs to be revieuwed and merged to re-structure the gateway and its devices (otherwise other PRs get loads of merge conflicts...)
- We need to discuss if the approach of branch https://github.com/starkillerOG/python-miio/tree/EU_gateway is acceptable as a quick way to get the lumi.gateway.mieu01 working and later on refactor it according to @rytilahti explanation of a global device list that is not only sutable for the gateways but also for other xiaomi devices (make it more general)
- Based on 2) HomeAssistant needs an options flow to configure the cloud credentials such that lumi.gateway.mieu01 will work with HomeAssistant
- HomeAssistant integration for all the simple devices like light bulbs, plug sockets etc needs to be made (the python_miio side of things is already coverd by step 1))
- Then some cloud polling / event subscription needs to be looked at for the harder devices like motion sensors / door sensors / remote buttons etc.
Ok. I'm not sure I can help for the few next steps but I'll stay around (I'll look for the model numbers). I'm still looking for a way to find if the gateway alarm is ringing if you have any idea...
@rytilahti Thank you for the suggestion. I've implemented a super basic cli interface and released a new version.
Usage: micloud [OPTIONS]
Options:
-u, --username TEXT Your Xiaomi username.
-c, --country TEXT Language code of the server to query. Default: "de"
--pretty Pretty print json output.
--help Show this message and exit.
@Squachen you're welcome, happy to help! Btw, take a look at password and prompt (https://click.palletsprojects.com/en/7.x/options/#password-prompts), that'll allow keeping the shell history clean of credentials & making the commands interactive (if one forgots to specify them).
Released a new version with proper password prompt.
Have you seen this project? https://github.com/AlexxIT/XiaomiGateway3
It has the Mi Cloud login functionality.
I have a lumi.gateway.mieu01 an I was able to get the token with this custom component in Home Assistant.
Hi, All of this seems promessing, and I would love to use and try this.. Any idea of if it is planned to integrate this in Home Assistant (or as a custom component) ? If there is a way to test it before release, I would love to 👍 Thanks for your answer
@jonasCr basically the groundwork is there, but I have little time at the moment to work on it. First PR https://github.com/rytilahti/python-miio/pull/782 needs to be finished, then we can think of lumi.gateway.mieu01 support through the cloud.
Hey there, is there any progress on that so far?
I can help a bit if there's any help needed (can both test and write a bit of Python) as I've bought the lumi.gateway.mieu01 gateway and I cannot get it working with Home Assistant and it's no use for me without Home Assistant support.
Thanks for your hard work!
Happy new year everyone!
I have been watching this since summer, but I have not really had the time to help until now.
I would like to help if possible, I have some spare time next week from University after finishing my exams.
I can write python code and/or test. I have the lumi.gateway.mieu01 too. :)
Thanks for everything so far!
I am planning on picking up this as soon as possible. I will be working on PR #782, so basically that is where any help would be appriciated.
@serge1peshcoff, @airampg I picked up this work again, current progress is in this branch: https://github.com/starkillerOG/python-miio/tree/patch-18 I will update PR #782 once I get the code back to a working state (hopfully this weekend). But for those of you that are interested you can have a peak at patch-18 already
Alright, I finished the PR and I think it is ready for revieuw/merge. Due to merge conflicts PR #782 was closed. The new PR is here: https://github.com/rytilahti/python-miio/pull/924
@serge1peshcoff, @airampg It would be helpfull if you could take a look at the PR and revieuw it to get it merged as soon as possible
Alright, I finished the PR and I think it is ready for revieuw/merge. Due to merge conflicts PR #782 was closed. The new PR is here: #924
@serge1peshcoff, @airampg It would be helpfull if you could take a look at the PR and revieuw it to get it merged as soon as possible
Hey @starkillerOG Thanks a lot for your work on this!! I have downloaded miio and your patch, installed it, re-read a lot of this thread and the changelog on PR #924. I have created an object for my gateway with
from miio import gateway
hub = gateway.Gateway("192.168.0.IP", "12345678901234567890123456789012", lazy_discover=False, start_id=1000)
sid = "lumi.SidSidSidSid"
device_type = 3
subdevice_cls = lumi.sensor_magnet.v2
dev_info = gateway.SubDeviceInfo(sid, device_type, 1, 1, 3)
dev = subdevice_cls(hub, dev_info)
dev.update()
print(dev)
and I am currently getting the following traceback:
subdevice_cls = lumi.sensor_magnet.v2
NameError: name 'lumi' is not defined
I have also tried the following just in case:
print(hub.send("get_device_list"))
(times out)
and
gat.discover_devices()
but returns:
Gateway model 'lumi.gateway.mieu01' does not (yet) support getting the device list
{}
Could you please tell me what I can test and how? I can do the tests tomorrow 😊 Thanks again!
@airampg The current PR does not yet include the EU_gateway support
The following branch I just made does: https://github.com/starkillerOG/python-miio/blob/EU_gateway_2/miio/gateway/gateway.py
I did no properly add micloud to the dependancies yet, so please make sure you have micloud installed.
You can use this test_code:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken", cloud_username = "USERNAME", cloud_password = "PASSWORD")
gateway.discover_devices()
devices = gateway.devices
for dev in devices:
dev.update()
print(dev)
@starkillerOG Thanks! I got it working, this is my output:
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_magnet.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_motion.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_switch.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_switch.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
WARNING:miio.gateway.gateway:Unknown subdevice discovered, could not match zigbee_model 'lumi.sensor_switch.v2' of subdevice sid 'lumi.12312311231231' from Xiaomi gateway with ip: 192.168.0.IP
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
lumi.12312311231231
It looks like my devices are not on the subdevices.yaml, but it can detect them all! If there is some docs on how to add them there, I could try to do so myself :)
The dev.update() returned a traceback AttributeError: 'str' object has no attribute 'update'.
Correct me if I am wrong, but I think that this is because devices = gateway.devices is of type dict, with the shape:
'lumi.12312311231231': <Subdevice unknown: lumi.12312311231231, model: unknown, zigbee: unknown, fw: -1, bat: None, vol: 3.005, props: {}>,
and dev.update() is expecting to be called by an object of class SubDevice.
I am not sure where update is going sideways for me.
Thanks again!
@airampg I just made a commit to branch https://github.com/starkillerOG/python-miio/blob/EU_gateway_2/miio/gateway/devices/subdevices.yaml
Could you update with that latest commit and try again?
And you are right, I made a small mistake in the script I provided to you (missing the .values()), the correct one is:
from miio import Gateway
gateway = Gateway("192.168.1.IP", "tokentokentoken", cloud_username = "USERNAME", cloud_password = "PASSWORD")
gateway.discover_devices()
devices = gateway.devices
for dev in devices.values():
dev.update()
print(dev)
@starkillerOG Amazing job!!
This is the output after running with the new subdevices.yaml and devices.values():
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 2.995, props: {}>
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 2.995, props: {}>
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Magnet: lumi.12312311231231, model: MCCGQ01LM, zigbee: lumi.sensor_magnet.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.035, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.015, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.015, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.015, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.035, props: {}>
<Subdevice Motion: lumi.12312311231231, model: RTCGQ01LM, zigbee: lumi.sensor_motion.v2, fw: -1, bat: None, vol: 3.005, props: {}>
<Subdevice Switch: lumi.12312311231231, model: WXKG01LM, zigbee: lumi.sensor_switch.v2, fw: -1, bat: None, vol: 3.012, props: {}>
<Subdevice Switch: lumi.12312311231231, model: WXKG01LM, zigbee: lumi.sensor_switch.v2, fw: -1, bat: None, vol: 3.012, props: {}>
<Subdevice Switch: lumi.12312311231231, model: WXKG01LM, zigbee: lumi.sensor_switch.v2, fw: -1, bat: None, vol: 3.022, props: {}>
<Subdevice SensorHT: lumi.12312311231231, model: WSDCGQ01LM, zigbee: lumi.sensor_ht.v1, fw: -1, bat: None, vol: 2.965, props: {'temperature': 20.49, 'humidity': 71.06}>
<Subdevice AqaraVibration: lumi.12312311231231, model: DJT11LM, zigbee: lumi.vibration.aq1, fw: -1, bat: None, vol: 2.975, props: {}>
<Subdevice CubeV2: lumi.12312311231231, model: MFKZQ01LM, zigbee: lumi.sensor_cube.aqgl01, fw: -1, bat: None, vol: 2.985, props: {}>
Good news, PR https://github.com/rytilahti/python-miio/pull/924 has been merged. I am now looking into getting the EU_gateway supported. I have opend up this PR for that: https://github.com/rytilahti/python-miio/pull/935, please follow that for more information
With the release of Python-Miio 0.5.5 everything is ready for the EU_gateway support. I just made a PR for HomeAssistant: https://github.com/home-assistant/core/pull/47955
I will be testing it in the coming days.
If someone want to already test it, that would be very helpfull
Hey @starkillerOG
Thanks again for an amazing job!
If someone want to already test it, that would be very helpful
I can definitely help with testing, I will just need some instructions on how to add/enable this pre-release on my HA 😊
you can run it as a custom component to test it. I will do some test tonight and make some improvements and then post some instructions on how to do this here.
Alright, the PR is done. Instructions to test the code are here: https://github.com/home-assistant/core/pull/47955#issuecomment-799798564
Thanks for the link to test it.
I have been able to install it and set it up with my cloud account.
I can see it has pulled my thermometer from the cloud and created an entity for it. (lumi.sensor_ht.v1)

However, it does not show any of the other devices which are trigger enabled, such as buttons (lumi.sensor_switch.v2), motion sensors (lumi.sensor_motion.v2), magnetic (lumi.sensor_magnet.v2), cube (lumi.sensor_cube.aqgl01), vibration (lumi.vibration.aq1).
Could you please let me know whether this is intended behaviour or if I need to do something else?
Thank you again!
@airampg thanks for testing, greath to hear it works! yes that is intended behaviour, you can see the currently suppported subdevices here: https://www.home-assistant.io/integrations/xiaomi_miio/#supported-subdevices and the recognized but not yet supported subdevices here: https://www.home-assistant.io/integrations/xiaomi_miio/#recognized-subdevices-not-yet-implemented
Note that the dev release already has PRs merged that will add support for a lot more subdevices (switches and lights) you can see that here: https://github.com/home-assistant/home-assistant.io/blob/next/source/_integrations/xiaomi_miio.markdown#supported-subdevices
The trigger enabled devices can not yet be implemented because they don't have state attributes, they only provide trigger events and there is no way to listen for those events in python-miio yet. Support to make it possible to listen for those kinds of events is worked on in this PR: https://github.com/rytilahti/python-miio/pull/709
However that PR has been stale for quite some time. Maybe I will pick that up some time and see if I can get that working (it would have some greath advantages), however I don't know when I will have time for that
@starkillerOG Having the Xiaomi Miio integration installed I placed the xiaomi_miio folder that is in homeassistant/components/ PR inside custom_components. I was able to insert my cloud credentials, but when I list my devices it looks like they are coming from the released Xiaomi Miio integration and not from the custom one, I assume it's wrong looking at @airampg print which shows the devices coming from xiaomi_miio and not from Xiaomi Miio

Can you help?
@carloslindo you can try removing the gateway integration and setting it up again. Besides do you have any subdevice listed here: https://github.com/home-assistant/home-assistant.io/blob/next/source/_integrations/xiaomi_miio.markdown#supported-subdevices ?
Otherwise it will not show any aditional subdevices (because they are not yet implemented)
@carloslindo and of course you need to select the correct "cloud server country" in the options (depends on how you setup your xiaomi miio account), you can find that in the Miio Home app under Profile --> Settings (Language & region) --> Region. Mine is "Chinese mainland" and therefore I need to select "cn" you can find more on the country servers here: https://www.openhab.org/addons/bindings/miio/#country-servers
@starkillerOG I am using the same country code de as the token_extractor shows. I think the problem is my subdevices are lumi.sensor_motion.v2 and that falls into the list of not supported subdevices... Is there anything else that I can do to help testing?
@carloslindo No not really, I think the code just works so it can be merged. The only thing you can check is if you don't see any errors in the log.
I got this in the log :
2021-03-16 16:14:05 ERROR (SyncWorker_7) [miio.gateway.gateway] Could not find gateway with ip '192.168.1.57', mac '50:EC:50:EE:42:76', model 'lumi.gateway.mieu01' in the cloud device list response
2021-03-16 16:14:11 ERROR (SyncWorker_4) [miio.miioprotocol] Got error when receiving: timed out
2021-03-16 16:14:11 ERROR (MainThread) [custom_components.xiaomi_miio.gateway] DeviceException during setup of xiaomi gateway with host 192.168.1.57
But when I run micloud manually I do get that device which is my gateway. Also I think the "first setup" popup should start by proposing the cloud credentials, and then auto-discover the gateway and the token. So we could do everything directly in home assistant, without needing to go through the token extractor.
@tbarbette
If it cannot find it, the only things I can think of is that the chosen server is not the same as your gateway or the "use cloud to get connected subdevices" may be unticked.
Perhaps your gateway's IP address has changed? is that the one on the Mi Home app?
I definitely did not get that issue, so I am not sure of there this is going wrong for you.
This is what my cloud options look like on HA:

Ticked, and I have DE too (my locale is BE). I actually re-installed the gateway from the informations given by micloud (ip and token) as that gives you the token very easily so it's the same. One thing maybe, in the micloud json, the gateway is the second device as the first one is a Xiaomi camera.
@tbarbette could you try running this python code (preferably inside the virtual enviroment of HomeAssistant)?
from micloud import MiCloud
mc = MiCloud("USERNAME", "PASSWORD")
mc.login()
token = mc.get_token() # to get your cloud service token.
device_list = mc.get_devices(country="de") # get list of devices
print(device_list )
And then see if the gateway is listed in the dict
@tbarbette the order in which the devices are listed is not importend, a for loop over the devices is made to see if the gateway can be found: https://github.com/rytilahti/python-miio/blob/5ea3157db58045260edceebb52a0f1e45f709d79/miio/gateway/gateway.py#L207-L221
@tbarbette Note that this needs to be an exact match of the mac (case and format sensitive). So maybe the format of the mac is diffrent??? I would need the output of the python script above to compare with the error message to see what is going wrong...
Hi, I'm trying to install it to test but no success as far. This is the steps I made:
- Uninstall the official miio integration
- Put your miio folder in my custom_components folder
- restart HA
- I'm able to add my cloud account but then nothing more happend.. :( Is there something I'm missing ?? I tried to restart HA after this but no success
I'm in spain so i put the de server
Thanks for your help
Also I think the "first setup" popup should start by proposing the cloud credentials, and then auto-discover the gateway and the token. So we could do everything directly in home assistant, without needing to go through the token extractor.
I agree, but that is something for a future PR, that is a bit more complicated than you might think:
- it may not work for users that have internet acces (cloud) blocked, so the old method schould still be supported.
- Other devices like vacuums etc will also be discoverd in that way and they schould also be setup. However then all those things will end up in one config entry, currently it is not possible to setup multiple devices from one config_entry (all mac's and models schould be stored to be able to still setup the integration if for instance internet is down and cloud is not available at the moment HomeAssistant starts).
@jonasCr do you see any errors in the log? Do you have one or more of the devices listed here: https://github.com/home-assistant/home-assistant.io/blob/next/source/_integrations/xiaomi_miio.markdown#supported-subdevices ? (Otherwise nothing will show up because other subdevices are not yet supported)
Ook, that's it. Mine are in the Recognized section but not in the supported :( ... Well, I'm not going to be able to try it... But well done !! That's a big step! Thanks for your job. Let me know if more device are added
@jonasCr As I see that there is quite some intrest in subdevice support for the Xiaomi Miio Gateway integration, I might see if I can pick up PR https://github.com/rytilahti/python-miio/pull/709 to get event driven (sub)devices supported.
Yeah, I think it's because here there are selling a kit with the kit and 5 sensors (2 doors, 2 motion and 1 button) and all of them are recognized but not supported, for now. Hopefully the support is coming soon. Until that it's useless for me 😉
@tbarbette could you try running this python code (preferably inside the virtual enviroment of HomeAssistant)?
from micloud import MiCloud mc = MiCloud("USERNAME", "PASSWORD") mc.login() token = mc.get_token() # to get your cloud service token. device_list = mc.get_devices(country="de") # get list of devices print(device_list )And then see if the gateway is listed in the dict
I get the same list than with the micloud client. Today I tried to hit "reload" and I don't get that message anymore... I only have sensors so I can't verify something else was added up. I think I did not select the right server at the first try, maybe the change of server was not saved? Anyway I guess it works :) Thanks! And yes, please support events :p