Xiaomi Mi Air Purifier 3H

Hi,

Thank you for sharing your work.

I’ve managed to add sensors for my Mi Air Purifier 3H but somehow I get value “none” for all sensors.

Here is my code:

sensor:
 - platform: template
   sensors:
     mi_air_purifier_temp:
       friendly_name: "Temperature"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'temperature') }}"
       unit_of_measurement: "°C"
       device_class: "temperature"
     mi_air_purifier_humidity:
       friendly_name: "Humidity"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'humidity') }}"
       unit_of_measurement: "%"
       device_class: "humidity"
     mi_air_purifier_air_quality_pm25:
       friendly_name: "Air quality (AQI) PM2.5"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'aqi') }}"
       unit_of_measurement: "μg/m³"
       icon_template: "mdi:weather-fog"
     mi_air_purifier_avg_air_quality_pm25:
       friendly_name: "Average air quality (AvgAQI) PM2.5"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'average_aqi') }}"
       unit_of_measurement: "μg/m³"
       icon_template: "mdi:weather-hazy"
     mi_air_purifier_use_time:
       friendly_name: "Time used"
       value_template: >
           {% macro phrase(value, name) %}
           {%- set value = value | int %}
           {%- set end = 's' if value > 1 else '' %}
           {{- '{} {}{}'.format(value, name, end) if value | int > 0 else '' }}
           {%- endmacro %}
            
           {% set weeks = (state_attr('fan.xiaomi_airpurifier_3h', 'use_time') | int / 604800) | int %}
           {% set days = ((state_attr('fan.xiaomi_airpurifier_3h', 'use_time') | int - (weeks * 604800)) / 86400) | int %}
           {% set hours = ((state_attr('fan.xiaomi_airpurifier_3h', 'use_time') | int - (weeks * 604800) - (days * 86400)) / 3600) | int %}
           {% set minutes = ((state_attr('fan.xiaomi_airpurifier_3h', 'use_time') | int - (weeks * 604800) - (days * 86400) - (hours * 3600)) / 60) | int %}
           {% set seconds = (state_attr('fan.xiaomi_airpurifier_3h', 'use_time') | int - (weeks * 604800) - (days * 86400) - (hours * 3600) - (minutes*60)) | int %}
           {{ [ phrase(weeks, 'week'), phrase(days, 'day'), phrase(hours, 'hr'), phrase(minutes, 'min'), phrase(seconds, 'sec') ] | select('!=','') | list | join(', ') }}
       icon_template: "mdi:heart-pulse"
     mi_air_purifier_filter_used:
       friendly_name: "Filter used"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'filter_hours_used') }}"
       unit_of_measurement: "hrs"
       icon_template: "mdi:heart-off"
     mi_air_purifier_filter_remaining:
       friendly_name: "Filter remaining"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'filter_life_remaining') }}"
       unit_of_measurement: "%"
       icon_template: "mdi:heart-outline"
     mi_air_purifier_purify_volume:
       friendly_name: "Purified volume"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'purify_volume') }}"
       unit_of_measurement: "m³"
       icon_template: "mdi:warehouse"
     mi_air_purifier_speed:
       friendly_name: "Motor speed"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'motor_speed') }}"
       unit_of_measurement: "rpm"
       icon_template: "mdi:speedometer"
     mi_air_purifier_led_brightness:
       friendly_name: "Led brightness"
       value_template: "{{ state_attr('fan.xiaomi_airpurifier_3h', 'led_brightness') }}"
       unit_of_measurement: "lx"
       icon_template: "mdi:brightness-5"

Any idea?

Thank you.

Check the platform definition

fan:

  • platform: xiaomi_miio
    name: “Mi Air Purifier 3H”

then you should use fan.mi_air_purifier_3H. Or you could use as name Xiaomi Airpurifier 3H

1 Like

For me, I have another issue. It show fine the values. But it only updates when i restart hassio. Not when a change happens. Why is that? Do I need something else or what could be missing?

Thank you spotting it. That was exactly the issue.

UPDATE here Lovelace: Xiaomi - Mi air purifier 3H card

Regarding availability blinking. I have the same issue and I opened corresponding ticket at core repo: https://github.com/home-assistant/core/issues/36972

Also I’ve created another thread on forum: Miio Xiaomi Air Purifier availability blinking

I’ve seen the “official” integration for the various Air Purifiers, including the 3 and 3H, but I do not use the Xiaomi Gateway.
I haven’t found a way to retrieve the “token” to be able to integrate the Air Purifier 3. Does anyone know how this can be retrieved,as the official integration seems to have all the functions I need. I just can’t seem to get the token needed to make it work.

Been trying to get my 3H to connect with home assistant without much luck. I only get “Unable to discover a device” errors in the logs.

If I run miiocli on a different computer, I can successfully pull all details from the device so the token is correct. Command I’m using:

miiocli -d airpurifiermiot --token <token> --ip <ip> status

The HA component however just says unable to discover device, configuration below.

- platform: xiaomi_miio
  host: <my ip address>
  token: <my token>
  model: zhimi.airpurifier.mb3
  name: Xiaomi Air Purifier 3H One

If I go into portainer and run the exact same miiocli command from above from the HA container, a python exception is thrown

INFO:miio.cli:Debug mode active
DEBUG:miio.miioprotocol:Unable to discover a device at address <ip address>
DEBUG:miio.click_common:Exception: Unable to discover the device <ip address>
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 59, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 280, in wrap
    kwargs["result"] = func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 245, in command_callback
    return miio_command.call(miio_device, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/click_common.py", line 193, in call
    return method(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/miio/airpurifier_miot.py", line 300, in status
    for prop in self.get_properties_for_mapping()
  File "/usr/local/lib/python3.8/site-packages/miio/miot_device.py", line 29, in get_properties_for_mapping
    return self.get_properties(
  File "/usr/local/lib/python3.8/site-packages/miio/device.py", line 232, in get_properties
    values.extend(self.send(property_getter, _props[:max_properties]))
  File "/usr/local/lib/python3.8/site-packages/miio/device.py", line 146, in send
    return self._protocol.send(
  File "/usr/local/lib/python3.8/site-packages/miio/miioprotocol.py", line 160, in send
    self.send_handshake()
  File "/usr/local/lib/python3.8/site-packages/miio/miioprotocol.py", line 87, in send_handshake
    raise DeviceException("Unable to discover the device %s" % self.ip)

The miiocli version is 0.5.3 in both cases so I have no idea what is different in the HA container that causes it to fail. I can ping the purifier from the docker container so I didn’t think it was a network issue.

Hoping someone can shed light on this.

Hi,

Did you already solve this?
I’m having the same issue, I’m not able to communicate with the device through miiocli, but the Mi Home app works, I’ve extracted the token from there.

Unfortunately no I’m still stuck. Are you able to connect through miiocli on a separate machine to HA at all, or not at all?

I wasn’t able to connect at all.
In my case it was apparently because the purifier is on a different subnet.
Made a rule in my Unifi config and now it works!

I’m afraid I’m not a docker user so your issue is different than mine.
Maybe also some network rules have to be applied in your case?

Interesting, my HA instance is actually on a different subnet, when i tested using the miicli too on a different machine I was probably on the same subnet as the purifier.

I also have a unifi router + wap, mind sharing what changes you made? Thanks! I thought because I could ping there wasn’t a network issue, maybe there is!

you might need the mihack app

Or just read the complete thread, I posted links to how to acquire the token. :wink:

1 Like

Yeah sure, this is what I added to my custom config (config.gateway.json) in Unifi:

				"5010": {
					"description": "HASS",
					"destination": {
						"address": "192.168.2.0/24"
					},
					"log": "disable",
					"outbound-interface": "eth1.2",
					"protocol": "all",
					"source": {
						"address": "192.168.1.0/24"
					},
					"type": "masquerade"
				},	

Where 192.168.1.x is my normal LAN and 192.168.2.x is my VLAN.
eth1.2 is also my VLAN obviously.

Hello, a Xiaomi gateway is mandatory or we can go without ?

You can go without.

Amazing thank you, adding a masquerade rule across my subnets fixed this for me. I guess the Xiaomi for whatever reason has issues with default gateways.

Hey @mistaed you wouldn’t happen to have a bit more info on what you had to do to connect to the Xiaomi on another subnet? I run my IoT device on their own subnet but my HA is on my home subnet. I can ping the Xiaomi but can’t seem to connect.

Hi @danny-117, I first verified the token is correct by running miiocli on the same subnet as the Xiaomi.
Once that’s working, I created a masquerade rule on my router than routes between both subnets as follows:

  • Source: HA IP address
  • Protocol: Any
  • Destination: Interface of Xiaomi subnet
    I’m not sure why I needed this since the router already sits across both subnets, and routing normally works fine.