Lovelace: Xiaomi - Mi air purifier 3H card

EDIT: I posted about an issue where I implemented this new card for two air purifiers, one 3H and one 2S, but changing the favorite level of one also changed the favorite level of the other, and after hours fiddling around still couldn’t solve the issue. But just as I had posted I realized what the problem was, that the script needed to specify the entity ID.

So for anyone else who is looking to implement this for multiple Air Purifiers, this is what I had to do to make it work for a 3H and a 2S version.

  • Modify the script for favorite level up/down to specify the entity ID
  • Remove the code related to fan mode from the configuration for the 2S variant
  • Modify the binary_sensors to use 'auto', 'silent' and 'favorite' for the attribute checks instead of 0,1 and 2. Otherwise the is_state_attr always returned false for some reason.

I have also made a different variant of the cards. I will clean up a few small things and then post the code here in a day or two, in case others also struggle with same.

1 Like

Here is my variant where I have removed some sensors and the switches (LED, buzzer etc) I dont use, with a picture that works on both dark and light theme. Two air purifiers, one version 3H (Bedroom) and one version 2S (Living Room).

configuration.yaml

#################################################################################################
# Xiaomi Air Purifiers, Bedroom 3H, Living Room 2S
#################################################################################################
  - platform: xiaomi_miio             # Mi Air Purifier 2S
    name: "Living Room Air Purifier"  # entity fan.living_room_air_purifier
    host: XXX.XXX.XXX.XXX
    token: xxxxxxxxxxxxxxxxxxxxxxxx
    model: zhimi.airpurifier.m1

  - platform: xiaomi_miio
    name: "Bedroom Air Purifier"      # Mi Air Purifier 3H
    host: YYY.YYY.YYY.YYY             # entity fan.bedroom_air_purifier
    token: yyyyyyyyyyyyyyyyyyyyyyyy
    model: zhimi.airpurifier.mb3

sensor:
  #===================================#
  #  Mi Air Purifier Living Room (2S) #
  #===================================#
  - platform: template
    sensors:
      living_room_air_purifier_temp:
        friendly_name: "Temperature"
        value_template: "{{ state_attr('fan.living_room_air_purifier', 'temperature') }}"
        unit_of_measurement: "°C"
        device_class: "temperature"
      living_room_air_purifier_humidity:
        friendly_name: "Humidity"
        value_template: "{{ state_attr('fan.living_room_air_purifier', 'humidity') }}"
        unit_of_measurement: "%"
        device_class: "humidity"
      living_room_air_purifier_air_quality_pm25:
        friendly_name: "Air Quality Index (AQI) PM2.5 (μg/m³)"
#        value_template: "{{ state_attr('fan.living_room_air_purifier', 'aqi') }}"
        value_template: >-
          {% if state_attr('fan.living_room_air_purifier', 'aqi') == None %}
            {{ 0 }}
          {% else %}
            {{ state_attr('fan.living_room_air_purifier', 'aqi') }}
          {% endif %}
        unit_of_measurement: " "
#        unit_of_measurement: "μg/m³"
        icon_template: "mdi:air-purifier"
      living_room_air_purifier_favorite_level:
        friendly_name: "Favorite Level"
        value_template: "{{ state_attr('fan.living_room_air_purifier', 'favorite_level') }}"
      living_room_air_purifier_avg_air_quality_pm25:
        friendly_name: "Average air quality (AvgAQI) PM2.5"
        value_template: "{{ state_attr('fan.living_room_air_purifier', 'average_aqi') }}"
        unit_of_measurement: "μg/m³"
        icon_template: "mdi:weather-hazy"
      living_room_air_purifier_filter_remaining:
        friendly_name: "Filter remaining"
        value_template: "{{ state_attr('fan.living_room_air_purifier', 'filter_life_remaining') }}"
        unit_of_measurement: "%"
        icon_template: "mdi:air-filter"
  #================================#
  #  Mi Air Purifier Bedroom (3H)  #
  #================================#
  - platform: template
    sensors:
      bedroom_air_purifier_temp:
        friendly_name: "Temperature"
        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'temperature') }}"
        unit_of_measurement: "°C"
        device_class: "temperature"
      bedroom_air_purifier_humidity:
        friendly_name: "Humidity"
        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'humidity') }}"
        unit_of_measurement: "%"
        device_class: "humidity"
      bedroom_air_purifier_air_quality_pm25:
        friendly_name: "Air Quality Index (AQI) PM2.5 (μg/m³)"
#        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'aqi') }}"
        value_template: >-
          {% if state_attr('fan.bedroom_air_purifier', 'aqi') == None %}
            {{ 0 }}
          {% else %}
            {{ state_attr('fan.bedroom_air_purifier', 'aqi') }}
          {% endif %}
        unit_of_measurement: " "
