rytilahti / python-miio

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

miio local api soon deprecated? / add support for miot api #543

Closed rezmus closed 4 years ago

rezmus commented 5 years ago

just to let you know. this is part of mail sent to xiaomi iot platform devs today (translated):

The Xiaomi IoT platform is fully implementing the MioT-Spec access work. The Xiaomi IoT Device Protocol Specification (MIoT Specification) will replace the original miio profile protocol specification.

i've checked some plugins of new devices and many of them use miot api (cloud only) rather than miio. for example air purifier 3. i can't say for sure because i don't have device, but from what i saw it's stripped from local miio api.

syssi commented 5 years ago

Wow. Terrible news.

vampywiz17 commented 5 years ago

it possible to use miot api on external software, like domoticz or Home Assistant? i know it is cloud based, but possible to make api call across the cloud?

Like this not help? Or it only work with Yeelight lamp?

https://github.com/Yeelight/miot-api

https://github.com/Yeelight/miot-api/tree/master/manual

Leatherface75 commented 5 years ago

If that's true then i have bought my last Xiaomi product.

roth-m commented 5 years ago

It's true. I have an Air Purifier 3. It returns {"id":216,"error":{"code":-5001,"message":"command error"}} for any command excepted {"id":214,"method":"miIO.info","params":[]}.

If someone knows how to get a console (or something like this) on this "thing", it would be great! (ESP32 inside!)

rezmus commented 5 years ago

can you check "method":"get_properties","params":["prop.3.6"] or "method":"get_properties","params":[{"siid":3,"piid":6}]

roth-m commented 5 years ago

Sent: {"id": 2, "method": "get_properties", "params": ["prop.3.6"]} Recv: {"id":2,"error":{"code":-9999,"message":"user ack timeout"}}

Sent: {"id": 1, "method": "get_properties", "params": [{"siid": 3, "piid": 6}]} Recv: {"id":1,"error":{"code":-9999,"message":"user ack timeout"}}

Leatherface75 commented 5 years ago

Xiaomi Fan seems to work atleast so far.

rezmus commented 5 years ago

"method":"set_properties","params":[{"piid":2,"siid":2,"value":true}]

roth-m commented 5 years ago

{'code': -9999, 'message': 'user ack timeout'}

rezmus commented 5 years ago

strange, this is exact command sent to device from automation to power on purifier.

{"sa_id":2866,"model":"zhimi.airpurifier.ma4","name":"Turn on","keyName":"Turn on","type":0,"groupInfo":[],"tr_id":201,"payload":{"did":"","command":"zhimi.airpurifier.ma4.set_properties","value":[{"siid":2,"piid":2,"value":true}]}}

i even put such automation (manual trigger) on device where i can log device <> cloud traffic and got this from miio.log

{"from":"6,X,Y,.click","id":Z,"method":"set_properties","params":[{"piid":2,"siid":2,"value":true}]}

roth-m commented 5 years ago

Got it working with the DID!

"method":"set_properties","params":[{"did":"MYDID","siid":2,"piid":2,"value":true}] Turns the beast ON

"method":"set_properties","params":[{"did":"MYDID","siid":2,"piid":2,"value":true}] Turns the beast OFF

"method":"get_properties","params":[{"did":"MYDID","siid": 3, "piid": 6}] Returns: "did": "MYDID", "siid": 3, "piid": 6, "code": 0, "value": 1 }

How do you get the mapping (siid,piid) <-> function / property ?

rezmus commented 4 years ago

i found out that they use did with siid/piid from some RN plugin and sent you some json for test to your github mail yesterday. did you get it? anyway i'm glad it works, because it proves devices that deploy new miot-spec scheme can still be used with local api :)

do you have chinese version (ma4)? here is full json spec for it https://ufile.io/53ribhi8

roth-m commented 4 years ago

I got it (but prefer to write as much information in public ;) ) I have the chinese version (ma4). I bought it on BG and bet it would work the same as the previous versions (I did not see your message here otherwise I would have not ordered). I lost my bet. You make me win it with the spec file! :) Thanks a lot!

rezmus commented 4 years ago

so it looks like miot-spec is based on 3 method "get_properties", "set_properties" and "action" invoked with params according to device specs. can you check last method (action)?

1st get some info about filter usage with get_properties siid:4/piid:3 (filter life) and siid:4/piid:5 (filter usage time). next send (with aiid, not piid)

"method":"action","params":[{"did":"MYDID","siid":4,"aiid":1}]

if executed correctly it should reset your filter life. hope it won't be big issue because you don't have it to long ;) resend get_properties to confirm.

roth-m commented 4 years ago

It does nothing. No reply and no change on filter-life-level.

I tried with {"did":"MYDID","siid":4,"aiid":1, "in": [ true ]}] also, without luck.

rezmus commented 4 years ago

try this way (i found it on some blanket)

"method":"action","params":[{"did":"MYDID","siid":4,"aiid":1,"in":[{"piid":1,"value":true}]}] or "method":"action","params":[{"did":"MYDID","siid":4,"aiid":1,"in":[]}]

if it does not work maybe they just didn't implement it in firmware. i guess it's not so important for purifier while get/set works.

roth-m commented 4 years ago

No luck... Tried the "in": [ ] before and retried again.... but no :|

rezmus commented 4 years ago

miot-spec is what they manually setup with xiaomi iot developer platform so it does not have to fully cover firmware features. i guess we will test it with some other devices, because more and more will come which deploy this scheme.

vampywiz17 commented 4 years ago

My Air purifier 3 is on the way. It possible that is supported?

roth-m commented 4 years ago

A minimal implementation using Python and MQTT is here: https://github.com/roth-m/mqttmiot-airpurifier3 You can control the Fan speed as you like and get data from the purifier (pm2.5, temperature, filter remaining time, ...)

vampywiz17 commented 4 years ago

A minimal implementation using Python and MQTT is here: https://github.com/roth-m/mqttmiot-airpurifier3 You can control the Fan speed as you like and get data from the purifier (pm2.5, temperature, filter remaining time, ...)

great news!!! Thanks! You will plan to expand the features list? (if possible, of course)

rezmus commented 4 years ago

@roth-m can you please share props value for 13/4 (aqi-zone) and 10/1-6? i would like to compare with older models. aqi-zone defines aqi value ranges for auto mode (each range has associated fan speed with 10/1-6). for my 2s it was factory "35,75,115,150,250", but i played with firmware ;)

roth-m commented 4 years ago

So, for the record...

aqi zones 13 4: 35,75,115,150,250 10 1: 2150 10 2: 1900 10 3: 1600 10 4: 1300 10 5: 770 10 6: 390

vampywiz17 commented 4 years ago

@roth-m @rezmus

I got my machine.

If need, i able to help you to discover the functions! The python - MQTT script working well, i get the data. if we able to set it, it will be perfect!

roth-m commented 4 years ago

Just send 70 to /fanspeed and it should set the fan speed to 70%.

At this time, the fanspeed/state will not be exactly the same as there are only 14 levels of speed and thus the code will update fanspeed/state to /14*100.

vampywiz17 commented 4 years ago

The "On/Off" and "Mode" params working with your device?

I try this to turn on the device:

miio protocol call 192.168.31.121 "method":"set_properties","params":[{"did":".my_did","siid":2,"piid":2,"value":true}] But nothing happen.

other question, the fanspeed state is RPM value?

roth-m commented 4 years ago

Yes they work.

Are you trying to issue a command using nodejs miio package?! In this case you should have: set_properties '[{"did":"my_did","siid":2,"piid":2,"value":true}]'

Using my implementation, the reported fanspeed is a percentage (among the 14 levels). This might change in a later version.

vampywiz17 commented 4 years ago

@roth-m

How to send ON or OFF (ar any control ) command with your implementation via MQTT?

roth-m commented 4 years ago

Send ON or OFF to the PREFIX/power topic.

vampywiz17 commented 4 years ago

Ehh oh my god. I'm stupid, i send the command before the "state" subtopic.... sorry for that....

Working well, thanks!

rezmus commented 4 years ago

@roth-m can you read one more thing 13/9? this one is very promising for mi home users i think. aqi heartbeat in older models was hardcoded to 1800s or aqi change >19ug/m3 (since last value send to cloud), which made automation work a bit laggy.

roth-m commented 4 years ago

13 9: Value is 0!

rezmus commented 4 years ago

maybe when it's 0 it uses hardcoded value or they just didn't implement it, tx anyway for testing ;)

Sku4l commented 4 years ago

Hey guys, thanks a lot for the work!

Apologies for the noob question, but what exactly is the "DID" ? I am aware of broker/ip/purifiertoken/etc.. but I do not understand what I am supposed to put as the DID ?

vampywiz17 commented 4 years ago

Device ID

It is a number near the device name if you discover it.

GiaQuy commented 4 years ago

Một triển khai tối thiểu bằng Python và MQTT có tại đây: https://github.com/roth-m/mqttmiot-airpurifier3 Bạn có thể điều khiển tốc độ Quạt theo ý muốn và lấy dữ liệu từ bộ lọc (pm2,5, nhiệt độ, thời gian còn lại của bộ lọc , ...)

tin tốt!!! Cảm ơn! Bạn sẽ có kế hoạch mở rộng danh sách tính năng? (nếu có thể, tất nhiên)

Hi, I'm a new user. I have xiaomi air purifier 3 (zhimi.airpurifier.ma4) and how can i add it to hass with mqtt ? many thanks

cedriccheah commented 4 years ago

A minimal implementation using Python and MQTT is here: https://github.com/roth-m/mqttmiot-airpurifier3 You can control the Fan speed as you like and get data from the purifier (pm2.5, temperature, filter remaining time, ...)

Hi roth-m, I am quite new to HA. Can share the light how to use your script?

roth-m commented 4 years ago

Hi,

Sorry, I do NOT know much about HA (never used it).

rytilahti commented 4 years ago

@rezmus looks like your link to the spec has expired (The hosting period for this file has now expired, only premium users can download it.). Would you mind uploading it to github as a gist or somewhere else to make it accessible again?

From what I gather, this is a consolidation of the used APIs (i.e., replacing get_prop with get_properties and separate set_x methods with set_properties), am I reading it correctly? If so, I think we should create a new base class (MiOTDevice or something) and start basing devices using the protocol on top of that. Before doing that, it would be great to have a confirmation that this is the case, though. Are there also other devices using this new-style API?

rezmus commented 4 years ago

yeah miot spec is all about get_properties / set_properties / action (still need to figure out that one) based on spec file.

http://miot-spec.org/miot-spec-v2/instances?status=all

and for example air purifier 3 cn (zhimi.airpurifier.ma4)

https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-ma4:1

as you can see there are many devices that have miot specs, but most lack support in firmware. i've tested a few of mine and all failed. anyway miot spec way is xiaomi goal now so more and more devices will come and maybe some older get support via firmware update.

these devices use miot spec api for sure, but there are probably more.

090615.plug.plus01 090615.plug.plus02 666.curtain.gt01 cuco.plug.cp1 huayi.light.aries huayi.light.fanwy huayi.light.wy lumi.curtain.hagl05 miaomiaoce.blanket.d02 miaomiaoce.blanket.s02 smith.blanket.cxma1 szdy.airfresh.n80 xinyue.blanket.n1918 yeelink.light.dn2grp yeelink.light.dnlight2 yeelink.light.mb1grp yeelink.light.mb2grp yeelink.light.meshbulb1 yeelink.light.meshbulb2 yeelink.light.sp1grp yeelink.light.spot1 zhimi.airpurifier.ma4 zhimi.airpurifier.mb3 zhimi.airpurifier.va1 zhimi.heater.ma2 zhimi.heater.za2

rytilahti commented 4 years ago

Thanks for the links! I spent some time to to tinker a parser to make those descriptions easier to understand. My understanding is the following: a single device can contain multiple services (addressed by siid), all of which can expose different properties (piid), actions (aiid), and events (eiid). Each property can have different access controls, so I assume only those with write can be set with set_properties. One example being siid 10: (motor-speed), which has write and would thus allow adjusting the levels, if my assumption holds. Some properties also define what sort of inputs they take (value-list or value-range), and/or the used units (e.g., celsius or percentage).

Also, if this really works locally on several devices, it would be pretty straightforward to generate some basic support for all the devices having a description file. Here's an example for the device you linked, maybe this is helpful for someone with the device :-) I don't have any of those you listed, so I cannot really test and develop that right now.

