Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
rezmus opened this issue Aug 30, 2019 · 93 comments
Closed

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

rezmus opened this issue Aug 30, 2019 · 93 comments

Comments

@rezmus
Copy link

rezmus commented Aug 30, 2019

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
Copy link
Collaborator

syssi commented Aug 30, 2019

Wow. Terrible news.

@vampywiz17
Copy link

vampywiz17 commented Sep 6, 2019

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
Copy link

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

@roth-m
Copy link

roth-m commented Sep 13, 2019

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
Copy link
Author

rezmus commented Sep 14, 2019

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

@roth-m
Copy link

roth-m commented Sep 14, 2019

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
Copy link

Xiaomi Fan seems to work atleast so far.

@rezmus
Copy link
Author

rezmus commented Sep 14, 2019

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

@roth-m
Copy link

roth-m commented Sep 14, 2019

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

@rezmus
Copy link
Author

rezmus commented Sep 14, 2019

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
Copy link

roth-m commented Sep 15, 2019

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
Copy link
Author

rezmus commented Sep 15, 2019

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
Copy link

roth-m commented Sep 15, 2019

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
Copy link
Author

rezmus commented Sep 15, 2019

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
Copy link

roth-m commented Sep 17, 2019

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
Copy link
Author

rezmus commented Sep 17, 2019

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
Copy link

roth-m commented Sep 17, 2019

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

@rezmus
Copy link
Author

rezmus commented Sep 18, 2019

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
Copy link

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

@roth-m
Copy link

roth-m commented Sep 22, 2019

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
Copy link

vampywiz17 commented Sep 23, 2019

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
Copy link
Author

rezmus commented Sep 23, 2019

@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
Copy link

roth-m commented Sep 24, 2019

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
Copy link

vampywiz17 commented Sep 26, 2019

@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
Copy link

roth-m commented Sep 26, 2019

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
Copy link

vampywiz17 commented Sep 27, 2019

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
Copy link

roth-m commented Sep 27, 2019

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
Copy link

vampywiz17 commented Sep 27, 2019

@roth-m

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

@roth-m
Copy link

roth-m commented Sep 27, 2019

Send ON or OFF to the PREFIX/power topic.

@vampywiz17
Copy link

vampywiz17 commented Sep 27, 2019

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

Working well, thanks!

@Loic691
Copy link

Loic691 commented Feb 9, 2020

Hi all
I writted recently a plugin based on miio lib for support of humidifier CA1 in eedomus.
All was fine.
Since few days, my humidifier done automaticaly an update to 1.6.7.1032 and the miio lib don't working now.

I don't understand if xiaomi replace old miio protocol by miot based on cloud ?
I'm don't happy for this because manage our xiaomi device on local without cloud is the best things we can have...
Is this the reason?
A lib / sdk is ready for this?

Can you confirm these informations
Thanks a lot

@tuxuser
Copy link

tuxuser commented Feb 14, 2020

How can somebody help on this issue / protocol? Could we get up a TODO list?

@mouth4war
Copy link
Contributor

mouth4war commented Feb 18, 2020

yeah we already checked it's some sort of count down (by 5s), but not sure what it really does.

@rezmus Based on my testing, it looks like this parameter needs to be set every minute to 60 to get AQI updates from purifier. If you don't set it, once it zeroes out, the purifier stops giving frequent updates (AQI doesn't seem to change as much - almost like its being smoothened).

It's like a keep-alive heartbeat that tells the purifier to update AQI real-time.

@rezmus
Copy link
Author

rezmus commented Feb 18, 2020

yeah from my understanding and when i checked plugin code when it's set it sends data to cloud every 5s. that's why plugin set it to 60 every 50s so it keeps data feed frequent when you are in the app. my idea for regular users with mi home app was to set it twice a day to 43200 (12x3600s) via schedule to keep constant feed (you can't open plugin meanwhile). i'm just not sure if it won't make too much traffic to cloud ;)

@mouth4war
Copy link
Contributor

mouth4war commented Feb 18, 2020

So if we want to use only locally only (no cloud), we can set the value to maximum possible and since plugin is where cloud update happens, there will be no cloud traffic hitting their servers hard.

Why don't you give it a try and tell us how it goes? I don't use mi home for automations, I use home-assistant.

@rezmus
Copy link
Author

rezmus commented Feb 18, 2020

i don't have 3/3h. for non mi home users you just don't set it because there is no point. 0 counter = no cloud updates.

@mouth4war
Copy link
Contributor

I think the parameter affects real-time reporting of AQI versus smoothened AQI in the purifier firmware. I'm sure what you say about plugin reporting to xiaomi server is correct but I'm talking about the firmware on the purifier itself.

Seems to be that when this heartbeat is set to zero (not alive), there is a smoothened AQI number reported by purifier (if within +/- 10 AQI of previous reading, don't report a new value). When it is positive (get alive!), it picks up the actual AQI (within +/- 1 AQI). This is probably coded in the firmware itself and not the app plugin.

In a way, the user needs to be looking for real-time update via the app to receive actual number. If the plugin isn't opened, say you look at the shortcut card - it will not set this parameter. Once you open the plugin, it sets it for 60 seconds (probably average user interaction time with the plugin) so that user sees live values.

@rezmus
Copy link
Author

rezmus commented Feb 18, 2020

are you saying that when the app is off (counter = 0) you don't get real time readings on oled or via get_properties 3/6? that would be really strange. like i said i don't have 3/3h, but with older purifiers i never seen such thing.

@mouth4war
Copy link
Contributor

mouth4war commented Feb 18, 2020

OLED shows real-time but get_prop doesn't. And yeah I have older air purifiers which don't do this but then their AQI readings change a lot over a few minutes (+/- 2 of a mean value) especially in lower AQI number range.

People have reported this in the re-opened air purifier 3 pull request #585 as the 20 AQI issue (eg #585 (comment)) where oled shows a lower number than get_properties.

@pawelkw @cisco-devnet please set 13:9 to 600 and test by blowing smoke or vapor at your purifiers. Expected result should be real-time AQI values for 10 minutes. And while you're at it, could you also check if you get temperature readings in 0.1 C increments or 0.5 C increments.

@mouth4war
Copy link
Contributor

mouth4war commented Feb 23, 2020

Update regarding how my purifiers (I have 3 new ones) are all acting up - they report AQI/Temperature as a float with 10 decimal places and then go unavailable/offline. This happens throughout the day but a lot more when the purifier is on.

I'm hoping it's a fixable firmware issue. Worst case it's a miot issue that can not be fixed. Anyone else seen this behaviour in the purifier 3 or other devices?

@rezmus what's the prop name for 13:9 so i can send a raw command?

@rezmus
Copy link
Author

rezmus commented Feb 24, 2020

with miot spec there are not prop names. you just send

{"method":"set_properties","params":[{"did":"yourdid","siid":13,"piid":9,"value":x}]}

@mouth4war
Copy link
Contributor

Thanks for that. Setting this prop did enable real-time reporting of PM25.

@CLARENNE-Q
Copy link

Do you have some news about this request ?

@rytilahti
Copy link
Owner

@CLARENNE-Q could you be more specific?

The current state of affairs is that we have now basic miot implementation and support for one device using this protocol.

@Siutat
Copy link

Siutat commented Apr 14, 2020

@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!

hi could you please share how you get the Xiaomi Air Purifier 3 (zhimi.airpurifier.ma4) work with hassio? Thanks.

@rytilahti
Copy link
Owner

The next homeassistant release (0.109) will include support for that device, as how to use this before that you need to consult hassio documentation (or support forums) to find out how you can install the dev branch of homeassistant on it.

Anyway, as we now have basic miot support merged, I will close this issue now. Special thanks to @rezmus, @petrkotek and @foxel for their work on this! 🥇

@Yonsm
Copy link

Yonsm commented Jul 29, 2020

so do zhimi.fan.fa1

@SpeedFire0
Copy link

Based on the information above I was able to get the data from an unsupported device (HeatCold Heating Floor Controller - cubee.airrtc.th123e) and to set the required parameters from a Terminal on Mac. Now is the hard part - how to convert this in the working plugin for Home Assistant and then HomeKit?

Here is my step-by-step guide for all newcomers who want to play with their devices:

  1. Install python-miio on Mac. Enter this in Terminal app on Mac:
    sudo pip3 install python-miio

  2. Get model name of your device ("cubee.airrtc.th123e" in my case), IP address (like "192.168.1.152") and Token (like "b110204d86732b019d3d6axxxxb9ad3a"). The easiest way for me was to use this integration for Home Assistant - https://github.com/AlexxIT/XiaomiGateway3

  3. Check that your device is accessible by entering the following in a Terminal app on Mac:
    miiocli -d device --ip 192.168.1.152 --token b110204d86732b019d3d6axxxxb9ad3a info
    Note 1: You need to put your device's IP and Token here.
    Note 2: "-d" is for Debug and can be excluded for a shorter output.
    In my case I got something like this:
    "Model: cubee.airrtc.th123e
    Hardware version: esp32
    Firmware version: 2.1.7"
    Device is responding! Nice! Going to the next step.

  4. Find your device in the list of MIOT devices:
    http://miot-spec.org/miot-spec-v2/instances?status=all
    I searched for "cubee.airrtc.th123e" and found the following line:
    {"status":"released","model":"cubee.airrtc.th123e","version":1,"type":**"urn:miot-spec-v2:device:thermostat:0000A031:cubee-th123e:1"**},

  5. Copy the "urn" part after this url:
    https://miot-spec.org/miot-spec-v2/instance?type=
    in my case: https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:thermostat:0000A031:cubee-th123e:1
    You will see an unformatted JSON text of the device's specs

  6. Put this JSON text to any JSON Formatter to make it more human readable. For example here: http://json.parser.online.fr/

  7. You will see a hierarchy with a list of Services (later used as "siid"), each of which has a list of Properties ("piid"):

miot_json

  1. You need to find some property in the list which you want to get from the device and which is readable
    (in my case siid 1 didn't return the value, so you may want to check other services like "siid 2" and other properties)
    I wanted to receive the current "Target Temperature". This is "siid":2 and "piid":5:

miot_json_temp

  1. Try to get a response from your device by entering this in Terminal:
    miiocli -d device --ip 192.168.1.152 --token b110204d86732b019d3d6axxxxb9ad3a raw_command get_properties "[{'did': 'MYDID', 'siid': 2, 'piid': 5 }]"
    Note: replace IP, token, siid and piid with your values
    I got a response the last line of which was:
    "[{'did': 'MYDID', 'siid': 2, 'piid': 5, 'code': 0, 'value': 29}]"
    This was an actual Target Temperature set on my device: 29 degrees celsius! It works!

  2. Now let's try to change some properties. Make sure it has a "write" access (look at the the field "access" for a particular piid in the JSON file mentioned above).
    I want to set 28 degrees and here is the command for that:
    miiocli -d device --ip 192.168.1.152 --token b110204d86732b019d3d6axxxxb9ad3a raw_command set_properties "[{'did': 'MYDID', 'siid': 2, 'piid': 5, 'value' : 28 }]"
    The new temperature was set on my device and was also updated in MiHome app!

  3. Check that the value / setting was set on an actual device and redo step 9 to confirm that the new value is successfully returned by the device.

That's all! Now you can retrieve and set values from a Terminal.
This was my part. I would be glad if someone describes how to further make a Home Assistant plugin based on this knowledge :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests