Philips Air Purifier

I copy yours YAML and only change name of entity. This is My YAML:

type: vertical-stack
layout: horizontal
cards:
  - type: custom:button-card
    icon: custom:circle
    entity: fan.philips_airpurifier
    show_name: false
    template: ac_state
    size: 100%
    state:
      - operator: template
        value: '[[[ return variables.has_iai <= 3 ]]]'
        color: blue
      - operator: template
        value: '[[[ return variables.has_iai <= 6 ]]]'
        color: '#6666ff'
      - operator: template
        value: '[[[ return variables.has_iai <= 9 ]]]'
        color: '#ff00ff'
      - operator: template
        value: '[[[ return variables.has_iai > 9 ]]]'
        color: red
    styles:
      icon:
        - filter: drop-shadow(0 0 0.7rem)
      card:
        - pointer-events: none
      grid:
        - position: relative
      custom_fields:
        primary_reading:
          - position: absolute
          - top: 50%
          - left: 50%
          - transform: translate(-50%, -60%)
          - pointer-events: none
        secondary_reading:
          - position: absolute
          - top: 57%
          - left: 50%
          - transform: translate(-50%, 0%)
          - pointer-events: none
        notifications:
          - position: absolute
          - top: 25%
          - left: 50%
          - transform: translate(-50%, 0%)
          - pointer-events: none
    custom_fields:
      notifications:
        card:
          type: horizontal-stack
          cards:
            - type: custom:button-card
              template: ac_notifications
              icon: mdi:air-filter
              color: darkgreen
              state:
                - operator: template
                  value: '[[[ return variables.has_days_pre <=1 ]]]'
                  styles:
                    icon:
                      - color: darkred
                      - animation: blink 3s ease infinite
                - operator: template
                  value: '[[[ return variables.has_days_pre <=3 ]]]'
                  styles:
                    icon:
                      - color: darkorange
            - type: custom:button-card
              template: ac_notifications
              icon: philips:filter_replacement
              color: darkgreen
              state:
                - operator: template
                  value: '[[[ return variables.has_days_hepa <=1 ]]]'
                  styles:
                    icon:
                      - color: darkred
                      - animation: blink 3s ease infinite
                - operator: template
                  value: '[[[ return variables.has_days_hepa <=3 ]]]'
                  styles:
                    icon:
                      - color: darkorange
            - type: custom:button-card
              template: ac_notifications
              icon: mdi:image-filter-none
              color: darkgreen
              state:
                - operator: template
                  value: '[[[ return variables.has_days_carbon <=1 ]]]'
                  styles:
                    icon:
                      - color: darkred
                      - animation: blink 3s ease infinite
                - operator: template
                  value: '[[[ return variables.has_days_carbon <=3 ]]]'
                  styles:
                    icon:
                      - color: darkorange
            - type: custom:state-switch
              entity: template
              template: '[[[ return variables.has_water >= 0 && !variables.is_pur ]]]'
              states:
                'true':
                  type: custom:button-card
                  template: ac_notifications
                  icon: philips:water_refill
                  color: darkgreen
                  state:
                    - operator: template
                      value: '[[[ return variables.has_water <=10 ]]]'
                      styles:
                        icon:
                          - color: darkred
                          - animation: blink 3s ease infinite
                    - operator: template
                      value: '[[[ return variables.has_water <=30 ]]]'
                      styles:
                        icon:
                          - color: darkorange
            - type: custom:state-switch
              entity: template
              template: '[[[ return variables.has_days_wick >= 0 && !variables.is_pur ]]]'
              states:
                'true':
                  type: custom:button-card
                  template: ac_notifications
                  icon: philips:prefilter_wick_cleaning
                  color: darkgreen
                  state:
                    - operator: template
                      value: '[[[ return variables.has_days_wick <=1 ]]]'
                      styles:
                        icon:
                          - color: darkred
                          - animation: blink 3s ease infinite
                    - operator: template
                      value: '[[[ return variables.has_days_wick <=3 ]]]'
                      styles:
                        icon:
                          - color: darkorange
      secondary_reading:
        card:
          type: vertical-stack
          cards:
            - type: custom:button-card
              template: ac_readings
              icon: |
                [[[
                  if (variables.is_pm25)
                    return 'philips:iai' 
                  else
                    return 'philips:pm25'
                ]]]              
              variables:
                var_reading_text: |
                  [[[
                    if (variables.is_pm25)
                      return variables.has_iai
                    else
                      return variables.has_pm25
                  ]]] 
            - type: custom:state-switch
              entity: template
              template: '[[[ return variables.has_temp >= 0 ]]]'
              states:
                'true':
                  type: custom:button-card
                  template:
                    - ac_readings
                    - ac_state
                  icon: hass:thermometer
                  variables:
                    var_reading_text: '[[[ return variables.has_temp + " °C" ]]]'
            - type: custom:state-switch
              entity: template
              template: '[[[ return variables.has_humidity >= 0 ]]]'
              states:
                'true':
                  type: custom:button-card
                  template: ac_readings
                  icon: philips:humidity_button
                  variables:
                    var_reading_text: '[[[ return variables.has_humidity + " %" ]]]'
      primary_reading:
        card:
          type: custom:button-card
          icon: |
            [[[
              if (variables.is_pm25)
                return 'philips:pm25' 
              else
                return 'philips:iai'
            ]]] 
          size: 50%
          label: |
            [[[
              if (variables.is_pm25)
                return variables.has_pm25
              else
                return variables.has_iai
            ]]] 
          layout: icon_label
          show_label: true
          styles:
            label:
              - font-size: 400%
          style: |
            ha-card {
              box-shadow: none;
              background: none;
            }
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        template: buttons
        icon: philips:power_button
        entity: fan.air_ac2729
        name: Power
        tap_action:
          action: call-service
          service: script.toggle_ac_power
          service_data:
            entity_id: entity
      - type: custom:button-card
        template:
          - buttons
          - ac_state
        entity: fan.air_ac2729
        name: Lüfter
        tap_action:
          action: call-service
          service: script.toggle_ac_fan_speed
          service_data:
            entity_id: entity
        state:
          - operator: template
            value: '[[[ return variables.is_off ]]]'
            styles:
              card:
                - pointer-events: none
          - operator: template
            value: '[[[ return variables.is_on ]]]'
            id: activated_state
            icon: |-
              [[[
                switch (variables.has_speed) {
                  case "1":
                    return "philips:fan_speed_button"
                  case "2":
                    return "philips:fan_speed_button"
                  case "3":
                    return "philips:fan_speed_button"
                  case "auto":
                    return "philips:auto_mode"
                  case "allergen":
                    return "philips:allergen_mode"
                  case "night":
                    return "philips:sleep_mode"
                  case "turbo":
                    return "philips:fan_speed_button"
                }
              ]]]
        styles:
          icon:
            - animation: |-
                [[[
                  var speed = 'linear 0s infinite normal none running rotating';
                  switch (variables.has_speed) {
                    case '1':
                      return '12s ' + speed;
                    case '2':
                      return '6s ' + speed;
                    case '3':
                      return '2s ' + speed;
                    case 'turbo':
                      return '0.5s ' + speed;
                    default:
                      return 'none'; 
                  }
                ]]]
          grid:
            - position: relative
          custom_fields:
            fan_speed:
              - position: absolute
              - top: 47%
              - left: 42%
              - transform: translate(-50%, -60%)
              - pointer-events: none
        custom_fields:
          fan_speed:
            card:
              type: custom:button-card
              template: activated_state
              color_type: icon
              show_icon: false
              show_label: true
              label: |-
                [[[
                  switch (variables.has_speed) {
                    case '1':
                      return '1';
                    case '2':
                      return '2';
                    case '3':
                      return '3';
                    case 'turbo':
                      return 't';
                  }
                ]]]
              state:
                - operator: template
                  value: '[[[ return variables.is_on ]]]'
                  id: activated_state
              styles:
                label:
                  - padding: 2px 6px 0px 6px
                  - font-weight: bold
                  - color: |
                      [[[
                        if (variables.is_off)
                          return 'var(--paper-item-icon-color)';
                        else
                          return 'var(--mmp-accent-color, var(--accent-color))';
                      ]]]
              style: |
                ha-card {
                  box-shadow: none;
                }
      - type: custom:button-card
        template:
          - buttons
          - ac_state
        icon: philips:light_dimming_button
        entity: fan.air_ac2729
        name: Anzeige
        tap_action:
          action: call-service
          service: script.toggle_ac_light
          service_data:
            entity_id: entity
        state:
          - operator: template
            value: '[[[ return variables.is_off ]]]'
            styles:
              card:
                - pointer-events: none
          - operator: template
            value: '[[[ return variables.is_backlight ]]]'
            id: activated_state
      - type: custom:button-card
        template:
          - buttons
          - ac_state
        entity: fan.air_ac2729
        name: Modus
        tap_action:
          action: call-service
          service: script.toggle_ac_two_in_one_mode
          service_data:
            entity_id: entity
        state:
          - operator: template
            value: '[[[ return variables.is_on && variables.has_humidity > 0 ]]]'
            icon: >-
              [[[ return variables.is_pur ? "philips:purification_only_mode" :
              "philips:two_in_one_mode" ]]]
            id: activated_state
          - operator: template
            value: '[[[ return variables.is_off || variables.has_humidity < 0 ]]]'
            icon: >-
              [[[ return variables.is_pur ? "philips:purification_only_mode" :
              "philips:two_in_one_mode" ]]]
            styles:
              card:
                - pointer-events: none

Did you install my Phillips icons as well? Is the custom:button-card up to date?

Thank you! it worked for me, I have a 3033.

In log I get this warning when component starts:

2021-12-28 17:04:08 WARNING (MainThread) [homeassistant.helpers.entity] Entity fan.philips_airpurifier (<class 'custom_components.philips_airpurifier_coap.fan.PhilipsAC3033'>) implements device_state_attributes. Please report it to the custom component author.

EDIT:
device_version: 3.3.1
software_version: Ms3331
wifi_version: [email protected]

I did a diff with my yaml and noticed quite a few differences appart from the renamed entity.

  • You’re using your own icons? I’m not sure if that makes a difference, but it could explain why the icons are not shown on your buttons
  • The templates have been changed for the humidity_button. Might not make a difference? Or maybe it does?
  • The whole icon part for the toggle_ac_fan_speed was moved
  • and some other stuff is modified, moved or changed

Overall, that makes it difficult to judge if the changes introduced a problem. I suggest, you try with the original script first and then step by step adapt it to what you want.

Could you give the actual script here? I copied from your post from January.

Hello, do you know the scale for the pm25, voc and air quality?

Because I am want to do some automation but I don’t know the max values and the ranges of the “good” values…

I created a custom card for this air purifier. this is the link https://community.home-assistant.io/t/fan-control-with-set-preset-mode/372741

These are the values from the Philips Clean Home+ App for iOS. I hope this helps.

1 Like

Are there other components or steps necessary to add the purifier to HA?
I followed the “Installation” instructions but the air purifier stays unavailable.
Its an AC2889/10, device firmware version 1.0.7, WiFi Firmware version 68.3.

Are you really using “my” repository of Philips AirPurifier? Just asking… =)
There are other repositorys of Philips Airpurifier that uses “coap”

This problem with “device_state_attributes” I have fixed, but I dont have the “COAP” fan

Hey

Have you changed the ip-adress to your fans ip?

Yes I did. To be sure I removed the component and configuration and added it once more. Unfortunately the problem persists.
Interestingly Studio Code Server gives me this warning:
Screenshot 2022-01-06 at 21.15.02
But checking the configuration and restarting HA does not result in an error or warning.
After fixing the apparent error to:

fan:
  - platform: philips_airpurifier
    host: 192.168.182.25

and a successful restart without errors or warnings the state is still unavailable. Any ideas?

Thank you :+1:

Try restart the fan. Any charges?
If not Try restart HA.

At the end I used the repository from @kongo09

But I can tell you that the warning is present in all the repositories I found linked to this 3d.
At the beginning I wasn’t able to get the purifier on HA, so I tried everything…

Regarding the warning I could think that home assistant generate the warning because it could need a features that the purifier should provide or simply because the add on creates an entity without a device… I don’t know, I am a programmer but I am new of python and home assistant…
So I cannot help in this…

EDIT: Just saw that your repository is different… maybe I missed it during my tests… can it work with coap or it is only for http?

I can see the line in @kongo09 repository that I have fixed. The warning started with HA 2021.4 and now 2021.12 its an error.

In your respository you will have this code in fan.py at line 479:

def device_state_attributes(self) -> Optional[Dict[str, Any]]:

change it to:

def extra_state_attributes(self) -> Optional[Dict[str, Any]]:

No more error, hopefully! =)

I quickly changed this in my repo. Hope this eliminates the warning.

This is a real pain. Mine are unavailable most of the time. The integration is essentially broken since Philips did a firmware update over-the-air. I’m not the maintainer of the integration and lack the skill to fix it.

The error is gone, but I got others…

/usr/local/lib/python3.9/site-packages/aiocoap/transports/udp6.py:525

This is the folder where the file is:

pi@domotica:/ $ docker exec -it home-assistant sh
/config # cd /
/ # python --version
Python 3.9.7
/ # ls /usr/local/lib/python3.9/site-packages/aiocoap/
__init__.py            credentials.py         interfaces.py          meta.py                optiontypes.py         protocol.py            resourcedirectory      util
__pycache__            defaults.py            message.py             numbers                oscore.py              proxy                  tokenmanager.py
cli                    error.py               messagemanager.py      options.py             oscore_sitewrapper.py  resource.py            transports
/ # 

I also got these

2022-01-07 18:19:10 ERROR (MainThread) [coap] Connection loss was not expected.

2022-01-07 18:19:10 ERROR (MainThread) [coap] Connection loss was not expected.

As I said, the whole thing is broken and not really maintained.

Not a big problem, the device work to me.
I thought that wasn’t an issue to fix that alarm, as already said I am not an expert of python programming

Anyway thank you :wink: