Dashboard - simple HVAC filter clean reminder

This project uses standard HA elements (Helpers, Automations, Lovelace Cards) to track HVAC running time and trigger a filter clean reminder card indication & notification. [Purpose was to keep it simple & avoid using addons or custom integrations to minimise being exposed to breaking changes].

Setup [Working with HA Core 2025.1.2]

  • An existing sensor of HVAC status running or not (i.e. on/off) used to control the runtime timer helper. [e.g. a Threshhold Helper “Trigger Aircon Running” controlled by a minimum AirCon power trigger point, or see optional config.yaml code below to create a sensor from the Daikin HA integration].
  • A Timer Helper used in a Tile card to track HVAC runtime e.g. “Daikin Filter Remaining”. [Timer Duration is setup as per desired AirCon running time filter clean interval (e.g. 90 hours), select ‘restore state’ so that timer survives HA restarts. Note that Timer Helpers only count time down i.e. time remaining].
  • An Input Boolean Helper used in a Tile card to indicate when filter clean is due e.g. “Daikin Filter Due”
  • An Input Button Helper used in a Button card to Reset the timer e.g. “Daikin Filter Reset”

Automation:
This controls the timer & cards and includes a notification when filter is due. [There is also an option to manually adjust the Timer remaining Duration, see notes in Automation].

description: >-
  Aircon Filter timer using AC runtime. 

  *Option 5 disabled Action: use to manually decrease/ increase the timer by a
  desired unit of time. Check timer entities are correct, enable Action, edit
  Duration [e.g. edit Duration to -30:00:00 to decrease current timer by 30
  hours] & manually Run Action.
triggers:
  - trigger: state
    entity_id:
      - input_button.daikin_filter_reset
    from: null
    id: Timer Reset
  - trigger: state
    entity_id:
      - binary_sensor.trigger_aircon_running
    to: "on"
    id: Timer Start
    enabled: true
    from: "off"
  - trigger: state
    entity_id:
      - binary_sensor.trigger_aircon_running
    to: "off"
    id: Timer Pause
    for:
      hours: 0
      minutes: 0
      seconds: 0
    enabled: true
    from: "on"
  - trigger: state
    entity_id:
      - timer.daikin_runtime
    to: idle
    id: Timer Finished
    for:
      hours: 0
      minutes: 0
      seconds: 10
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Timer Start
        sequence:
          - action: timer.start
            metadata: {}
            data: {}
            target:
              entity_id: timer.daikin_runtime
          - action: input_boolean.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: input_boolean.daikin_filter_due
      - conditions:
          - condition: trigger
            id:
              - Timer Pause
        sequence:
          - action: timer.pause
            metadata: {}
            data: {}
            target:
              entity_id: timer.daikin_runtime
      - conditions:
          - condition: trigger
            id:
              - Timer Finished
        sequence:
          - action: input_boolean.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: input_boolean.daikin_filter_due
            enabled: true
          - action: notify.notify
            data:
              message: The Daikin AC Filter is due to be cleaned
            enabled: true
      - conditions:
          - condition: trigger
            id:
              - Timer Reset
        sequence:
          - action: input_boolean.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: input_boolean.daikin_filter_due
          - action: timer.cancel
            metadata: {}
            data: {}
            target:
              entity_id: timer.daikin_runtime
          - action: timer.start
            metadata: {}
            data: {}
            target:
              entity_id: timer.daikin_runtime
          - action: timer.pause
            metadata: {}
            data: {}
            target:
              entity_id: timer.daikin_runtime
      - conditions: []
        sequence:
          - alias: >-
              Manually adjust timer duration. [Enable, set Duration delta in
              Timer ‘Change’ Action & Run this]
            sequence:
              - action: timer.start
                metadata: {}
                data: {}
                target:
                  entity_id: timer.daikin_runtime
              - action: timer.change
                metadata: {}
                data:
                  duration: "-30:00:00"
                enabled: true
                target:
                  entity_id: timer.daikin_runtime
              - action: timer.pause
                metadata: {}
                data: {}
                target:
                  entity_id: timer.daikin_runtime
            enabled: false
mode: single

Dashboard Cards:
yaml code for Dashboard cards

[Note - Display of Timer real-time Duration countdown only works in Entities & Tile type cards, other cards will only refresh/ display the current Timer Duration when Timer is paused].

  - cards:
      - type: tile
        show_entity_picture: false
        vertical: true
        hide_state: false
        entity: input_boolean.daikin_filter_due
        state_content: state
        tap_action:
          action: none
        icon_tap_action:
          action: none
        hold_action:
          action: none
        icon: mdi:air-filter
        color: red
    type: horizontal-stack
  - cards:
      - show_name: true
        show_icon: true
        entity: input_button.daikin_filter_reset
        hold_action:
          action: toggle
        tap_action:
          action: none
        type: button
        icon_height: 40px
        show_state: true
        name: Timer Reset
      - type: tile
        entity: timer.daikin_runtime
        vertical: false
        hide_state: false
        state_content: remaining_time
        name: Hrs to go
        color: amber
    type: horizontal-stack
type: vertical-stack
type or paste code here

Optional config.yaml code below to create a HVAC status sensor from the Daikin HA integration.

  - platform: template
    sensors:
      daikinap63347_hvac_status:
        value_template: >
          {% if state_attr('climate.daikinap63347', 'hvac_action') == 'off' %}
            Off
          {% else %}
           On
          {% endif %}
        friendly_name: 'DaikinAP63347 HVAC Status'
        unique_id: daikin-hvac-status

Cool, but to be fair, for most of these types of thing, a simple recurrent calendar item on any calendaring app is probably better and more reliable.

Thats always an option, but dirty HVAC filters are majority correlated with the unit runtime, not just over time…

Oh, what an excellent point that i had not contemplated.