Xiaomi Humidifier support

It is supported (deerma.humidifier.mjjsq).

@E1m0 Could you provide the model number of your device (CA1?) to improve the list of supported devices? https://github.com/syssi/xiaomi_airpurifier#supported-devices

Hi! I have a problem with integration of Air Humidifier v2. Yes, Iā€™ve tried to reinstall integration, but it does not solve the problem.

HA: 0.113.1
Python: 3.7.3
python-miio: 0.5.2.1
Setup type: virtualenv + pip3 install ha
Humidifier firmware version: 2.0.6.1035

As I can see integration uses python-miio. Also python-miio setted up utility named miiocli. Using this util I can get status of humidifier at the same time I canā€™t do it with miio as library. Also Home Assistant failed to get status and show errors like this:

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

So, integration does not works.

I checked working with humidifier from other computer without HA and newer version of python-miio and got the same results:

corpse@lenovo [21:42:01]:~$ pip3 freeze | grep miio
python-miio==0.5.3
corpse@lenovo [21:42:09]:~$ miiocli airhumidifierca1 --ip 10.11.11.190 --token f54f5ba9640c964e27083fd9cec19a49 status
Power: off
Mode: OperationMode.High
Temperature: 22.4 Ā°C
Humidity: 28 %
LED brightness: LedBrightness.Off
Buzzer: False
Child lock: False
Target humidity: 70 %
Trans level: None
Speed: 0
Depth: 125
Dry: True
Use time: 5730894
Hardware version: 0001
Button pressed: None
corpse@lenovo [21:42:31]:~$ bpython3
bpython version 0.18 on top of Python 3.8.5 /usr/bin/python3
>>> import miio 
>>> fan = miio.Fan(ip="10.11.11.190", token="f54f5ba9640c964e27083fd9cec19a49", lazy_discover=False, debug=1, model="airhumidifierca1")
>>> fan.info()
zhimi.humidifier.ca1 v2.0.6 (04:CF:8C:AE:7D:71) @ 10.11.11.190 - token: f54f5ba9640c964e27083fd9cec19a49
>>> fan.update_state()
<UpdateState.Idle: 'idle'>
>>> fan.status()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    fan.status()
  File "/home/corpse/.local/lib/python3.8/site-packages/miio/fan.py", line 421, in status
    values = self.get_properties(properties, max_properties=_props_per_request)
  File "/home/corpse/.local/lib/python3.8/site-packages/miio/device.py", line 232, in get_properties
    values.extend(self.send(property_getter, _props[:max_properties]))
  File "/home/corpse/.local/lib/python3.8/site-packages/miio/device.py", line 146, in send
    return self._protocol.send(
  File "/home/corpse/.local/lib/python3.8/site-packages/miio/miioprotocol.py", line 213, in send
    self._handle_error(payload["error"])
  File "/home/corpse/.local/lib/python3.8/site-packages/miio/miioprotocol.py", line 273, in _handle_error
    raise DeviceError(error)
miio.exceptions.DeviceError: {'code': -9999, 'message': 'user ack timeout'}

Home Assitant get error state after trying to call get_properties method with list of parameters:

{'id': 3, 'method': 'get_prop', 'params': ['power', 'aqi', 'average_aqi', 'humidity', 'temp_dec', 'mode', 'favorite_level', 'filter1_life', 'f1_hour_used', 'use_time', 'motor1_speed', 'motor2_speed', 'purify_volume', 'f1_hour', 'led']}

Itā€™s interesting that I can get list with one of parameter from python using python-miio but I canā€™t get multiply parameters:

>>> fan.get_properties(['humidity'])
[43]
>>> fan.get_properties(['power'])
['off']
>>> fan.get_properties(['power','humidity'])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    fan.get_properties(['power','humidity'])
  File "/opt/ha/lib/python3.7/site-packages/miio/device.py", line 232, in get_properties
    values.extend(self.send(property_getter, _props[:max_properties]))
  File "/opt/ha/lib/python3.7/site-packages/miio/device.py", line 147, in send
    command, parameters, retry_count, extra_parameters=extra_parameters
  File "/opt/ha/lib/python3.7/site-packages/miio/miioprotocol.py", line 203, in send
    self._handle_error(payload["error"])
  File "/opt/ha/lib/python3.7/site-packages/miio/miioprotocol.py", line 263, in _handle_error
    raise DeviceError(error)
miio.exceptions.DeviceError: {'code': -9999, 'message': 'user ack timeout'}

Does anybody knows how to fix it?

If you use the correct device class (not Fan) and pass the correct model (zhimi.humidifier.ca1) the proper implementation is used which requests a single property per get_prop call:

Could you provide your HA configuration of the component? Did you set the correct model?

Oh! Thank you very much! But today I made my own ugly fix in code of device.py:

 215     def get_properties(
 216         self, properties, *, property_getter="get_prop", max_properties=None
 217     ):
 218         """Request properties in slices based on given max_properties.
 219 
 220         This is necessary as some devices have limitation on how many
 221         properties can be queried at once.
 222 
 223         If `max_properties` is None, all properties are requested at once.
 224 
 225         :param list properties: List of properties to query from the device.
 226         :param int max_properties: Number of properties that can be requested at once.
 227         :return List of property values.
 228         """
 229         _props = properties.copy()
 230         values = []
 231         for prop in _props:
 232             values.append(self.send(property_getter, [prop])[0])
 233 #        while _props:
 234 #            values.extend(self.send(property_getter, _props[:max_properties]))
 235 #            if max_properties is None:
 236 #                break
 237 #
 238 #            _props[:] = _props[max_properties:]

Everything works now, but your method is much better!

Can Humidifer ver1 be connected with HA just with wifi or do I need any of Xiaomi gateways?

Which product / variant do you mean in detail?

xiaomi evaporative humidifier 1, the one which looks like mini fridge

Do i really need the gateway to use this component? Because i dont have one, and dont want to buy one.

Itā€™s a WiFi device. No gateway required.

I downloaded xiaomi_miio_airpurifier directory from git and copied it into custom_components, added this below to my configuration.yaml and all I get is humidifier turns off and buzzer sounding every 10 seconds after HA is restarted. Canā€™t controll it in any way.

fan:
  - platform: xiaomi_miio_airpurifier
    name: smartmi
    host: 192.168.10.200
    token: bb1bd61f89630e0b05d564cfd1ffcccb
    model: zhimi.humidifier.v1

sma

I also dont get where this long entity name come from in autosuggestion, because I named it just smartmi.
sma2

If you name your device

the entity_id is fan.smartmi. If you choose another name the entity_id changes too. :stuck_out_tongue:

I know. I just thought that autosuggestion will follow that name change. This doesnā€™t matter anyway, because as You see on first pic humidifier cant be contacted. Only thing that happens after setting that integration is stopping humidifer which was tuner on manually via buttons/mi app and buzzer sound every 10-15 seconds, something like an error informing. Token is OK, extracted from mi app.

Hello. Iā€™m experiencing unavailability of the Xiaomi Humidifier on the periodical basis. The device is connected in HA for 5-10min than goes offline for couple of minutes, Iā€™m using the official integration:
- platform: xiaomi_miio

If Iā€™m pinging the device, no dropped packages.
Does anybody experience something similar?
I didnā€™t try the HACS integration as I get an error:

Platform error fan.xiaomi_miio_airpurifier - cannot import name ā€˜FanMiotā€™ from ā€˜miioā€™ (/usr/local/lib/python3.8/site-packages/miio/init.py)

when checking the configuration.
Iā€™m using the latest version of the HA.

You could enable the debug output of the official component and the underlying library:

logger:
  default: warn
  logs:
    homeassistant.components.xiaomi_miio: debug
    miio: debug

Check your home-assistant.log to provide the traffic between HA and your humidifier here. Which model do you own?

I have Smartmi Air Humidifier CB1 zhimi.humidifier.cb1

Here is part of the log:

2020-12-11 08:45:39 WARNING (MainThread) [homeassistant.helpers.entity] Update of fan.air_humidifier is taking over 10 seconds
2020-12-11 08:45:40 DEBUG (SyncWorker_11) [miio.miioprotocol] Unable to discover a device at address 192.168.200.212
2020-12-11 08:45:40 ERROR (MainThread) [homeassistant.components.xiaomi_miio.fan] Got exception while fetching the state: Unable to discover the device 192.168.200.212
2020-12-11 08:46:04 DEBUG (SyncWorker_8) [miio.miioprotocol] Unable to discover a device at address 192.168.200.212
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.protocol] Unable to decrypt, returning raw bytes: b''
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] Got a response: Container: 
    data = Container: 
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container: 
        data = b'!1\x00 \x00\x00\x00\x00\x12\xca"p\x00\x03~i' (total 16)
        value = Container: 
            length = 32
            unknown = 0
            device_id = unhexlify('12ca2270')
            ts = 1970-01-03 15:36:09
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' (total 16)
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] Discovered 12ca2270 with ts: 1970-01-03 15:36:09, token: b'00000000000000000000000000000000'
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 >>: {'id': 228, 'method': 'get_prop', 'params': ['power']}
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 (ts: 1970-01-03 15:36:09, id: 228) << {'result': ['on'], 'id': 228}
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 >>: {'id': 229, 'method': 'get_prop', 'params': ['mode']}
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 (ts: 1970-01-03 15:36:10, id: 229) << {'result': ['auto'], 'id': 229}
2020-12-11 08:46:29 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 >>: {'id': 230, 'method': 'get_prop', 'params': ['humidity']}
2020-12-11 08:46:30 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 (ts: 1970-01-03 15:36:10, id: 230) << {'result': [34], 'id': 230}
2020-12-11 08:46:30 DEBUG (SyncWorker_3) [miio.miioprotocol] 192.168.200.212:54321 >>: {'id': 231, 'method': 'get_prop', 'params': ['buzzer']}
2020-12-11 08:46:35 DEBUG (SyncWorker_3) [miio.miioprotocol] Retrying with incremented id, retries left: 3
2020-12-11 08:46:35 DEBUG (SyncWorker_3) [miio.protocol] Unable to decrypt, returning raw bytes: b''
2020-12-11 08:46:35 DEBUG (SyncWorker_3) [miio.miioprotocol] Got a response: Container: 

I extract the token following this instructions: https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor
Thx.

After installation of integration canā€™t find it in integrations menu.
What am I doing wrong?



Upd:
If i add info to configuration.yaml

I getting such error during checking config

Hi there,

What is the best way to add Xiaomi Mijia SCK0A45 using this component in Home Assistant?
I installed it in HACS:
Screenshot 2020-12-13 at 12.15.16
But i canā€™t see it in integrations, only to other Xiaomi components show up and they donā€™t have humidifier entity in them.
Screenshot 2020-12-13 at 12.10.40

I also tried to do it manually like this without any luck, the humidifier is not showing up:

climate:
  - platform: xiaomi_miio_airpurifier
    name: Xiaomi Air Humidifier
    host: 192.168.86.51
    token: !secret xiaomy_token

Tried reinstalling this but with no luck. The xiaomi_miio_airpurifier folder is in custom_components.
What im doing wrong? Any ideas and directions appreciated :slight_smile:
I wonder if im missing important step?

Thanks,
Alex

maybe you have error: xiaomy vs xiaomi

nah its just misspelling and i copy pasted it from secrets.yaml, so it isfineā€¦
Im getting this error with my manual configuration: