Open bskaplou opened 4 years ago
Sounds good! Let's give it a try! A capture of incoming events/messages would be helpful, too.
If I'm understanding it correctly, the idea would be basically to create a listener that acts like a miio device to the gateway? I don't think anyone has explored that possibility so far, but it is probably also a lot of work to pull this off. If you want to give it a go, feel free to do so :-)
I have the cube myself, too, but instead of using the gateway, I'm using zigbee2mqtt which makes it all very simple.
Everyone is aware that there is already an official HomeAssistant integration specifically for the xiaomi aqara gateway that uses the UDP protocol using pushes (instant updates of sub devices including the cube) https://www.home-assistant.io/integrations/xiaomi_aqara/ That integration uses the UDP protocol specific to the gateway. However that protocol does not support all possibilities of the gateway as far as I am aware of. For instance the Alarm feature of the gateway is not supported by the UDP protocol and is supported by the miio protocol. That was the initial reason I started to work on the Miio implementation of the gateway
If I understand correctly that this is a different protecol/way to subscribe to events that would be awesome and worth exploring. I am wondering if this would allow to subscribe to more events/propertie changes than when using the UDP developer API (https://github.com/Danielhiversen/PyXiaomiGateway)
@starkillerOG
Currently I use xiaomi_aqara and it works, but:
With xiaomi_miio for some gateway features and xiaomi_aqara for other we'll get two gateways in system, this will work but looks awkward and definitely not commodity solution ...
Then I found fresh gateway support in xiaomi_miio component of hass I decided that xiomi_miio gateway should replace xiaomi_aqara and I'm trying to help with this move :)
@rytilahti Ok good. I'll try to implement this approach
Sounds good, very excited to test this new subscription method if you have some initial code working!
@starkillerOG @rytilahti It works :) you can look at code here https://github.com/bskaplou/python-miio/tree/fake_device
fake_device.py is implementation of miio server which:
How to run:
miiocli gateway --ip 192.168.2.109 --token XXX install_cube_rotate_script your_cube_lumi_sid
miiocli gateway --ip 192.168.2.109 --token XXX install_cube_move_script your_cube_lumi_sid
miiocli gateway --ip 192.168.2.109 --token XXX x_del x.scene.2732711973
miiocli gateway --ip 192.168.2.109 --token XXX x_del x.scene.2732711975
Output of fake_device.py looks as follows:
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
192.168.2.109:54321=>{'method': 'move', 'params': [], 'from': 'nbl.134550490', 'id': 619969141}
192.168.2.109:54321<={'result': 0, 'id': 619969141}
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
192.168.2.109:54321=>{'method': 'rotate', 'params': [-39, 500], 'from': 'nbl.134550490', 'id': 620237685}
192.168.2.109:54321<={'result': 0, 'id': 620237685}
192.168.2.109:54321=>{'method': 'rotate', 'params': [32, 380], 'from': 'nbl.134550490', 'id': 620238918}
192.168.2.109:54321<={'result': 0, 'id': 620238918}
192.168.2.109:54321=>{'method': 'move', 'params': [], 'from': 'nbl.134550490', 'id': 620240647}
192.168.2.109:54321<={'result': 0, 'id': 620240647}
192.168.2.109:54321=>PING
192.168.2.109:54321<=ACK(device_id=120009025)
Here we can see:
But there are problems .... script:
{"id":4994,"method":"send_data_frame","params":{"cur":0,"data":"[[\"x.scene.2732711973\",[\"1.0\",1590158978,[\"0\",{\"src\":\"device\",\"key\":\"event.lumi.sensor_cube.v1.move\",\"did\":\"lumi.158d000103ec74\",\"model\":\"lumi.sensor_cube.v1\",\"token\":\"\",\"extra\":\"[1,18,2,85,[6,256],0,0]\",\"timespan\":[\"0 0 * * 0,1,2,3,4,5,6\",\"0 0 * * 0,1,2,3,4,5,6\"]}],[{\"id\":0,\"did\":\"120009025\",\"token\":\"79cf21b08fb051499389f23c113477a4\",\"ip\":\"192.168.2.94\",\"command\":\"chuangmi.plug.v3.set_usb_on\",\"value\":\"\",\"model\":\"chuangmi.plug.v3\",\"extra\":\"\"}]]]]","data_tkn":45293,"total":1,"type":"scene"}}
this script contains token 79cf21b08fb051499389f23c113477a4, but this token differs from real device token which is 9bc7c7ce6291d3e443fd7708608b9892.
I use token 9bc7c7ce6291d3e443fd7708608b9892 in fake_server for decryption and 79cf21b08fb051499389f23c113477a4 in script ... Method of creation of script token from device token is required ... Maybe data_tkn somehow used to create script token ...
Any ideas are more then welcome :)
That's pretty cool! :100: I'm wondering if the system supports wildcards for events? I'm thinking about something like "subscribe all events on all devices" which could allow generic event support?
Unfortunately I don't have ideas on that token issue, nor really any time to help with these efforts.. You may want to have a take a look at dustcloud (or at least the dummycloud impl https://github.com/dgiese/dustcloud/tree/master/dummycloud) if there's something relevant.
@rytilahti Right now callback receives source_device/action/params But I use methodname to pass source device to callback (the only way I found to identify source of event). So it will willingly process any callback but name should be encoded as f"{action}{device_sid}"
INFO:__main__:fake miio device started with address=0.0.0.0 device_id=120009025 callback=<function callback at 0x10dbf9378> token=****
DEBUG:__main__:192.168.2.109:54321=>PING
DEBUG:__main__:192.168.2.109:54321<=ACK(device_id=120009025)
DEBUG:__main__:192.168.2.109:54321=>{'method': 'move_158d000103ec74', 'params': [], 'from': 'nbl.134550490', 'id': 655700828}
DEBUG:__main__:CALLBACK lumi.158d000103ec74=>move([])
DEBUG:__main__:192.168.2.109:54321<={'result': 0, 'id': 655700828}
DEBUG:__main__:192.168.2.109:54321=>PING
DEBUG:__main__:192.168.2.109:54321<=ACK(device_id=120009025)
DEBUG:__main__:192.168.2.109:54321=>{'method': 'rotate_158d000103ec74', 'params': [23, 500], 'from': 'nbl.134550490', 'id': 655702095}
DEBUG:__main__:CALLBACK lumi.158d000103ec74=>rotate([23, 500])
DEBUG:__main__:192.168.2.109:54321<={'result': 0, 'id': 655702095}
DEBUG:__main__:192.168.2.109:54321=>{'method': 'rotate_158d000103ec74', 'params': [13, 460], 'from': 'nbl.134550490', 'id': 655702575}
DEBUG:__main__:CALLBACK lumi.158d000103ec74=>rotate([13, 460])
DEBUG:__main__:192.168.2.109:54321<={'result': 0, 'id': 655702575}
DEBUG:__main__:192.168.2.109:54321=>{'method': 'move_158d000103ec74', 'params': [], 'from': 'nbl.134550490', 'id': 655700828}
DEBUG:__main__:CALLBACK lumi.158d000103ec74=>move([])
DEBUG:__main__:192.168.2.109:54321<={'result': 0, 'id': 655700828}
DEBUG:__main__:192.168.2.109:54321=>{'method': 'move_158d000103ec74', 'params': [], 'from': 'nbl.134550490', 'id': 655703870}
DEBUG:__main__:CALLBACK lumi.158d000103ec74=>move([])
DEBUG:__main__:192.168.2.109:54321<={'result': 0, 'id': 655703870}
DEBUG:__main__:192.168.2.109:54321=>PING
DEBUG:__main__:192.168.2.109:54321<=ACK(device_id=120009025)
It seems PR is almost here please drop a look https://github.com/bskaplou/python-miio/tree/fake_device
https://github.com/rytilahti/python-miio/compare/master...bskaplou:fake_device?expand=1
Meanwhile I'll capture remaining actions of cube and square button and add their support into scripts .
Afterwards I'll beg for release :)
Please feel free to create a PR already (you can mark it as WIP/draft if you want), it is much easier to comment on it.
How do you plan this feature should be exposed? How would you propose to integrate this with the gateway support?
I'm wondering if the system supports wildcards for events
Ammm ... I understood your question... No...
Right now it works as follows:
script_install_count = actions * devices
Unfortunately right now I have no idea how to implement wildcards... Problem:
@rytilahti How to make it work in hass:
is your gw still connected to xiaomi cloud? gw can refresh ip/token of wifi devices it runs automation on via cloud api (_sync.neighborDevInfo). i checked on my (newer) hub and it gets current token with send_data_frame. extra field is lumi encoded automation trigger. it's used (NOT human readable key field) for lan automations. they use this method for most hubs, only last one lumi.gateway.mgl03 dropped it.
@rezmus Yes gateway is connected to the cloud. BTW did you sniffed cloud traffic?
yeah it kinda use the same encryption as local miio but with cloud did/key credentials which you can get via shell (linux mi global hub or aqara).
https://github.com/dgiese/dustcloud/wiki/Lumi-Aqara-Gateway-Root https://github.com/roth-m/miioclient-mqtt
@rezmus, still trying to figure out a way to get the token that needs to be sent with "send_data_frame" which is diffrent from the token used for the rest of the communication.
It sounds like you know a lot about those tokens, could you help me with devoloping a method to obtain that token?
I did figure out that the "data_tkn" does not have to match, for me both "29576" or "52507" work just as fine. So I guess that if we always set "data_tkn" to "29576" as was done in the original PR of @bskaplou it will be fine.
Just need to figure out how to get that "send_data_frame" token, the rest I know how to implement and get it in HomeAssistant.
@xcray I see you have quite some experiance with the Xiaomi Miio protecol since you wrote a CSharp implementation. Do you have any ideas on how to obtain the token needed for "send_data_frame"?
@xcray I see you have quite some experiance with the Xiaomi Miio protecol since you wrote a CSharp implementation. Do you have any ideas on how to obtain the token needed for "send_data_frame"?
My C# implementation was based on this: https://github.com/OpenMiHome/mihome-binary-protocol/blob/master/doc/PROTOCOL.md, and from only a few devices it could obtain token directly.
@starkillerOG if there is some hashing algo for tokens you need to reverse engineer it from hubs firmware.
Alright, thanks for your info. If you happen to come accross new commands for the gateway, please let me know.
On a side node, do you happen to know how to get any of the following properties:
i haven't used lumi.gateway.v3 for a long time so i'm not sure what it does return as device list. mgl03 returns such list
> {"method":"get_device_list","params":[],"id":1}
< {"code":0,"result":[{"did":"lumi.a","model":"lumi.sensor_motion.aq2","num":1,"total":3},{"did":"lumi.b","model":"lumi.plug.mmeu01","num":2,"total":3},{"did":"lumi.c","model":"lumi.remote.b686opcn01","num":3,"total":3}],"id":1}
so you have sid/model.
lumi.curtain.aq3 - Aqara Blind Controller lumi.eemeter.rs485ecn01 - RS485 Connector(Electric meter) lumi.eemeter.zbtecn01 - Zigbee Connector lumi.curtain.aq1 - Aqara Curtain Controller 3.0 lumi.airrtc.tcpco2ecn01 - Aqara Thermostat(CO2) lumi.plug.maeu01 - Aqara Smart Plug lumi.plug.saus01 - Aqara Wall Outlet lumi.dimmer.rgbegl01 - Dimmer(Multicolor) lumi.dimmer.c3egl01 - Dimmer(3 Channels) lumi.dimmer.cwegl01 - Dimmer(Tunable White) lumi.switch.b1laus01 - Aqara Wall Switch(No Neutral, Single Rocker) lumi.switch.b2laus01 - Aqara Wall Switch (No Neutral, Double Rocker) lumi.light.aqcn01 - Aqara LED Light Bulb(Dimmable) lumi.plug.maus01 - Aqara Smart Plug lumi.plug.mitw01 - Mi Smart Plug lumi.remote.b1acn02 - Aqara Wireless Mini Switch T1 lumi.flood.agl02 - Aqara Water Leak Sensor T1 lumi.magnet.agl02 - Aqara Door and Window Sensor T1 lumi.motion.agl02 - Aqara Motion Sensor T1 lumi.plug.maus02 - Aqara Smart Plug S2 lumi.switch.b1lacn01 - Aqara Wall Switch T1 (No Neutral, Single Rocker) lumi.switch.b2lacn01 - Aqara Wall Switch T1 (No Neutral, Double Rocker) lumi.switch.b1nacn01 - Aqara Wall Switch T1 (With Neutral, Single Rocker) lumi.switch.b2nacn01 - Aqara Wall Switch T1 (With Neutral, Double Rocker) lumi.plug.sacn02 - Aqara Smart Wall Outlet T1 lumi.gateway.mgl04 - Mi Smart Home Hub lumi.switch.b1naus01 - Aqara Smart Wall Switch (With Neutral, Single Rocker) lumi.gateway.irabr01 - Aqara Hub M2 lumi.curtain.vagl02 - Aqara Roller Shade Controller T1 lumi.curtain.hagl07 - Aqara Curtain Controller C2 lumi.switch.b2naus01 - Aqara Smart Wall Switch (With Neutral, Double Rocker) lumi.gateway.iragl01 - Aqara Hub S2 lumi.gateway.mihk01 - Mi Control Hub lumi.gateway.mieu01 - Mi Control Hub lumi.gateway.lmuk01 - Mi Control Hub lumi.gateway.mitw01 - Mi Control Hub lumi.gateway.aqhm02 - Aqara Hub lumi.sen_ill.agl01 - Aqara Light Detection Sensor T1 lumi.curtain.hagl05 - Xiaomiyoupin Curtain Controller (Wi-Fi) lumi.sensor_ht.agl02 - Aqara Temperature and Humidity Sensor T1 lumi.sen_ill.mgl01 - Mi Light Detection Sensor lumi.switch.b3l01 - Aqara Wall Switch T1 (No Neutral, Three Rocker) lumi.switch.b3n01 - Aqara Wall Switch T1 (With Neutral, Three Rocker) lumi.lock.bmcn02 - Mi Smart Door Lock lumi.sensor_smoke.acn01 - Aqara Smart Smoke Detector(NB-IoT) lumi.airmonitor.acn01 - Aqara TVOC Sensor lumi.plug.macn01 - Aqara Smart Plug T1 lumi.remote.cagl01 - Aqara Cube T1 lumi.plug.mmeu01 - Mi Smart Plug (Zigbee) lumi.gateway.aqhm03 - Aqara Hub lumi.gateway.mgl03 - Mi Smart Home Hub lumi.remote.b186acn01 - Aqara Wireless Remote Switch (Single Rocker) lumi.remote.b286acn01 - Aqara Wireless Remote Switch (Double Rocker) lumi.lock.acn03 - Aqara Door lock S2 Pro lumi.gateway.v1 - Mi Control Hub lumi.sensor_switch.v1 - Wireless switch lumi.sensor_magnet.v1 - Door & window sensor lumi.sensor_motion.v1 - Body sensor lumi.sensor_switch.v2 - Mi Wireless Switch lumi.ctrl_neutral2.v1 - Aqara Wall Switch (No Neutral, Double Rocker) lumi.ctrl_neutral1.v1 - Aqara Wall Switch(No Neutral, Single Rocker) lumi.sensor_ht.v1 - Mi Temperature and Humidity Sensor lumi.plug.v1 - Mi Smart Plug lumi.sensor_86sw1.v1 - Aqara Wireless Remote Switch (Single Rocker) lumi.sensor_86sw2.v1 - Aqara Wireless Remote Switch (Double Rocker) lumi.curtain.v1 - Aqara Curtain Controller lumi.sensor_smoke.v1 - Mi Smart Smoke Detector lumi.sensor_natgas.v1 - Mi Smart Natural Gas Detector lumi.weather.v1 - Aqara Temperature and Humidity Sensor lumi.ctrl_86plug.v1 - Aqara Wall Outlet lumi.ctrl_ln2.v1 - Aqara Wall Switch (With Neutral, Double Rocker) lumi.sensor_wleak.aq1 - Water Leak Sensor lumi.ctrl_ln1.v1 - Aqara Wall Switch (With Neutral, Single Rocker) lumi.vibration.aq1 - Aqara Vibration Sensor lumi.curtain.aq2 - Aqara Roller Shade Controller lumi.lock.v1 - Door lock lumi.sensor_switch.aq2 - Aqara Wireless Mini Switch lumi.lock.aq1 - Aqara Door Lock lumi.sensor_switch.aq3 - Aqara Wireless Mini Switch(Advanced) lumi.ctrl_ln2.aq1 - Aqara Wall Switch (With Neutral, Double Rocker) lumi.ctrl_86plug.aq1 - Aqara Wall Outlet lumi.light.aqcn02 - Aqara LED Light Bulb (Tunable White) lumi.relay.c2acn01 - Aqara Wireless Relay Controller(2 Channels) lumi.airrtc.vrfegl01 - VRF Air Conditioning Controller lumi.airrtc.tcpecn01 - Thermostat lumi.lock.acn02 - Aqara Door Lock S2 lumi.remote.b1acn01 - Aqara Wireless Mini Switch lumi.curtain.hagl04 - Aqara Curtain Controller B1 lumi.ctrl_ln1.aq1 - Aqara Wall Switch (With Neutral, Single Rocker) lumi.acpartner.mcn02 - Mi Smart Air Conditioner Controller 2 lumi.lock.mcn01 - Mi Smart Door Lock lumi.sensor_cube.aqgl01 - Aqara Cube lumi.sensor_cube.v1 - Mi Cube lumi.switch.b2lacn02 - Aqara Wall Switch D1 (No Neutral, Double Rocker) lumi.remote.b286acn02 - Aqara Wireless Remote Switch D1 (Double Rocker) lumi.remote.b186acn02 - Aqara Wireless Remote Switch D1 (Single Rocker) lumi.gateway.v2 - Mi Control Hub lumi.gateway.v3 - Mi Control Hub lumi.gateway.aqhm01 - Aqara Hub lumi.camera.aq1 - Camera Hub lumi.acpartner.v1 - Air Conditioning Controller lumi.acpartner.v2 - Mi Smart Air Conditioner Controller lumi.acpartner.v3 - Air Conditioning Controller(Advanced) lumi.camera.gwagl01 - Camera Hub G2 lumi.airer.acn01 - Aqara Smart Clothes Drying Rack lumi.sensor_motion.aq2 - Aqara Motion Sensor lumi.sensor_motion.v2 - Mi Motion Sensor lumi.airrtc.tcpecn02 - Thermostat S2 lumi.sensor_magnet.aq2 - Aqara Door and Window Sensor lumi.sensor_magnet.v2 - Mi Window and Door Sensor lumi.switch.b1nacn02 - Aqara Wall Switch D1 (With Neutral, Single Rocker) lumi.switch.b1lacn02 - Aqara Wall Switch D1 (No Neutral, Single Rocker) lumi.switch.b2nacn02 - Aqara Wall Switch D1 (With Neutral, Double Rocker) lumi.light.cbacn1 - Aqara Smart Constant Current Driver T1-1 lumi.lock.bzacn2 - Aqara smart door lock N100 lumi.lock.bzacn1 - Aqara smart door lock N200 lumi.switch.l3acn3 - Aqara Smart Wall Switch D1 (No Neutral, Triple Rocker) lumi.switch.n3acn3 - Aqara Smart Wall Switch D1(With Neutral, Triple Rocker) lumi.switch.n0acn2 - Aqara Single Switch Module T1 (With Neutral) lumi.switch.l0acn1 - Aqara Single Switch Module T1 (No Neutral) lumi.switch.l1acn1 - Aqara Smart Wall Switch H1 (No Neutral, Single Rocker) lumi.switch.l2acn1 - Aqara Smart Wall Switch H1 (No Neutral, Double Rocker) lumi.switch.l3acn1 - Aqara Smart Wall Switch H1 (No Neutral, Triple Rocker) lumi.switch.n1acn1 - Aqara Smart Wall Switch H1 (With Neutral, Single Rocker) lumi.switch.n2acn1 - Smart Wall Switch H1 (With Neutral, Double Rocker) lumi.switch.n3acn1 - Smart Wall Switch H1 (With Neutral, Triple Rocker) lumi.light.rgbac1 - Aqara Smart Dimmer Controllor T1 lumi.airrtc.pcacn2 - Aqara Thermostat S2 Pro lumi.remote.b486opcn01 - Wireless Scene Switch (Four Button Edition) lumi.light.cwopcn01 - Ceiling Light MX960 (Adjustable Color Temperature) lumi.light.cwopcn03 - Ceiling Light MX480 (Adjustable Color Temperature) lumi.light.cwopcn02 - Ceiling Light MX650 (Adjustable Color Temperature) lumi.remote.b686opcn01 - Wireless Scene Switch (Six Button Edition) lumi.remote.b286opcn01 - Wireless Scene Switch (Two Button Edition) lumi.curtain.hmcn01 - Mi Smart Motorized Curtain lumi.lock.bmcn03 - Mi Smart Door Lock E lumi.remote.b186acn03 - Aqara Wireless Remote Switch T1 (Single Rocker) lumi.remote.b286acn03 - Aqara Wireless Remote Switch T1 (Double Rocker) lumi.camera.gwakr1 - Camera G2 lumi.flood.bmcn01 - Mi Flood Detector lumi.motion.agl04 - Aqara High Precision Motion Sensor lumi.gateway.acn01 - Aqara Hub M1S lumi.plug.sacn03 - Aqara Smart Wall Outlet H1 (USB) lumi.vibration.agl01 - Aqara Vibration Sensor T1 lumi.sensor_smoke.mcn02 - Mi Smoke Detector lumi.airer.acn02 - Aqara Smart Clothes Drying Rack Lite lumi.sensor_gas.mcn02 - Mi Natural Gas Detector lumi.curtain.hagl08 - Aqara Curtain Controller A1 lumi.aircondition.acn05 - Aqara Air Conditioning Controller P3 lumi.gateway.aeu01 - Aqara Hub M1S (EU) lumi.camera.gwag03 - Camera Hub G2H
custom name you give is part of xiaomi cloud api not related to device.
just tryed the get_device_list
command but does not work on lumi.gateway.v3 I get miio.exceptions.DeviceError: {'code': -32601, 'message': 'Method not found.'}
I can get devices using
self.send("get_device_prop", ["lumi.0", "device_list"])
and that gives:
["lumi.a",1,2,3,4]
where 1 is a number representing the model
2 and 3 are unknown variables
and 4 is the firmware version
id - model map
0 - lumi.gateway 1 - lumi.sensor_switch 2 - lumi.sensor_motion 3 - lumi.sensor_magnet 7 - lumi.ctrl_neutral2 8 - lumi.sensor_cube 9 - lumi.ctrl_neutral1 10 - lumi.sensor_ht 11 - lumi.plug 12 - lumi.sensor_86sw2 13 - lumi.curtain 14 - lumi.sensor_86sw1 15 - lumi.sensor_smoke 17 - lumi.ctrl_86plug 18 - lumi.sensor_natgas 19 - lumi.weather 20 - lumi.ctrl_ln1 21 - lumi.ctrl_ln2 51 - lumi.sensor_switch.aq2 52 - lumi.sensor_motion.aq2 53 - lumi.sensor_magnet.aq2 54 - lumi.relay.c2acn01 55 - lumi.sensor_wleak.aq1 56 - lumi.vibration.aq1 59 - lumi.lock.aq1 62 - lumi.sensor_switch.aq3 63 - lumi.ctrl_ln1.aq1 64 - lumi.ctrl_ln2.aq1 65 - lumi.ctrl_86plug.aq1 66 - lumi.light.aqcn02 68 - lumi.sensor_cube.aqgl01 70 - lumi.lock.acn02 71 - lumi.curtain.aq2 72 - lumi.curtain.hagl04 81 - lumi.lock.v1 82 - ikea.light.led1545g12 83 - ikea.light.led1546g12 84 - ikea.light.led1536g5 85 - ikea.light.led1537r6 86 - ikea.light.led1623g12 87 - ikea.light.led1650r5 88 - ikea.light.led1649c5 133 - lumi.remote.b1acn01 134 - lumi.remote.b186acn01 135 - lumi.remote.b286acn01 163 - lumi.lock.acn03 166 - lumi.lock.acn05 167 - lumi.switch.b1lacn02 168 - lumi.switch.b2lacn02 169 - lumi.switch.b1nacn02 170 - lumi.switch.b2nacn02 171 - lumi.remote.b186acn02 172 - lumi.remote.b286acn02 176 - lumi.switch.n3acn3 177 - lumi.switch.l3acn3 202 - lumi.dimmer.rgbegl01 203 - lumi.dimmer.c3egl01 204 - lumi.dimmer.cwegl01 205 - lumi.airrtc.vrfegl01 206 - lumi.airrtc.tcpecn01 207 - lumi.airrtc.tcpecn02
@rezmus you are amazing, that is incredibly helpfull!!! I will emidiatly start adding all those device ids
How did you get that model map, where is that documented?
firmware dump.
@rezmus is that firmware dump available somewhere (on github) in readable text format?
here is some older version
https://github.com/dgiese/dustcloud-documentation/tree/master/lumi.gateway.v3
it's firmware so if you plan to do some reverse engineering you have to use ida/ghidra or similar.
@starkillerOG if there is some hashing algo for tokens you need to reverse engineer it from hubs firmware.
@rezmus I tried looking at the firmware dump you provided, but that goes a little above my head.... Would you be willing to look if you can figure out where the "send_data_frame" token comes from? And maybe see if there is some way to get that token using some hashing algoritm or get it in some other way from the gateway or from the cloud?
sorry, i took a look some time ago but without success. however i'm not really good at decompiled code analysis.
Alright, do you happen to know someone who might be able to help with this?
Maybe @dgiese has an idea about the gateway <-> subdevice intercomms? He has some deep knowledge on how xiaomi devices tick ;-)
Any chance to add lumi.curtain.hagl08? Seems like it's the same as lumi.curtain.hagl05
I finished a PR for including this callback mechanism into python miio. The only problem left is obtaining the encrypted_token from the normal token. See https://github.com/rytilahti/python-miio/issues/699#issuecomment-633005818
If someone has any idea how to obtain the encrypted_token (besides packet capture/sniffing), help is more than welcome!
I just found a way to get the "encrypted token":
from miio.protocol import Utils
token = "TokenTokenToken"
def calculated_token_enc(token):
token_bytes = bytes.fromhex(token)
encrypted_token = Utils.encrypt(token_bytes, token_bytes)
encrypted_token_hex = encrypted_token.hex()
return encrypted_token_hex[0:32]
print(calculated_token_enc(token))
It works for the tokens of both my 2 gateways.
I'm trying to make xiaomi cube and xiaomi square button work. Pub/Sub mechanism is necessary to make these devices work properly While investigating the way to implement it I've found no subscription mechanism in python-miio ;(
I've also looked at nodejs miio implementation and found it uses developer-api https://github.com/aholstenson/miio/blob/master/lib/devices/gateway/developer-api.js instead of miio protocol for event subscription. Which is akward and doesn't help to avoid soldering of gateway...
I've sniffed traffic between Mi Home app and gateway and found what when I create Mi Home automation involving cube as source and other wi-fi device in local network as destination Mi Home app sends to gateway a script as follows:
-> 192.168.2.17 data= {"id":2666,"method":"send_data_frame","params":{"cur":0,"data":"[[\"x.scene.2732711973\",[\"1.0\",1589956238,[\"0\",{\"src\":\"device\",\"key\":\"event.lumi.sensor_cube.v1.move\",\"did\":\"lumi.158d000103ec74\",\"model\":\"lumi.sensor_cube.v1\",\"token\":\"\",\"extra\":\"[1,18,2,85,[6,256],0,0]\",\"timespan\":[\"0 0 * * 0,1,2,3,4,5,6\",\"0 0 * * 0,1,2,3,4,5,6\"]}],[{\"id\":0,\"did\":\"120009025\",\"token\":\"XXXX\",\"ip\":\"192.168.2.94\",\"command\":\"chuangmi.plug.v3.set_usb_on\",\"value\":\"\",\"model\":\"chuangmi.plug.v3\",\"extra\":\"\"}]]]]","data_tkn":46567,"total":1,"type":"scene"}}
This message even includes token of destination device :) It makes possible extraction of any token if you know gateway token...
Anyway, my idea here is implement subscription as follows: 1) Send send_data_frame to gateway with destination ip address of python-miio host 2) Bind 54321/udp on python-miio host and listen for incoming messages from gateway 3) Decrypt/unpack message for further processing
I'm new at miio hacking.... Can you tell me if you already tried this way of subscription or have some other way to implement pub/sub?