Found service: siid 2: (Air Purifier): 4 props, 0 actions
Found service: siid 1: (Device Information): 4 props, 0 actions
Found service: siid 3: (Environment): 3 props, 0 actions
Found service: siid 4: (Filter): 2 props, 1 actions
Found service: siid 5: (Alarm): 1 props, 0 actions
Found service: siid 6: (Indicator Light): 2 props, 0 actions
Found service: siid 7: (Physical Control Locked): 1 props, 0 actions
Found service: siid 8: (button): 1 props, 2 actions
Found service: siid 9: (filter-time): 2 props, 0 actions
Found service: siid 10: (motor-speed): 10 props, 0 actions
Found service: siid 12: (use-time): 1 props, 0 actions
Found service: siid 13: (aqi): 9 props, 0 actions
Found service: siid 14: (rfid): 5 props, 0 actions
Found service: siid 15: (others): 9 props, 0 actions

Service: siid 2: (Air Purifier): 4 props, 0 actions
    * Property piid: 1 (Device Fault): (uint8, unit: None) (acc: ['read', 'notify'], value-list: [{'value': 0, 'description': 'No faults'}, {'value': 1, 'description': 'm1_run'}, {'value': 2, 'description': 'm1_stuck'}, {'value': 3, 'description': 'no_sensor'}, {'value': 4, 'description': 'error_hum'}, {'value': 5, 'description': 'error_temp'}], value-range: [])
    * Property piid: 2 (Switch Status): (bool, unit: None) (acc: ['read', 'write', 'notify'], value-list: [], value-range: [])
    * Property piid: 4 (Fan Level): (uint8, unit: None) (acc: ['read', 'write', 'notify'], value-list: [{'value': 1, 'description': 'Level1'}, {'value': 2, 'description': 'Level2'}, {'value': 3, 'description': 'Level3'}], value-range: [])
    * Property piid: 5 (Mode): (uint8, unit: None) (acc: ['read', 'write', 'notify'], value-list: [{'value': 0, 'description': 'Auto'}, {'value': 1, 'description': 'Sleep'}, {'value': 2, 'description': 'Favorite'}, {'value': 3, 'description': 'None'}], value-range: [])

Service: siid 1: (Device Information): 4 props, 0 actions
    * Property piid: 4 (Current Firmware Version): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 1 (Device Manufacturer): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 2 (Device Model): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 3 (Device Serial Number): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])

Service: siid 3: (Environment): 3 props, 0 actions
    * Property piid: 6 (PM2.5 Density): (float, unit: None) (acc: ['read', 'notify'], value-list: [], value-range: [0, 600, 1])
    * Property piid: 7 (Relative Humidity): (uint8, unit: percentage) (acc: ['read', 'notify'], value-list: [], value-range: [0, 100, 1])
    * Property piid: 8 (Temperature): (float, unit: celsius) (acc: ['read', 'notify'], value-list: [], value-range: [-40, 125, 0.1])
Service: siid 4: (Filter): 2 props, 1 actions
    * Property piid: 3 (Filter Life Level): (uint8, unit: percentage) (acc: ['read', 'notify'], value-list: [], value-range: [0, 100, 1])
    * Property piid: 5 (Filter Used Time): (uint16, unit: hours) (acc: ['read', 'notify'], value-list: [], value-range: [0, 10000, 1])
    * Action aiid 1 Reset Filter Life: in: [] -> out: []

Service: siid 5: (Alarm): 1 props, 0 actions
    * Property piid: 1 (Alarm): (bool, unit: None) (acc: ['read', 'write', 'notify'], value-list: [], value-range: [])

Service: siid 6: (Indicator Light): 2 props, 0 actions
    * Property piid: 1 (Brightness): (uint8, unit: percentage) (acc: ['read', 'write', 'notify'], value-list: [{'value': 0, 'description': 'brightest'}, {'value': 1, 'description': 'glimmer'}, {'value': 2, 'description': 'led_closed'}], value-range: [])
    * Property piid: 6 (Switch Status): (bool, unit: None) (acc: ['read', 'write', 'notify'], value-list: [], value-range: [])

Service: siid 7: (Physical Control Locked): 1 props, 0 actions
    * Property piid: 1 (Physical Control Locked): (bool, unit: None) (acc: ['read', 'write', 'notify'], value-list: [], value-range: [])

