Open technyon opened 8 months ago
P.S.:
If I run any other "device" command (descriptors, sensors, settings), I get this message:
WARNING 'Device' does not specify any descriptors, please considering creating a PR.
I've tried adding it to airpurifier_miot.py:
"zhimi.airp.rma3": _MAPPING_RMB1, # airpurifier 4 lite
The result is the same unfortunately.
Did you try the command shown in the info? Try miiocli genericmiot --ip 192.168.8.232 --token <redacted> status
:-)
The warning about missing descriptors is unrelated, it's more aimed for other commands than miiocli device
.
For the airpurifier_miot.py, the command is miiocli airpurifiermiot
.
I've made some progress. Yes running the suggested command works, I have to say this is very confusing as a user. You run a command which outputs the correct command to run.
I was also able to control the device using "miiocli airpurifiermiot", status gives an empty output though. Calling status on genericmiot only gives me read only properties like temperature and humidity, nothing to control the device. I can control the device though by specifying siid and piid manually like this:
miiocli genericmiot --ip 192.168.8.232 --token
Thanks so far, next I'll try to access the API directly using a python script. Would you still classify this as a bug, since the original NotImplementedError is still valid? Otherwise I'd close this issue.
Ohh, I didn't realize genericmiot status
is not showing the settable items, that's a bug...
You can try miiocli genericmiot settings
(and miiocli genericmiot set
for changing values), miiocli genericmiot actions
(and miiocli genericmiot call
for executing an action) for the time being. For example, on your device:
# set the screen brightness to brightest (0 = off, 1 = bright, 2 = brightest)
miiocli genericmiot set screen:brightness 2
# turn the device off
miiocli genericmiot air-purifier:on 0
# toggle device state
miiocli genericmiot call air-purifier:toggle
Let's keep this issue open, as it's indeed confusing that calling miiocli device
errors out like that.
To add to your API question, it really depends on what you want to do.
The easiest way is to use a repl like ipython to explore the API (besides checking out https://github.com/rytilahti/python-miio/#api-usage), as you can use a tab for autocompletion.
Here are some examples (using a simulated rma3):
In [1]: from miio import DeviceFactory
In [2]: dev = DeviceFactory.create("127.0.0.1", 32*"0")
In [3]: dev
Out[3]: <GenericMiot: 127.0.0.1 (token: 00000000000000000000000000000000)>
In [5]: status = dev.status()
In [6]: status.data
Out[6]:
{'air-purifier:fault': 3,
'environment:relative-humidity': 38,
'environment:pm2.5-density': 507,
'environment:temperature': 70,
'environment:air-quality': 1,
'filter:filter-life-level': 13,
'filter:filter-used-time': 8073,
'filter:filter-left-time': 434,
'custom-service:moto-speed-rpm': 2388}
In [7]: status.filter_filter_used_time
Out[7]: 8073
In [8]: settings = dev.settings()
In [9]: list(settings)
Out[9]:
['air-purifier:on',
'air-purifier:mode',
'alarm:alarm',
'screen:brightness',
'physical-controls-locked:physical-controls-locked',
'air-purifier-favorite:fan-level',
'custom-service:filter-used-time-dbg',
'aqi:aqi-updata-heartbeat']
In [10]: on = settings["air-purifier:on"]
In [11]: on.setter
Out[11]: functools.partial(<bound method MiotDevice.set_property_by of <GenericMiot: 127.0.0.1 (token: 00000000000000000000000000000000)>>, 2, 1, name='air-purifier:on')
In [12]: on.setter(True)
Out[12]: 0
In [13]: on.setter(False)
Out[13]: 0
In [14]: brightness = settings["screen:brightness"]
In [15]: brightness.choices
Out[15]: <enum 'Brightness'>
In [16]: list(brightness.choices)
Out[16]: [<Brightness.Close: 0>, <Brightness.Bright: 1>, <Brightness.Brightest: 2>]
In [17]: brightness.name
Out[17]: 'Brightness'
In [18]: brightness.setter(1)
Out[18]: 0
Also, if you don't need anything fancy, you can also use the *_by()
methods of the MiotDevice class to read & write individual properties.
Alas, proper documentation for API usage is missing at the moment, but let me know what you need and I'll try to help.
Thanks, control using the set command works.
Good input for exploring the API, will do tomorrow, it's already late here. If all works out I have the idea to add an MQTT client to my code so I can control via iobroker (which runs on nodejs. There's some javascript code available but it hasn't been updated in years unfortunately).
Sure thing! I think the simplest way to explore would be using a graphical debugger (e.g., pycharm) as it can be overwhelming with all the dynamically constructed data.
pycharm is already up and running :).
Thanks again.
Great! Let me know if you find something odd or if you have some ideas what should be included in the docs regarding the API use.
Sure will do
I made some progress: I can read the status and publish it to MQTT. Accessing setting and controlling the device works (e. g. turn on/off with on.setter(False)). What I couldn't figure out though, is there a way to get the current value of a setting. It says read/write, so it should be possible to read and not only to write.
I've figured out how to do it, although it's rather complicated as I did it. Is there an easier way to get the settings current value?
You can check my script at:
https://github.com/technyon/mqmiio/
I've kept it very general, so best case this works for more than just my air purifier.
Also, should we create a seperate issue for this discussion?
Describe the bug I want to control my Xiaomi Air Purifier 4 Lite, it is a model for chinese mainland. It took some work to get it to work outside of china with the smartphone app, and I can connect using miiocli now:
If I try however to run the status command, I get a NotImplementedError in device.py:
Version information (please complete the following information):
miiocli --version
orpip show python-miio
] I've installed the latest version directly from github:Device information: If the issue is specific to a device [Use
miiocli device --ip <ip address> --token <token> info
]:To Reproduce Steps to reproduce the behavior:
Expected behavior The output of the status command is printed.
Console output See above.