#        unit_of_measurement: "μg/m³"
        icon_template: "mdi:air-purifier"
      bedroom_air_purifier_favorite_level:
        friendly_name: "Favorite Level"
        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'favorite_level') }}"
      bedroom_air_purifier_avg_air_quality_pm25:
        friendly_name: "Average air quality (AvgAQI) PM2.5"
        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'average_aqi') }}"
        unit_of_measurement: "μg/m³"
        icon_template: "mdi:weather-hazy"
      bedroom_air_purifier_filter_remaining:
        friendly_name: "Filter remaining"
        value_template: "{{ state_attr('fan.bedroom_air_purifier', 'filter_life_remaining') }}"
        unit_of_measurement: "%"
        icon_template: "mdi:air-filter"

binary_sensor:
  #===================================#
  #  Mi Air Purifier Living Room (2S) #
  #===================================#
  - platform: template
    sensors:
      living_room_air_purifier_mode_off:
        friendly_name: "Purifier Off"
        value_template: "{{ is_state('fan.living_room_air_purifier', 'off') }}"
      living_room_air_purifier_mode_auto:
        friendly_name: "Purifier Auto mode"
        value_template: "{{ is_state_attr('fan.living_room_air_purifier', 'mode', 'auto') and is_state('fan.living_room_air_purifier', 'on') }}"
      living_room_air_purifier_mode_silent:
        friendly_name: "Purifier Silent mode"
        value_template: "{{ is_state_attr('fan.living_room_air_purifier', 'mode', 'silent') and is_state('fan.living_room_air_purifier', 'on') }}"
      living_room_air_purifier_mode_favorite:
        friendly_name: "Purifier Favorite mode"
        value_template: "{{ is_state_attr('fan.living_room_air_purifier', 'mode', 'favorite') and is_state('fan.living_room_air_purifier', 'on') }}"
  #================================#
  #  Mi Air Purifier Bedroom (3H)  #
  #================================#
  - platform: template
    sensors:
      bedroom_air_purifier_mode_off:
        friendly_name: "Purifier Off"
        value_template: "{{ is_state('fan.bedroom_air_purifier', 'off') }}"
      bedroom_air_purifier_mode_auto:
        friendly_name: "Purifier Auto mode"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 0) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_silent:
        friendly_name: "Purifier Silent mode"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 1) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_favorite:
        friendly_name: "Purifier Favorite mode"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 2) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_fan:
        friendly_name: "Purifier Fan mode"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 3) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_fan_1:
        friendly_name: "Purifier Fan mode 1"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 3) and is_state_attr('fan.bedroom_air_purifier', 'fan_level', 1) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_fan_2:
        friendly_name: "Purifier Fan mode 2"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 3) and is_state_attr('fan.bedroom_air_purifier', 'fan_level', 2) and is_state('fan.bedroom_air_purifier', 'on') }}"
      bedroom_air_purifier_mode_fan_3:
        friendly_name: "Purifier Fan mode 3"
        value_template: "{{ is_state_attr('fan.bedroom_air_purifier', 'mode', 3) and is_state_attr('fan.bedroom_air_purifier', 'fan_level', 3) and is_state('fan.bedroom_air_purifier', 'on') }}"

scripts.yaml

bedroom_air_purifier_favorite_up:
  sequence:
  - service: xiaomi_miio.fan_set_favorite_level
    data:
      level: '{% if (state_attr(''fan.bedroom_air_purifier'',''favorite_level'') +
        step | int) < 14 -%} {{ state_attr(''fan.bedroom_air_purifier'', ''favorite_level'')
        + step | int }} {%- else -%} {{ 14 }} {%- endif %}'
    entity_id: fan.bedroom_air_purifier
  mode: single
bedroom_air_purifier_favorite_down:
  sequence:
  - service: xiaomi_miio.fan_set_favorite_level
    data:
      level: '{% if (state_attr(''fan.bedroom_air_purifier'',''favorite_level'') -
        step | int) > 0  -%} {{ state_attr(''fan.bedroom_air_purifier'', ''favorite_level'')
        - step | int }} {%- else -%} {{ 0 }} {%- endif %}'
    entity_id: fan.bedroom_air_purifier
  mode: single
living_room_air_purifier_favorite_up:
  sequence:
  - service: xiaomi_miio.fan_set_favorite_level
    data:
      level: '{% if (state_attr(''fan.living_room_air_purifier'',''favorite_level'')
        + step | int) < 14 -%} {{ state_attr(''fan.living_room_air_purifier'', ''favorite_level'')
        + step | int }} {%- else -%} {{ 14 }} {%- endif %}'
    entity_id: fan.living_room_air_purifier
  mode: single
living_room_air_purifier_favorite_down:
  sequence:
  - service: xiaomi_miio.fan_set_favorite_level
    data:
      level: '{% if (state_attr(''fan.living_room_air_purifier'',''favorite_level'')
        - step | int) > 0  -%} {{ state_attr(''fan.living_room_air_purifier'', ''favorite_level'')
        - step | int }} {%- else -%} {{ 0 }} {%- endif %}'
    entity_id: fan.living_room_air_purifier
  mode: single

3H (Bedroom) Lovelace card

type: picture-elements
title: Bedroom Air-Purifier
image: local/mi_air_purifier_big_circle_2.png
elements:
  - type: state-icon
    entity: binary_sensor.bedroom_air_purifier_mode_off
    title: 'Off'
    icon: 'mdi:power-standby'
    tap_action:
      action: call-service
      service: fan.turn_off
      service_data:
        entity_id: fan.bedroom_air_purifier
    style:
      top: 10%
      left: 20%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(128, 128, 128)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: fan.bedroom_air_purifier
    title: More Info
    icon: 'mdi:dots-vertical'
    tap_action:
      action: more-info
    style:
      top: 10%
      left: 82%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(128, 128, 128)'
      '--paper-item-icon-active-color': 'rgb(128, 128, 128)'
  - type: conditional
    conditions:
      - entity: binary_sensor.bedroom_air_purifier_mode_off
        state: 'off'
    elements:
      - type: state-label
        entity: sensor.bedroom_air_purifier_air_quality_pm25
        title: PM2.5
        tap_action:
          action: more-info
        style:
          top: 18%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 400%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
      - type: state-label
        entity: sensor.bedroom_air_purifier_temp
        title: Temperature
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 42%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
      - type: state-label
        entity: sensor.bedroom_air_purifier_humidity
        title: Humidity
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 58%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
  - type: conditional
    conditions:
      - entity: binary_sensor.bedroom_air_purifier_mode_off
        state: 'on'
    elements:
      - type: state-label
        entity: sensor.bedroom_air_purifier_air_quality_pm25
        title: PM2.5
        tap_action:
          action: more-info
        style:
          top: 18%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 400%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
      - type: state-label
        entity: sensor.bedroom_air_purifier_temp
        title: Temperature
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 42%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
      - type: state-label
        entity: sensor.bedroom_air_purifier_humidity
        title: Humidity
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 58%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
  - type: state-icon
    entity: binary_sensor.bedroom_air_purifier_mode_auto
    title: Auto
    icon: 'mdi:autorenew'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.bedroom_air_purifier
        speed: Auto
    style:
      top: 50%
      left: 37%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: binary_sensor.bedroom_air_purifier_mode_silent
    title: Silent
    icon: 'mdi:power-sleep'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.bedroom_air_purifier
        speed: Silent
    style:
      top: 50%
      left: 46%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: binary_sensor.bedroom_air_purifier_mode_fan
    title: Fan
    icon: 'mdi:fan'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.bedroom_air_purifier
        speed: Fan
    style:
      top: 50%
      left: 54%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: binary_sensor.bedroom_air_purifier_mode_favorite
    title: Favorite
    icon: 'mdi:heart'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.bedroom_air_purifier
        speed: Favorite
    style:
      top: 50%
      left: 63%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: conditional
    conditions:
      - entity: binary_sensor.bedroom_air_purifier_mode_fan
        state: 'on'
    elements:
      - type: state-icon
        entity: binary_sensor.bedroom_air_purifier_mode_fan_1
        title: Fan level 1
        icon: 'mdi:fan-speed-1'
        tap_action:
          action: call-service
          service: xiaomi_miio.fan_set_fan_level
          service_data:
            entity_id: fan.bedroom_air_purifier
            level: 1
        style:
          top: 65%
          left: 42%
          transform: 'translate(-50%, 0)'
          '--paper-item-icon-color': 'rgb(192, 192, 192)'
          '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
      - type: state-icon
        entity: binary_sensor.bedroom_air_purifier_mode_fan_2
        title: Fan level 2
        icon: 'mdi:fan-speed-2'
        tap_action:
          action: call-service
          service: xiaomi_miio.fan_set_fan_level
          service_data:
            entity_id: fan.bedroom_air_purifier
            level: 2
        style:
          top: 65%
          left: 50%
          transform: 'translate(-50%, 0)'
          '--paper-item-icon-color': 'rgb(192, 192, 192)'
          '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
      - type: state-icon
        entity: binary_sensor.bedroom_air_purifier_mode_fan_3
        title: Fan level 3
        icon: 'mdi:fan-speed-3'
        tap_action:
          action: call-service
          service: xiaomi_miio.fan_set_fan_level
          service_data:
            entity_id: fan.bedroom_air_purifier
            level: 3
        style:
          top: 65%
          left: 58%
          transform: 'translate(-50%, 0)'
          '--paper-item-icon-color': 'rgb(192, 192, 192)'
          '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: conditional
    conditions:
      - entity: binary_sensor.bedroom_air_purifier_mode_favorite
        state: 'on'
    elements:
      - type: state-label
        entity: sensor.bedroom_air_purifier_favorite_level
        title: Favorite level
        tap_action:
          action: none
        style:
          top: 67%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 200%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255, 128, 0)'
      - type: icon
        icon: 'mdi:plus'
        title: Favorite level +
        tap_action:
          action: call-service
          service: script.bedroom_air_purifier_favorite_up
          service_data:
            entity_id: fan.bedroom_air_purifier
            step: 1
        style:
          top: 69%
          left: 60%
          min-width: 40px
          min-height: 40px
          transform: 'translate(-50%, 0)'
          color: 'rgb(192, 192, 192)'
          color_off: 'rgb(255, 128, 0)'
      - type: icon
        icon: 'mdi:minus'
        title: Favorite level -
        tap_action:
          action: call-service
          service: script.bedroom_air_purifier_favorite_down
          service_data:
            entity_id: fan.bedroom_air_purifier
            step: 1
        style:
          top: 69%
          left: 44%
          min-width: 40px
          min-height: 40px
          transform: 'translate(-50%, 0)'
          color: 'rgb(192, 192, 192)'
          color_off: 'rgb(255, 128, 0)'

2S (Living Room) Lovelace card

type: picture-elements
title: Living Room Air-Purifier
image: local/mi_air_purifier_big_circle_2.png
elements:
  - type: state-icon
    entity: binary_sensor.living_room_air_purifier_mode_off
    title: 'Off'
    icon: 'mdi:power-standby'
    tap_action:
      action: call-service
      service: fan.turn_off
      service_data:
        entity_id: fan.living_room_air_purifier
    style:
      top: 10%
      left: 20%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(128, 128, 128)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: fan.living_room_air_purifier
    title: More Info
    icon: 'mdi:dots-vertical'
    tap_action:
      action: more-info
    style:
      top: 10%
      left: 82%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(128, 128, 128)'
      '--paper-item-icon-active-color': 'rgb(128, 128, 128)'
  - type: conditional
    conditions:
      - entity: binary_sensor.living_room_air_purifier_mode_off
        state: 'off'
    elements:
      - type: state-label
        entity: sensor.living_room_air_purifier_air_quality_pm25
        title: PM2.5
        tap_action:
          action: more-info
        style:
          top: 18%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 400%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
      - type: state-label
        entity: sensor.living_room_air_purifier_temp
        title: Temperature
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 42%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
      - type: state-label
        entity: sensor.living_room_air_purifier_humidity
        title: Humidity
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 58%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 110%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255,255,255)'
  - type: conditional
    conditions:
      - entity: binary_sensor.living_room_air_purifier_mode_off
        state: 'on'
    elements:
      - type: state-label
        entity: sensor.living_room_air_purifier_air_quality_pm25
        title: PM2.5
        tap_action:
          action: more-info
        style:
          top: 18%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 400%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
      - type: state-label
        entity: sensor.living_room_air_purifier_temp
        title: Temperature
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 42%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 100%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
      - type: state-label
        entity: sensor.living_room_air_purifier_humidity
        title: Humidity
        tap_action:
          action: more-info
        style:
          top: 36%
          left: 58%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 100%
          transform: 'translate(-50%, 0)'
          color: 'rgb(128, 128, 128)'
  - type: state-icon
    entity: binary_sensor.living_room_air_purifier_mode_auto
    title: Auto
    icon: 'mdi:autorenew'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.living_room_air_purifier
        speed: Auto
    style:
      top: 50%
      left: 37%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: binary_sensor.living_room_air_purifier_mode_silent
    title: Silent
    icon: 'mdi:power-sleep'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.living_room_air_purifier
        speed: Silent
    style:
      top: 50%
      left: 50%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: state-icon
    entity: binary_sensor.living_room_air_purifier_mode_favorite
    title: Favorite
    icon: 'mdi:heart'
    tap_action:
      action: call-service
      service: fan.set_speed
      service_data:
        entity_id: fan.living_room_air_purifier
        speed: Favorite
    style:
      top: 50%
      left: 63%
      transform: 'translate(-50%, 0)'
      '--paper-item-icon-color': 'rgb(192, 192, 192)'
      '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
  - type: conditional
    conditions:
      - entity: binary_sensor.living_room_air_purifier_mode_favorite
        state: 'on'
    elements:
      - type: state-label
        entity: sensor.living_room_air_purifier_favorite_level
        title: Favorite level
        tap_action:
          action: none
        style:
          top: 67%
          left: 50%
          min-width: 40px
          min-height: 40px
          text-align: center
          font-size: 200%
          transform: 'translate(-50%, 0)'
          color: 'rgb(255, 128, 0)'
      - type: icon
        icon: 'mdi:plus'
        title: Favorite level +
        tap_action:
          action: call-service
          service: script.living_room_air_purifier_favorite_up
          service_data:
            entity_id: fan.living_room_air_purifier
            step: 1
        style:
          top: 69%
          left: 60%
          min-width: 40px
          min-height: 40px
          transform: 'translate(-50%, 0)'
          color: 'rgb(192, 192, 192)'
          color_off: 'rgb(255, 128, 0)'
      - type: icon
        icon: 'mdi:minus'
        title: Favorite level -
        tap_action:
          action: call-service
          service: script.living_room_air_purifier_favorite_down
          service_data:
            entity_id: fan.living_room_air_purifier
            step: 1
        style:
          top: 69%
          left: 44%
          min-width: 40px
          min-height: 40px
          transform: 'translate(-50%, 0)'
          color: 'rgb(192, 192, 192)'
          color_off: 'rgb(255, 128, 0)'

Picture to be put in config/www

6 Likes

I must admit I have wanted something even simpler as of the lovelace card, as the rest of my dashboard is not using images, the picture of the purifier kind of stands out like a sore thumb.

The picture below is simply a mock-up as I am still contemplating if I need any other elements. I have intentionally removed temperature and humidity readings, as I have collected those with readings of other rooms elsewhere.

AP

2 Likes

@bbrandal great work.

@bjorn.sivertsen. I am also thinking on something simpler like the card for climate. Could you also post the code here?

Hi schilea, no code yet, as I am only in the idea-phase.

I am unsure, if there is a card-type that allows you setup elements the way you did, without having a picture background.

A quick workaround could be to use a transparent picture. But I guess the ideal thing would be to create a custom card.

For sure there is a need for a custom-card to be created. Picture card is not allowing this.

Hi schilea, I tested it and it actually does. If I use a transparent .png picture, I get an empty canvas I can model on top. This is an extremely dirty (and ugly) transformation I did of your card.

I used this picture that is considered transparent by HA.

AP-Card-Background

And finally this is the lovelace code, I use a different entity-name for the purifier. Please keep that in mind.

type: 'custom:stack-in-card'
cards:
  - type: vertical-stack
    cards:
      - type: picture-elements
        image: local/AP-Card-Background.png
        title: Bedroom Air Purifier
        elements:
          - type: state-icon
            entity: binary_sensor.mi_air_purifier_mode_off
            title: 'Off'
            icon: 'mdi:power-standby'
            tap_action:
              action: call-service
              service: fan.turn_off
              service_data:
                entity_id: fan.xiaomi_miio_device
            style:
              top: 8%
              left: 6%
              min-width: 40px
              min-height: 40px
              transform: 'translate(-50%, 0)'
              '--paper-item-icon-color': 'rgb(128, 128, 128)'
              '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: conditional
            conditions:
              - entity: binary_sensor.mi_air_purifier_mode_off
                state: 'off'
            elements:
              - type: state-label
                entity: sensor.mi_air_purifier_air_quality_pm25
                title: PM2.5
                tap_action:
                  action: more-info
                suffix: ug/m3
                style:
                  top: 2%
                  left: 73.5%
                  min-width: 40px
                  min-height: 40px
                  text-align: center
                  font-size: 300%
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(255,255,255)'
          - type: conditional
            conditions:
              - entity: binary_sensor.mi_air_purifier_mode_off
                state: 'on'
            elements:
              - type: state-label
                entity: sensor.mi_air_purifier_air_quality_pm25
                title: PM2.5
                tap_action:
                  action: more-info
                style:
                  top: 19%
                  left: 68.5%
                  min-width: 40px
                  min-height: 40px
                  text-align: center
                  font-size: 400%
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(128, 128, 128)'
              - type: state-label
                entity: sensor.mi_air_purifier_temp
                title: Temperature
                tap_action:
                  action: more-info
                style:
                  top: 32%
                  left: 65%
                  min-width: 40px
                  min-height: 40px
                  text-align: center
                  font-size: 75%
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(128, 128, 128)'
          - type: state-icon
            entity: binary_sensor.mi_air_purifier_mode_auto
            title: Auto
            icon: 'mdi:autorenew'
            tap_action:
              action: call-service
              service: fan.set_speed
              service_data:
                entity_id: fan.xiaomi_miio_device
                speed: Auto
            style:
              top: 8%
              left: 16%
              transform: 'translate(-50%, 0)'
              '--paper-item-icon-color': 'rgb(192, 192, 192)'
              '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: state-icon
            entity: binary_sensor.mi_air_purifier_mode_silent
            title: Silent
            icon: 'mdi:power-sleep'
            tap_action:
              action: call-service
              service: fan.set_speed
              service_data:
                entity_id: fan.xiaomi_miio_device
                speed: Silent
            style:
              top: 8%
              left: 46%
              transform: 'translate(-50%, 0)'
              '--paper-item-icon-color': 'rgb(192, 192, 192)'
              '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: state-icon
            entity: binary_sensor.mi_air_purifier_mode_fan
            title: Fan
            icon: 'mdi:fan'
            tap_action:
              action: call-service
              service: fan.set_speed
              service_data:
                entity_id: fan.xiaomi_miio_device
                speed: Fan
            style:
              top: 8%
              left: 26%
              transform: 'translate(-50%, 0)'
              '--paper-item-icon-color': 'rgb(192, 192, 192)'
              '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: state-icon
            entity: binary_sensor.mi_air_purifier_mode_favorite
            title: Favorite
            icon: 'mdi:heart'
            tap_action:
              action: call-service
              service: fan.set_speed
              service_data:
                entity_id: fan.xiaomi_miio_device
                speed: Favorite
            style:
              top: 8%
              left: 36%
              transform: 'translate(-50%, 0)'
              '--paper-item-icon-color': 'rgb(192, 192, 192)'
              '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: conditional
            conditions:
              - entity: binary_sensor.mi_air_purifier_mode_fan
                state: 'on'
            elements:
              - type: state-icon
                entity: binary_sensor.mi_air_purifier_mode_fan_1
                title: Fan level 1
                icon: 'mdi:fan-speed-1'
                tap_action:
                  action: call-service
                  service: xiaomi_miio.fan_set_fan_level
                  service_data:
                    entity_id: fan.xiaomi_miio_device
                    level: 1
                style:
                  top: 64%
                  left: 11%
                  transform: 'translate(-50%, 0)'
                  '--paper-item-icon-color': 'rgb(192, 192, 192)'
                  '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
              - type: state-icon
                entity: binary_sensor.mi_air_purifier_mode_fan_2
                title: Fan level 2
                icon: 'mdi:fan-speed-2'
                tap_action:
                  action: call-service
                  service: xiaomi_miio.fan_set_fan_level
                  service_data:
                    entity_id: fan.xiaomi_miio_device
                    level: 2
                style:
                  top: 64%
                  left: 21%
                  transform: 'translate(-50%, 0)'
                  '--paper-item-icon-color': 'rgb(192, 192, 192)'
                  '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
              - type: state-icon
                entity: binary_sensor.mi_air_purifier_mode_fan_3
                title: Fan level 3
                icon: 'mdi:fan-speed-3'
                tap_action:
                  action: call-service
                  service: xiaomi_miio.fan_set_fan_level
                  service_data:
                    entity_id: fan.xiaomi_miio_device
                    level: 3
                style:
                  top: 64%
                  left: 31%
                  transform: 'translate(-50%, 0)'
                  '--paper-item-icon-color': 'rgb(192, 192, 192)'
                  '--paper-item-icon-active-color': 'rgb(255, 128, 0)'
          - type: conditional
            conditions:
              - entity: binary_sensor.mi_air_purifier_mode_favorite
                state: 'on'
            elements:
              - type: state-label
                entity: sensor.mi_air_purifier_favorite_level
                title: Favorite level
                tap_action:
                  action: none
                style:
                  top: 64%
                  left: 21%
                  min-width: 40px
                  min-height: 40px
                  text-align: center
                  font-size: 200%
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(255, 128, 0)'
              - type: icon
                icon: 'mdi:plus'
                title: Favorite level +
                tap_action:
                  action: call-service
                  service: script.favorite_up
                  service_data:
                    entity_id: fan.xiaomi_miio_device
                    step: 2
                style:
                  top: 66%
                  left: 30%
                  min-width: 40px
                  min-height: 40px
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(192, 192, 192)'
                  color_off: 'rgb(255, 128, 0)'
              - type: icon
                icon: 'mdi:minus'
                title: Favorite level -
                tap_action:
                  action: call-service
                  service: script.favorite_down
                  service_data:
                    entity_id: fan.xiaomi_miio_device
                    step: 1
                style:
                  top: 66%
                  left: 16%
                  min-width: 40px
                  min-height: 40px
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(192, 192, 192)'
                  color_off: 'rgb(255, 128, 0)'
              - type: state-label
                entity: input_select.mi_air_purifier_coverage
                title: Coverage
                tap_action:
                  action: none
                style:
                  top: 74%
                  left: 23%
                  min-width: 40px
                  min-height: 40px
                  text-align: center
                  font-size: 100%
                  transform: 'translate(-50%, 0)'
                  color: 'rgb(255, 128, 0)'
      - type: 'custom:mini-graph-card'
        entities:
          - sensor.mi_air_purifier_air_quality_pm25
        show:
          icon: false
          name: false
          state: false

Obviously, there are a lot of issues with the card, concerning placement etc., but for me it’s a good start. But a custom card hosted in a github repository, would probably be the long-term solution (when the design is chosen).

1 Like

Hi guys! Thank you for this topic, I managed to get my 3H purifier into the homeassistant thanks to it.

It seems that I have a problem with the operation modes for the purifier. They are not changing from homeassistant I really don’t understant why. Everything else seems to work.

Here is the extract from the config:

input_select:
# Mi Air Purifier 3H
  xiaomi_airpurifier_mode:
    name: Operation Modes
    options:
     - Auto
     - Silent
     - Favorite
     - Fan
    initial: Auto
    icon: mdi:animation-outline

And here is part of the card:

cards:
      - cards:
          - cards:
              - entity: sensor.mi_air_purifier_3h_air_quality_pm25
                max: 30
                min: 0
                name: AQI PM2.5
                severity:
                  green: 0
                  red: 21
                  yellow: 11
                type: gauge
            type: horizontal-stack
          - entities:
              - entity: fan.living_room_air_purifier
              - entity: switch.mi_air_purifier_3h_led
              - entity: input_select.xiaomi_airpurifier_mode
            show_header_toggle: false
            type: entities
          - card:
              entities:
                - entity: input_number.mi_air_purifier_3h_favorite_level
              type: entities
            conditions:
              - entity: input_select.mi_air_purifier_3h_mode
                state: Favorite
            type: conditional

Any help would be appreciated!

Thanks!

probably this, different name for input select

Any ideas why I get this errors:

Logger:

Got exception while fetching the state: {‘code’: -9999, ‘message’: ‘user ack timeout’}
Got exception while fetching the state: Unable to discover the device ‘ip adress’

And

DeviceException during setup of xiaomi gateway with host ‘ip adress’

They spam the logs.
Thanks

Does anyone know how to go about letting the “Air Purifier set favorite level based on PM2.5” automation only trigger if there is a need to?

This is my current code:

- id: '1234567891012'
  alias: AP02 - Air Purifier set favorite level based on PM2.5
  description: ''
  trigger:
  - minutes: /5
    platform: time_pattern
  condition:
  - condition: state
    entity_id: fan.xiaomi_miio_device
    state: 'on'
  - condition: state
    entity_id: binary_sensor.mi_air_purifier_mode_fan
    state: 'off'
  - condition: time
    after: 08:00:00
    before: '20:00:00'
  action:
  - data:
      speed: Favorite
    entity_id: fan.xiaomi_miio_device
    service: fan.set_speed
  - data:
      level: '{% if states("sensor.mi_air_purifier_air_quality_pm25") | int > 40 -%}
        10 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 30 -%}
        8 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 20 -%}
        6 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 10 -%}
        4 {%- else -%} 1 {%- endif %}'
    entity_id: fan.xiaomi_miio_device
    service: xiaomi_miio.fan_set_favorite_level
  - data:
      message: Mi Air Purifier 3H - PM2.5 = {{ states('sensor.mi_air_purifier_air_quality_pm25')
        }} μg/m³ set favorite level to {{ state_attr('fan.xiaomi_miio_device', 'favorite_level')
        }} at {{
        states('sensor.date_time') }}
    service: notify.notify
  mode: single

Good question, I was trying to solve this but no solution so far. In theory you should add a triggering condition to check the current level value against the proposed one based on pm2.5 settings.

@bjorn.sivertsen try this:

- id: '12345678910'
  alias: AP02 - Air Purifier set favorite level based on PM2.5
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.mi_air_purifier_air_quality_pm25
  condition:
  - condition: state
    entity_id: fan.mi_air_purifier_3h
    state: 'on'
  - condition: or
    conditions:
    - condition: and
      conditions:
      - condition: numeric_state
        entity_id: sensor.mi_air_purifier_air_quality_pm25
        above: '50'
      - condition: not
        conditions:
        - condition: state
          entity_id: sensor.mi_air_purifier_favorite_level
          state: '14'
    - condition: and
      conditions:
      - condition: numeric_state
        entity_id: sensor.mi_air_purifier_air_quality_pm25
        above: '35'
        below: '51'
      - condition: not
        conditions:
        - condition: state
          entity_id: sensor.mi_air_purifier_favorite_level
          state: '12'
    - condition: and
      conditions:
      - condition: numeric_state
        entity_id: sensor.mi_air_purifier_air_quality_pm25
        above: '20'
        below: '36'
      - condition: not
        conditions:
        - condition: state
          entity_id: sensor.mi_air_purifier_favorite_level
          state: '9'
    - condition: and
      conditions:
      - condition: numeric_state
        entity_id: sensor.mi_air_purifier_air_quality_pm25
        above: '5'
        below: '21'
      - condition: not
        conditions:
        - condition: state
          entity_id: sensor.mi_air_purifier_favorite_level
          state: '6'
    - condition: and
      conditions:
      - condition: numeric_state
        entity_id: sensor.mi_air_purifier_air_quality_pm25
        below: '6'
      - condition: not
        conditions:
        - condition: state
          entity_id: sensor.mi_air_purifier_favorite_level
          state: '4'
  action:
  - data:
      speed: Favorite
    entity_id: fan.mi_air_purifier_3h
    service: fan.set_speed
  - data:
      level: '{% if states("sensor.mi_air_purifier_air_quality_pm25") | int > 50 -%}
        14 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 35 -%}
        12 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 20 -%}
        9 {%- elif states("sensor.mi_air_purifier_air_quality_pm25") | int > 5 -%}
        6 {%- else -%} 4 {%- endif %}'
    entity_id: fan.mi_air_purifier_3h
    service: xiaomi_miio.fan_set_favorite_level
  - data: {}
    entity_id: automation.air_purifier_translate_favorite_level_to_coverage
    service: automation.turn_on
  - data:
      message: Mi Air Purifier 3H - PM2.5 = {{ states('sensor.mi_air_purifier_air_quality_pm25')
        }} μg/m³ set favorite level to {{ state_attr('fan.mi_air_purifier_3h', 'favorite_level')
        }} (coverage {{ states('input_select.mi_air_purifier_coverage') }}) at {{
        states('sensor.date_time') }}
    service: notify.notify
  mode: single
1 Like

Perfect, I have made my modifications and will test it out, and get back to you!

Perfect , working well !!

I keep getting this error from time to time:

Logger: homeassistant.helpers.entity
Source: components/xiaomi_miio/fan.py:698
First occurred: 4:49:47 (2 occurrences)
Last logged: 7:05:47

Update for fan.mi_air_purifier_3h failsTraceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 278, in async_update_ha_state await self.async_device_update() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 474, in async_device_update raise exc File "/usr/src/homeassistant/homeassistant/components/xiaomi_miio/fan.py", line 840, in async_update { File "/usr/src/homeassistant/homeassistant/components/xiaomi_miio/fan.py", line 841, in <dictcomp> key: self._extract_value_from_attribute(state, value) File "/usr/src/homeassistant/homeassistant/components/xiaomi_miio/fan.py", line 698, in _extract_value_from_attribute value = getattr(state, attribute) File "/usr/local/lib/python3.8/site-packages/miio/airpurifier_miot.py", line 115, in mode return OperationMode(self.data["mode"]) File "/usr/local/lib/python3.8/enum.py", line 339, in __call__ return cls.__new__(cls, value) File "/usr/local/lib/python3.8/enum.py", line 662, in __new__ raise ve_exc ValueError: None is not a valid OperationMode

I think it has something to do with the verification if the aqi == None. Anybody has this asweel? Anyway to solve it?

Thanks!

I get totally the same, did you found any solution? The ping is time out a few times every minute. There are really high pings doesnt matter how close to the router.

I think has nothing to do with the Lovelace card. It is more related to the integration platform “xiaomi_miio” where receiving from purifier “None” that is not allowed. What card is doing is to translate the received None/unavailable into 0 just for displaying purposes.

Just realized that this error could also be related to None/Unavailable status. Favorite level should be 0 to 14 and accordingly input_select value. But when getting None/Unavailable there is no translation to input _select coverage value.

Hello
how did you add a card with your configuration ?
lovelace.yaml is stored into config folder?
how you use it?

sorry for a newby :slight_smile:

Seara Buna!