Xiaomi Air Purifier - Show all sensors and Switches in UI and HomeKit

  1. Is there an interest from your side to read the actual value at start and set the slider to that value? Or is there a difficulty to do this?
  2. I can’t fully agree with you. For me it is continuously updated, although it is a bit slow. It takes 20-30 seconds to update, but when I move the slider, the fan speed indicator follows the reality. So I think it is ok (or I misunderstood something).

Thanks all, that worked.

Now onto my next question, how do i setup the sensors independently.

This is what i use for one

sensor:
  - platform: template
    sensors:
      mi_aqi:
        friendly_name: "Upstairs Air Purifier"
        unit_of_measurement: 'AQI'
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'aqi') }}"

i cant get the second one to show separately

Hi @MickL,
Hi everybody,

Last month I’ve bought a brand new Xiaomi Mi Air Purifier 2H (European model) and since then I’m using it with your settings recommendations without any issue. It works flawlessly and I’m very happy.

The problem is my ‘configuration.yaml’ file. It is a real mess and I would like to keep it clean the more I can.
So I’m wondering if I may I use the ‘!include’ function for keep it clean, moving all the “purifier commands” stored in ‘configuration.yaml’ to a new file called ‘mi_purifier_2H.yaml’ (for instance).
In other words, I’m talking about writing a command line (inside my ‘configuration.yaml’ file) as the one below:

fan: !include mi_purifier_2H.yaml

Until now, the best I could was moving the ‘switch:’ command to a ‘switch.yaml’ file and the ‘sensor:’ command to a ‘sensor.yaml’ file.
Instead, ‘fan:’, ‘input_select:’ and ‘input_number’ commands are stored into ‘configuration.yaml’ file.

Any help?
I know I’m THE real noob…
Luca

P.S.
sorry for my poor English

Sure you can take it to a new file. :slight_smile:

In your configuration.yaml

fan: !include fans.yaml

then you create a file fans.yaml in the same directory / folder where your configuration.yaml sits.

In fans.yaml

- platform: xiaomi_miio
  host: IP_ADDRESS_OF_THE_PURIFIER
  token: YOUR_TOKEN 

This way you can later add more fans, just copy the lines and change the content. :slight_smile:

Check the documentation about splitting your config. https://www.home-assistant.io/docs/configuration/splitting_configuration/

1 Like

Hi @paddy0174

First of all, thank you!
I’ve tried following your suggestion but it doesn’t work…
I’ve used the !include function and I’ve put all the ‘platform:’, ‘sensor:’, ‘switch:’ e ‘input’ keys, that @MickL published here, inside the brand new ‘fans.yaml’ file.

The error is this:

Invalid config for [fan]: required key not provided @ data[‘platform’]. Got None. (See /config/configuration.yaml, line 70).
Invalid config for [fan]: required key not provided @ data[‘platform’]. Got None. (See /config/configuration.yaml, line 70).

What am I doing wrong?

Luca

Ah ok, I see what you’re trying to do. First of, this will not work that way. :slight_smile: You’re mixing a few things, maybe I can get them explained a bit further.

You can split your configuration.yaml in a few ways. One way is to put all configuration in different files, taking their “function” as criteria for the split.

So in configuration.yaml you have

fan: !include fans.yaml
sensor: !include sensors.yaml
switch: !include switches.yaml

Here you have to put all things in the corresponding file to split it.
Original (this is the one from the first post)

# configuration.yaml
fan:
  # Xiaomi Air Purifier 2S
  - platform: xiaomi_miio
    host: IP
    token: TOKEN
    name: "Xiaomi Air Purifier 2S"
    
sensor:
  # Xiaomi Air Purifier 2S
  - platform: template
    sensors:
      xiaomi_airpurifier_temp:
        friendly_name: "Temperature"
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'temperature') }}"
        unit_of_measurement: "°C"
        device_class: "temperature"
      xiaomi_airpurifier_humidity:
        friendly_name: "Humidity"
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'humidity') }}"
        unit_of_measurement: "%"
        device_class: "humidity"
      xiaomi_airpurifier_air_quality_pm25:
        friendly_name: "Air quality"
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'aqi') }}"
        unit_of_measurement: "μg/m³"
        icon_template: "mdi:weather-fog"
      xiaomi_airpurifier_speed:
        friendly_name: "Fan speed"
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'motor_speed') }}"
        unit_of_measurement: "rpm"
        icon_template: "mdi:speedometer"
      xiaomi_airpurifier_filter_remaining:
        friendly_name: "Filter remaining"
        value_template: "{{ state_attr('fan.xiaomi_miio_device', 'filter_life_remaining') }}"
        unit_of_measurement: "%"
        icon_template: "mdi:heart-outline"

switch:
  # Xiaomi Air Purifier 2S
  - platform: template
    switches:
      xiaomi_airpurifier_led:
        friendly_name: "LED"
        value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'led', true) }}"
        turn_on:
          service: xiaomi_miio.fan_set_led_on
          data:
            entity_id: fan.xiaomi_miio_device
        turn_off:
          service: xiaomi_miio.fan_set_led_off
          data:
            entity_id: fan.xiaomi_miio_device
        icon_template: "mdi:lightbulb-outline"
      xiaomi_airpurifier_child_lock:
        friendly_name: "Child lock"
        value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'child_lock', true) }}"
        turn_on:
          service: xiaomi_miio.fan_set_child_lock_on
          data:
            entity_id: fan.xiaomi_miio_device
        turn_off:
          service: xiaomi_miio.fan_set_child_lock_off
          data:
            entity_id: fan.xiaomi_miio_device
        icon_template: "mdi:lock-outline"
      xiaomi_airpurifier_buzzer:
        friendly_name: "Buzzer"
        value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'buzzer', true) }}"
        turn_on:
          service: xiaomi_miio.fan_set_buzzer_on
          data:
            entity_id: fan.xiaomi_miio_device
        turn_off:
          service: xiaomi_miio.fan_set_buzzer_off
          data:
            entity_id: fan.xiaomi_miio_device
        icon_template: "mdi:volume-high"
  
input_select:
  # Xiaomi Air Purifier 2S
  xiaomi_airpurifier_mode:
    name: Mode
    options:
      - Auto
      - Silent
      - Favorite
    icon: "mdi:animation-outline"

input_number:
  # Xiaomi Air Purifier 2S
  xiaomi_airpurifier_favorite_level:
    name: "Favorite level"
    initial: 0
    min: 0
    max: 14
    step: 1
    icon: "mdi:weather-windy"

becomes split into five files, as there are:

# configuration.yaml
fan: !include fans.yaml
sensor: !include sensors.yaml
switch: !include switches.yaml

and

# fans.yaml
# Xiaomi Air Purifier 2S
- platform: xiaomi_miio
  host: IP
  token: TOKEN
  name: "Xiaomi Air Purifier 2S"

and

# sensors.yaml
# Xiaomi Air Purifier 2S
- platform: template
  sensors:
    xiaomi_airpurifier_temp:
      friendly_name: "Temperature"
      value_template: "{{ state_attr('fan.xiaomi_miio_device', 'temperature') }}"
      unit_of_measurement: "°C"
      device_class: "temperature"
    xiaomi_airpurifier_humidity:
      friendly_name: "Humidity"
      value_template: "{{ state_attr('fan.xiaomi_miio_device', 'humidity') }}"
      unit_of_measurement: "%"
      device_class: "humidity"
    xiaomi_airpurifier_air_quality_pm25:
      friendly_name: "Air quality"
      value_template: "{{ state_attr('fan.xiaomi_miio_device', 'aqi') }}"
      unit_of_measurement: "μg/m³"
      icon_template: "mdi:weather-fog"
    xiaomi_airpurifier_speed:
      friendly_name: "Fan speed"
      value_template: "{{ state_attr('fan.xiaomi_miio_device', 'motor_speed') }}"
      unit_of_measurement: "rpm"
      icon_template: "mdi:speedometer"
    xiaomi_airpurifier_filter_remaining:
      friendly_name: "Filter remaining"
      value_template: "{{ state_attr('fan.xiaomi_miio_device', 'filter_life_remaining') }}"
      unit_of_measurement: "%"
      icon_template: "mdi:heart-outline"

and

# switches.yaml
# Xiaomi Air Purifier 2S
- platform: template
  switches:
    xiaomi_airpurifier_led:
      friendly_name: "LED"
      value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'led', true) }}"
      turn_on:
        service: xiaomi_miio.fan_set_led_on
        data:
          entity_id: fan.xiaomi_miio_device
      turn_off:
        service: xiaomi_miio.fan_set_led_off
        data:
          entity_id: fan.xiaomi_miio_device
      icon_template: "mdi:lightbulb-outline"
    xiaomi_airpurifier_child_lock:
      friendly_name: "Child lock"
      value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'child_lock', true) }}"
      turn_on:
        service: xiaomi_miio.fan_set_child_lock_on
        data:
          entity_id: fan.xiaomi_miio_device
      turn_off:
        service: xiaomi_miio.fan_set_child_lock_off
        data:
          entity_id: fan.xiaomi_miio_device
      icon_template: "mdi:lock-outline"
    xiaomi_airpurifier_buzzer:
      friendly_name: "Buzzer"
      value_template: "{{ is_state_attr('fan.xiaomi_miio_device', 'buzzer', true) }}"
      turn_on:
        service: xiaomi_miio.fan_set_buzzer_on
        data:
          entity_id: fan.xiaomi_miio_device
      turn_off:
        service: xiaomi_miio.fan_set_buzzer_off
        data:
          entity_id: fan.xiaomi_miio_device
      icon_template: "mdi:volume-high"

and so on for all the other files like input_select and input_number. You have to include each file with the line in configuration.yaml and put the corresponding part into a seperate file.

That was the way to split the config up, I already gave the link to the documentation.

But there is another way to get what you want and personally I find it the better one. HA offers another solution for such things and that is packages. Actually there is another one (appdaemon apps), but we do not take that one into account here.

So, packages. :slight_smile: Check the documentation here. With packages you can include all different kind of things like sensors, switches and so on into one neat file. The idea behind packages is, to split configuration not by component like sensor or switch, rather packages allow to split by “subject” like air_purifier_package.yaml and alarms_package.yaml or bedroom_package.yaml.

I’ll put things together as a package in the next days, if you want to wait, I’ll happily post it here. :slight_smile:

2 Likes

Thank you @paddy0174 for your precious time!
Your explanation is superb!

This is just the solution I’ve found some days ago, moving ‘sensor:’ and ‘switch:’ keys into the corresponding ‘sensor.yaml’ and ‘switch.yaml’ files.
But those ‘input_select’ and ‘input_number’ keys in the ‘configuration.yaml’ were very annoying to me and I was looking for a cleaner format.

Now I have to study the ‘packages’ function … What a challenge to me …
But I would like to try, so I’ll do my best and I’ll keep you informed.
If I lose this battle, I’ll wait for your kind helping hand…

Thank you in advance,
Luca

You’re welcome! :slight_smile:

Do it with these two as well:

# configuration.yaml
input_select: !include input_selects.yaml

and then

# input_selects.yaml
# Xiaomi Air Purifier 2S
- xiaomi_airpurifier_mode:
    name: Mode
    options:
      - Auto
      - Silent
      - Favorite
    icon: "mdi:animation-outline"

and exactly like that you do it for input_numbers (and all other things you want to split).
Btw. the best part of packages is, you can use it together with your other setup. So not to much work lost, if you later decide to change it.

If it helps, here is my configuration.yaml and as example the one file fans.yaml. :slight_smile:

# configuration.yaml
homeassistant:
  name: Dahoam
  latitude: !secret configuration_latitude
  longitude: !secret configuration_longitude
  elevation: !secret configuration_elevation
  unit_system: metric
  time_zone: Europe/Berlin
  customize: !include entities.yaml
  packages: !include_dir_named packages
api:
automation: !include automations.yaml
binary_sensor: !include binary_sensors.yaml
#climate: !include climate.yaml
config:
device_tracker: !include device_trackers.yaml
fan: !include fans.yaml
fritzbox_tools:
  host: !secret host_fritz-box
  username: !secret username_hassio
  password: !secret password_low
frontend:
  themes: !include_dir_merge_named themes
group: !include groups.yaml
hassio:
history: !include history.yaml
input_boolean: !include input_booleans.yaml
input_datetime: !include input_datetimes.yaml
input_select: !include input_selects.yaml
logbook: !include logbook.yaml
logger:
  default: warning
  #logs:
  #  custom_components.mitemp_bt: debug
lovelace: !include lovelace.yaml
media_player: !include media_players.yaml
mobile_app:
mqtt: !include mqtt.yaml
notify: !include notifications.yaml
pi_hole: !include pi_hole.yaml
recorder: !include recorder.yaml
scene: !include scenes.yaml
script: !include scripts.yaml
sensor: !include sensors.yaml
sun:
switch: !include switches.yaml
system_health:
telegram_bot: !include telegram.yaml
timer: !include timers.yaml
#tts:
#  - platform: google_translate
#    service_name: google_say
weather: !include weather.yaml
zone: !include zones.yaml
# fans.yaml
- platform: xiaomi_miio
  host: !secret host_air_purifier_2h
  token: !secret mi_home_app_token

:slight_smile: Have fun!

1 Like

Hi @paddy0174,
Before studying ‘packages:’ function, I’ve tried both of

input_select: !include input_selects.yaml
input_number: !include input_number.yaml

… but with no success … a lot of errors …
…probably something wrong with the indentation.

Then I’ve followed your suggestion and after some minutes …
Bang!!
‘packages:’ working!

Below a short piece of my ‘configuration.yaml’:

homeassistant:
  ...
  packages:
    pack_1: !include fans.yaml
#

Happy like a child …

@paddy0174,

I liked very much the remarkable clearness of your ‘configuration.yaml’ file.
So I created a packages folder and I moved there my ‘fans.yaml’ file.
According to this I’ve modified my configuration to:

homeassistant:
  ...
  packages: !include_dir_named packages
  ...

Everything works and I’m very satisfied.

Now, if you don’t mind, I would ask you another question.
If I would buy a new Mi Air Purifier for my daughters room, which is the best solution?

a) keeping the nowaday’s solution, updating ‘fans.yaml’ file as like as @MickL suggested two weeks ago. Something like the one below:

fan:
  # Xiaomi Air Purifier 2S (bedroom)
  - platform: xiaomi_miio
    host: 192.168.178.***
    token: *************************************
    name: "Air Purifier 2S (bedroom)"
  # Xiaomi Air Purifier 2S (living room)
  - platform: xiaomi_miio
    host: 192.168.178.***
    token: *************************************
    name: "Air Purifier 2S (living room)"

… followed by all the other stuff (sensor:, switch:, input_select:, input_number: etc, etc…)

b) dropping the ‘packages:’ solution and splitting all the stuff in separate files as like as your proposal:

fan: !include fans.yaml
sensor: !include sensors.yaml
switch: !include switches.yaml
input_select: !include input_selects.yaml
input_number: !include input_number.yaml

Which Is the best solution?
Luca

P.S.
I hope that my verbosity could be useful for others noob like me …

:slight_smile: See, you got it going. :slight_smile:

Unfortunately there is no “best way” with all this stuff. There is only a best way for you. Whatever you choose, it should fit your needs. You are working with this tool, make it yours. :slight_smile:

But I can tell you, how I found it fitting my needs nicely.
Above I have posted my config.yaml, where you can see, I’m putting all my devices and integrations into seperate files like fan.yaml or sensor.yaml. This is all the stuff, I can’t fit into one of my packages.

In packages I have files seperated after subjects. My router is a Fritz!Box, so I have a package that is called fritzbox_package.yaml. In there I have all things regarding this router. From sensors over switches and template_sensors to all automations. Even the handling of my phone monitor is here, as it is an automation in regard to the Fritz!Box and from the subject it fits here perfectly.

But I have some room related packages as well. My bedroom is not very smart, as I don’t like it to have a lot of electrical thingies in there. So one file for all of the stuff regarding the bedroom is enough. For my living room this wouldn’t work, as there is way to much stuff, like the Fritz!Box and the TV, and… As I said TV, the TV has it’s own file, together with my media players. Makes sense, to put all these into one file.

