Help with fan activity / runtime-hours monitor automation

Dear community, freshly coming from FHEM I am trying to (re-) create an automation that monitors the state of a ventilation fan. Having searched for hours, I still can’t wrap my head around how to do this. Now my hope is that some of you can point me in the right direction.

The problem I want to solve is this: The ventilation fan is switched on with a wall switch and once switched off will run for a follow-up time of 15 minutes. The only information I have in HA is the state of the switch (on/off), using a powermeter is not an option. From this and the known follow-up time I want to infer the state of the ventilation fan (on/follow-up/off). In the end, I want to use this state to keep track of the total runtime of the fan (filter has to be replaced every X hours) and visualize the state with differently colored icons in the GUI.

I assume I need some kind of state entity that stores the fan state and that I can use to show different icons/colors (how?) plus an automation that reacts to state changes of the switch and has a timeout to induce the followup-to-off-transition, triggered by the on-to-off-transition of the switch. Obviously, this timeout needs to be canceled if the switch changes back to on while the timeout is still running.

When the runtime counter reaches a certain value (e.g. 100h), an item should be added to the todo-list to exchange the filter. The runtime-counter should be reset to 0 when this todo-list item has been marked as done. Until then, the hours should still be counted and if possible, the todo-list entry should be updated with the new value.

I’m not expecting a ready-to-use solution (unless there’s already a blueprint I just failed to find); any hints on how to approach this automation and its various aspects are highly appreciated.

# Example configuration.yaml entry
sensor:
  - platform: history_stats
    name: Fan Run Time
    entity_id: switch.my_fan
    state: "on"
    type: time
    start: "{{ states('input_datetime.fan_filter_changed') }}"
    end: "{{ now() }}"

Additionally create an input datetime helper called Fan Filter Changed that has a date and time.

The rest you can do in two automations.

Trigger:

  • numeric state trigger sensor.fan_run_time > 100.

Actions

  • add your to-do item.
triggers:
  trigger: numeric_state
  entity_id: sensor.fan_run_time
  above: 100
actions:
  - action: todo.add_item
    target: 
      entity_id: todo.my_to_do_list
    data:
      item: "Change Fan Filter"
      due_date: "{{ now() + timedelta(hours = 24) }}" # due tomorrow
      description: "Change the fan filter."

Then another automation for when you clear the todo:

I’m not yet sure how to detect the todo has been done (trigger). But this is the action you want

  - action: input_datetime.set_value
    target:
      entity_id: input_datetime.fan_filter_changed
    datetime: "{{ now() }}"

Hopefully someone else can help with that trigger.

Thank you @tom_l this is brilliant, and a much more elegant solution for keeping track of the run time than I was expecting.

So for now, I’ve created a package for the required entities; first one handles the off->on transition:

input_select:
  duschbad_luefter_state:
    name: Duschbad-Lüfter Zustand
    options:
      - "off"
      - "on"
      - "followup"
    icon: mdi:fan

input_datetime:
  duschbad_luefter_filter_changed:
    name: Letzter Filterwechsel Duschbad
    has_date: true
    has_time: true

sensor:
  - platform: history_stats
    name: Duschbad Fan Run Time
    entity_id: input_select.duschbad_luefter_state
    state: ["on", "followup"]
    type: time
    start: "{{ states('input_datetime.duschbad_luefter_filter_changed') }}"
    end: "{{ now() }}"

and 3 automations created with the UI to select the duschbad_luefter_state:

alias: Duschbadlüfter wird angeschaltet
description: "Fan being switched on"
triggers:
  - trigger: state
    entity_id:
      - input_boolean.switchdemo  # dummy-switch for testing - replace with actual wall-switch 
    to: "on"
actions:
  - target:
      entity_id: input_select.duschbad_luefter_state
    data:
      option: "on"
    action: input_select.select_option
mode: single

second one for the off->followup transition

alias: Duschbadlüfter läuft nach
description: "Fan keeps running for another 15 min."
triggers:
  - trigger: state
    entity_id:
      - input_boolean.switchdemo  # dummy-switch for testing - replace with actual wall-switch 
    to: "off"
conditions: []
actions:
  - target:
      entity_id: input_select.duschbad_luefter_state
    data:
      option: followup
    action: input_select.select_option
mode: single

and ast one for the followup->off transition:

alias: Duschbad Lüfter geht aus
description: "Fan followup time ends"
triggers:
  - trigger: state
    entity_id:
      - input_select.duschbad_luefter_state
    to: followup
    for:
      hours: 0
      minutes: 15
      seconds: 0
conditions: []
actions:
  - target:
      entity_id: input_select.duschbad_luefter_state
    data:
      option: "off"
    action: input_select.select_option
mode: single

This already works like intended, but I’m wondering if it’s good practice to have 3 individual automations or if it would be better to combine then into one. I’m also wondering if the automations should be included in the package yaml where the related entities are defined. I’d be happy to hear your thoughts on this.

Do what ever is easiest for you to understand and maintain.

1 Like

Hmm, for now I can live with these individual automations, optimizations may be for another day. Meanwhile, I’ve got the todo list integration working, too. Adding to the todo list works as you proposed. For resetting the filter_changed_datetime helper, I’m using the blueprint Restart Safe - To-do List Chore Notifications! with an action that is executed when the entry is ticked off.