Service: siid 8: (button): 1 props, 2 actions
    * Property piid: 1 (button_pressed): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Action aiid 1 toggle: in: [] -> out: []
    * Action aiid 2 toggle-mode: in: [] -> out: []
    * Event eiid 1 (child-lock-trigger): (args: [])

Service: siid 9: (filter-time): 2 props, 0 actions
    * Property piid: 1 (filter-max-time): (int32, unit: hours) (acc: ['read', 'write'], value-list: [], value-range: [2000, 6000, 1])
    * Property piid: 2 (filter-hour-used-debug): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 5000, 1])
    * Event eiid 1 (filter1-eof): (args: [])
    * Event eiid 2 (filter-door-opened): (args: [])

Service: siid 10: (motor-speed): 10 props, 0 actions
    * Property piid: 1 (m1-strong): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 2 (m1-high): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 3 (m1-med): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 4 (m1-med-l): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 5 (m1-low): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 6 (m1-silent): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 7 (m1-favorite): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [300, 2300, 10])
    * Property piid: 8 (motor1-speed): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 3000, 1])
    * Property piid: 9 (motor1-set-speed): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 3000, 1])
    * Property piid: 10 (favorite fan level): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 14, 1])

Service: siid 12: (use-time): 1 props, 0 actions
    * Property piid: 1 (use-time): (int32, unit: seconds) (acc: ['read'], value-list: [], value-range: [0, 2147483600, 1])

Service: siid 13: (aqi): 9 props, 0 actions
    * Property piid: 1 (purify-volume): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 2147483600, 1])
    * Property piid: 2 (average-aqi): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 600, 1])
    * Property piid: 3 (average-aqi-cnt): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 2147483600, 1])
    * Property piid: 4 (aqi-zone): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 5 (sensor-state): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 6 (aqi-goodh): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 115, 1])
    * Property piid: 7 (aqi-runstate): (int32, unit: None) (acc: ['read'], value-list: [{'value': 0, 'description': 'continue'}, {'value': 1, 'description': 'hold'}, {'value': 2, 'description': 'sleep'}], value-range: [])
    * Property piid: 8 (aqi-state): (int32, unit: None) (acc: ['read'], value-list: [{'value': 0, 'description': 'AQI_GOOD_L'}, {'value': 1, 'description': 'AQI_GOOD_H'}, {'value': 2, 'description': 'AQI_MID_L'}, {'value': 3, 'description': 'AQI_MID_H'}, {'value': 4, 'description': 'AQI_BAD_L'}, {'value': 5, 'description': 'AQI_BAD_H'}], value-range: [])
    * Property piid: 9 (aqi-updata-heartbeat): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 65534, 1])

Service: siid 14: (rfid): 5 props, 0 actions
    * Property piid: 1 (rfid-tag): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 2 (rfid-factory-id): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 3 (rfid-product-id): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 4 (rfid-time): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 5 (rfid-serial-num): (string, unit: None) (acc: ['read'], value-list: [], value-range: [])

Service: siid 15: (others): 9 props, 0 actions
    * Property piid: 1 (app-extra): (int32, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [0, 10000, 1])
    * Property piid: 2 (main-channel): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 10000, 1])
    * Property piid: 3 (slave-channel): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 10000, 1])
    * Property piid: 4 (cola): (string, unit: None) (acc: ['read', 'write'], value-list: [], value-range: [])
    * Property piid: 5 (buttom-door): (bool, unit: None) (acc: ['read'], value-list: [], value-range: [])
    * Property piid: 6 (reboot_cause): (int32, unit: None) (acc: ['read'], value-list: [{'value': 0, 'description': 'REASON_HW_BOOT'}, {'value': 1, 'description': 'REASON_USER_REBOOT'}, {'value': 2, 'description': 'REASON_UPDATE'}, {'value': 3, 'description': 'REASON_WDT'}], value-range: [])
    * Property piid: 8 (hw-version): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 66535, 1])
    * Property piid: 9 (i2c-error-count): (int32, unit: None) (acc: ['read'], value-list: [], value-range: [0, 66535, 1])
    * Property piid: 10 (manual-level): (int32, unit: None) (acc: ['read'], value-list: [{'value': 1, 'description': 'Level1'}, {'value': 2, 'description': 'Level2'}, {'value': 3, 'description': 'Level3'}], value-range: [])
    * Event eiid 1 (status_report): (args: [1])