You get the idea. This is a system, that works well for me (finally), as I have tried a few different splitting techniques, none of them were to my liking.
There is one thing, you should take care of, before beginning to work with all this: get yourself an idea about naming or naming conventions. Think about, how you could organize this with clear names, so you will find things later. I personally write a small comment in one / or all of the files, so I can remember the way I named it in six or ten months. Helps a lot! :slight_smile:

EDIT: I forgot to answer your question clearly. :wink:
I would put the “device” info into fan.yaml (that should fit for at least 50 to 100 devices). All the necessary sensors, switches, automations go into a package air_purifier_package.yaml. For two or three devices I would leave it like that, if that grows, I would move each AirPurifier into a room based file, or if necessary to split that even more into e.g. bedroom_climate_package.yaml

1 Like

@paddy0174,

Your point of view is very interesting.
I have to think about it. And I have to study a lot.
This is just the beginning … :stuck_out_tongue_closed_eyes: :crazy_face:

Thank you again,
Luca

1 Like

Hello Iiuk4friends
How did you get the token for this purifier?
I have the same version (Sweden), but im not able to get the token. Please help if you can.
/Jerry

1 Like

Hi @KePeSWE,
I’m on iOS and I’ve followed this guide on Github:
Maxmudjon Github page
You can find here a useful guide also if you are an Android user…

Let me know If I can help you in some other ways

Oki, thanks. I will check that out and get back to you how it goes.

1 Like

Hi, i followed that guide abou the token. But i cant find that line in the textfile and im not able to connect to my air purifier either with this version of app. :frowning:
/Jerry

Hi @KePeSWE,
Assuming that you are an iOS user, can you tell me more precisely at which point you are stuck?
For you convenience, I’ve written the guide here below, using numbers at every step (instead of bullets).

1) Setup your iOS device with the Mi Home app
2) Create an unencrypted backup of your iOS device on your computer using iTunes. In case you are unable to disable encryption you probably have a profile preventing this that enforces certain security policies (like work related accounts). Delete these profiles or use another iOS device to continu.
3) Install iBackup Viewer from here (another tool that was suggested can be found here).
4) Navigate to your BACKUPS and find the name of your iOS device in the list. Open this backup by clicking the triangle in front of it and then click on raw data.
5) Sort the view by name and find the folder com.xiaomi.mihome and highlight it (it’s somewhere at the end). After highlighting it click on the cockwheel above the results and select “Save selected files” from here and choose a location to save the files.
6) Navigate to the com.xiaomi.mihome folder which you just saved somewhere and inside this folder navigate to the /Documents/ subfolder. In this folder there is a file named _mihome.sqlite where your userid is specific for your account.
7) Open this file with a SQLite browser (for instance http://sqlitebrowser.org/)
8) Execute the query “select ZTOKEN from ZDEVICE where ZLOCALIP is ‘192.168.0.1’” where you replace the IP address with the IP address of the Mi Home device you want to get the token from. It will show you the 32 character device token for your Mi Home device.
9) The latest Mi Home app store the tokens encrypted into a 96 character key and require an extra step to decode this into the actual token. Visit this website and enter the details as shown below: ** Input type: text

  • Input text (hex): your 96 character key*
  • Selectbox Plaintext / Hex: Hex*
  • Function: AES*
  • Mode: ECB*
  • Key (hex): 00000000000000000000000000000000*
  • Selectbox Plaintext / Hex: Hex*

10) Hit the decrypt button. Your token are the first two lines of the right block of code. These two lines should contain a token of 32 characters and should be the correct token for your device.
11) If this tutorial did not work for you, here is another that might work.

I don’t own an iOs device, but if I may suggest to ask a friend for an Android phone? I did the Android process to get the token, and it is done in around ten minutes - tops. Maybe a freind can lend you his Android phone to setup the connection and receive the token. Afterwards the phone is not needed anymore, and you can safely uninstall the MiHomeApp and give the phone back… :slight_smile:

Sorry, can’t be of more help here, but maybe this helps. :slight_smile:

Hi. Nope, im a android user.
I installed the APK like the guide you linked. I get stuck when i try to connect to the purifier.

1 Like

I can try to use an other android phone that im not using to try this out, mayby that will work.

1 Like