Btw, the firmware may not support that API for local access, but maybe this format may still be used for cloud connectivity and that's why there is so many devices and information about them?

rezmus commented 4 years ago

i don't think so, because i have firmware and cloud credentials for most of my devices. those with miotspec db record do not even have support for get/set_properties in firmware, there is also no sign of it in cloud logs. anyway i will investigate more, maybe future updates change something.

rezmus commented 4 years ago

@roth-m any chance you can connect your purifier to xiaomi cloud for a sec to test 13/9 (aqi heartbeat)? you could set it to 10 for example. obviously you can't decrypt traffic without cloud key, but you can still do

tcpdump -w ma4.pcap port 8053 and greater 75

to see if there is something sent to xiaomi cloud every 10s (len > 75 fillters out ping/pongs). it's kinda important to ppl still using xiaomi automation, because (old generation sends data very rare which makes automation not very useful).

edit: i've checked on shared device and looks like 13/9 is some kind of count down timer. when you set some value and then get prop it's being decreased by 1 every sec till 0.

danekszy commented 4 years ago

@rezmus Isn't it what aqi-updata-heartbeat (siid 13 piid 9) is for? The spec marks this as writable, but somehow it seems to lose it's value shortly after setting it... :( Edit: I've overlooked your edit. 😛 Yeah, it seems to count down, by 5.

rezmus commented 4 years ago

i'm not sure what is it for. i was hoping you can set heartbeat for aqi there (how often aqi is sent to cloud), but it looks it's not the case. older models (2s/pro) have aqi hearbeast hardcoded in firmware (every 30 minutes OR aqi level changed >20 since last send) which makes data feed / automation really laggy.

danekszy commented 4 years ago

I see. Will keep poking the holes... Is there any discussion/decision around implementing miot in this library (as someone suggested earlier)? Doesn't seem like that big of a change, from what I see. 😄 Btw. @rezmus - how did you get to modify FW for the device?

rezmus commented 4 years ago

i did some patches for 88mw300 (2s/pro) with IDA and

https://github.com/dgiese/dustcloud-nexmon/tree/master/firmwaretools/Marvel_MW30x

danekszy commented 4 years ago

Awesome, thanks @rezmus!

@rytilahti and/or any other maintainers (sorry, I'm new to the project) - Whats your take on this issue? Do you have any particular direction in mind for the project? Should this change even be implemented within it? If so, how? A [sub]class? Would any contributions be welcome here?

Not sure how exactly does miot compare to miio, espacially on Xiaomi's side, but I can confirm that (at least in the case of AP3) the API calls work locally (w/o internet connected), just like they did in miio. Other than this, I think you've nailed it above @rytilahti. 😉

lsiudut commented 4 years ago

And boom, now I landed in this world of madness of changed APIs. Ordered one to my family home, managed to force my brother configure it, just to discover that I can't control it via mii. Moreover now I can't also get DID as it's already configured (unless there's a secret way I haven't discover yet).

I'm far from my home, but I'm also quite motivated to do something with this sad state though. I'll probably order another one for me just to hack on it a bit. Btw. have anyone noticed that it apparently runs on ESP32? I don't believe that no one thought about looking into it ;-).

Sorry for slight offtop.

rytilahti commented 4 years ago

@danekszy so my take is that this should be implemented in this project assuming the change is just in the payload format. I'm bit on hold on this considering it is unclear how many devices will allow commanding them locally (but I think that'll be the regular case), so I'd be glad to hear experiences with other devices besides the AP3. Alternatively, if one of those miot supporting devices is reasonably priced (let's say under 50$), I'd be happy to hear about it so I can get myself one for testing.

Anyway, if it turns out to be that other devices are also controllable, we should definitely create a subclass of Device (as noted earlier) to use as a base for miot devices. What I'm unsure of is whether to use the descriptor files to generate ready-to-use interfaces, or simply use it as a helping hand to generate some code to be adjusted as needed. Regarding to contributions, they are always welcome :-)

@lsiudut I think the did is accessible in the mi home's database (and/or via poking the xiaomi's http api), but I haven't checked that myself. I'm also sure some people have been poking into those parts, some people find ARM-based systems more interesting than ESP*s ;-)