Dropdown should drive timer for heating (automation)

Hi folks,

I am using a mushroom-select-card to configure a timer for the heating in my bathroom. Could also be used for any other timed activities.

Workflow:

The mushroom dropdown triggers & sets the value for a timer helper and then starts the heating for the selected time duration. Once the set time is over the heating stops and timer & dropdown will be reset.

@Didgeridrew helped a lot here and I think this is worth sharing with others. Could also probably be worth creating a Blueprint for this - which is beyond my skills.

Follow the solution for details and code example.

This is a general automation to control a heater based on a select and a timer… you will need to provide your select option value details and entity names for something more specific.

trigger:
  - platform: state
    id: button
    entity_id: input_select.heater_time
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heat_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.start
    event_data:
      entity_id: timer.heat_timer
condition:
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
        sequence:
          - service: timer.start
            data:
              duration: "{{ trigger.to_state.state }}{# MORE INFO REQUIRED #}" 
            target:
              - entity_id: timer.heat_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.turn_on
    default:
      - service: climate.turn_off
mode: queued

Thanks Drew,

I also tried the “options” path but my skills are not high enough so tried the if/else which also didn’t work.

My dropdown is called “input_select.dropdown_bad_heizen_timer” and the HVAC entity is called “climate.badezimmer”.
For the 1/2/3 hrs I configured 3 different timers - not sure if this is needed or if one single timer can be configured based on the value of the input select.

My timers are called “timer.heizung_bad_1h_timer” and then …2h / …3h.

I configured a new Automation and will try to adapt the code you shared.

Ok, updated the automation based on your code example, still needs more refinement and I don’t see the 3 different timer options & off reflected.

trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_1h_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.start
    event_data:
      entity_id: timer.heizung_bad_1h_timer
condition: null
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
        sequence:
          - service: timer.start
            data:
              duration: "{{ trigger.to_state.state }}{# MORE INFO REQUIRED #}"
            target:
              - entity_id: timer.heizung_bad_1h_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
            target:
              entity_id: climate.badezimmer
    default:
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued

A single timer should be sufficient, and will keep the automation a lot simpler.

What are the values of your select’s options? Are they just “1”, “2”, “3” or something like “1 hour”, “2 hours”, “3 hours”? We will need to know that to correctly design the template to assign the timer’s duration.

The options are “Aus” (German for off), “1h”, “2h”, “3h”.

trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
    not_from:
      - unavailable
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_1h_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.start
    event_data:
      entity_id: timer.heizung_bad_1h_timer
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
          - condition: template
            value_template: "{{ trigger.to_state.state in ['1h', '2h', '3h'] }}"
        sequence:
          - service: timer.start
            data:
              duration: >
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_1h_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
            target:
              entity_id: climate.badezimmer
    default:
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued

When I try to safe, following error message is being displayed:

Message malformed: expected a dictionary for dictionary value @ data[‘action’][0][‘choose’][0][‘sequence’][0][‘target’]

The entity id should not have the - in front of it…

...
        sequence:
          - service: timer.start
            data:
              duration: >
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_1h_timer
...

EDIT: I have fixed it in the previous post as well

I can save the automation and when I change values in the dropdown from within the dashboard I see coresponding entries in the logbook, but the HVAC devices does not change to heating or sets the new temperature.
I also added the HVAC mode “heat” to the yaml, but that does not seem to have any effect.

Trying to troubleshoot through the logs & tracing - the latter isn’t intuitive enough for my skill level.

I understand from the trace that the timer started, but the heating would be started through the middle branch, which as I get it did not get followed.

You should have had another trace after that when the timer turning on triggers the climate action…

It looks like I messed up the start event trigger. The event type should have been timer.restarted.

...
  - platform: event
    id: timer_start
    event_type:
      - timer.restarted
    event_data:
      entity_id: timer.heizung_bad_1h_timer
...

That seems to work. I will test it today and share feedback tonight.

So this basically works, but there seems to be still a bug.

I had the timer running this morning and it worked, switched of the heating after 1hr.

After finishing, the dropdown stayed at 1hr (would be cool if it would switch back to “AUS” resp. “OFF” after the timer has finished).

Later today I switched the drop down to “AUS” and back to 1hr this evening. And it looks the process went again with the left branch and started only the timer, but not the heating.

For reference this is the current code:
I renamed the timer since it is can handle multiple hour values as I understand it and deleted the other 2hr and 3hr timers.

alias: Heizung - Bad Timer Steuerung
description: ""
trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
    not_from:
      - unavailable
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.restarted
    event_data:
      entity_id: timer.heizung_bad_timer
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
          - condition: template
            value_template: "{{ trigger.to_state.state in ['1h', '2h', '3h'] }}"
        sequence:
          - service: timer.start
            data:
              duration: |
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
              hvac_mode: heat
            target:
              entity_id: climate.badezimmer
    default:
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued

alias: Heizung - Bad Timer Steuerung
description: ""
trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
    not_from:
      - unavailable
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.restarted
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: state
    to: 'off'
    id: climate_off
    not_from:
      - unknown
      - unavailable
    entity_id: climate.badezimmer
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
          - condition: template
            value_template: "{{ trigger.to_state.state in ['1h', '2h', '3h'] }}"
        sequence:
          - service: timer.start
            data:
              duration: |
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
              hvac_mode: heat
            target:
              entity_id: climate.badezimmer
      - conditions:
          - condition: trigger
            id: climate_off
        sequence:
          - service: input_select.select_option
            target:
              entity_id: input_select.dropdown_bad_heizen_timer
            data:
              option: Aus
    default:
      - "{{ not is_state('climate.badezimmer', ['off', 'unknown', 'unavailable']) }}"
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued
max: 2

This throws the error message “Message malformed: expected dictionary @ data[‘action’][0][‘default’][0]”

I compared both old and new code and also validated the new yaml - still cannot make up where the error in the code is. Guess in the action section?

I changed the last options (4) default parameter through the GUI and so far the automation works.

However, I think I catched one bug, which is when the timer is off and I change the dropdown to 1h it does not always start the heating immediately. When I change it to 2hrs and back to 1hr it works.

Current code:

alias: Heizung - Bad Timer Steuerung
description: ""
trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
    not_from:
      - unavailable
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.restarted
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: state
    to: "off"
    id: climate_off
    not_from:
      - unknown
      - unavailable
    entity_id: climate.badezimmer
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
          - condition: template
            value_template: "{{ trigger.to_state.state in ['1h', '2h', '3h'] }}"
        sequence:
          - service: timer.start
            data:
              duration: |
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
              hvac_mode: heat
            target:
              entity_id: climate.badezimmer
      - conditions:
          - condition: trigger
            id: climate_off
        sequence:
          - service: input_select.select_option
            target:
              entity_id: input_select.dropdown_bad_heizen_timer
            data:
              option: Aus
    default:
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued
max: 2

That is because I accidentally left out the timer.started option of the timer_start trigger… both started and restarted are required so that it works when the timer goes from idle to active as well as when the timer is already active and the duration is changed.

alias: Heizung - Bad Timer Steuerung
description: ""
trigger:
  - platform: state
    id: button
    entity_id:
      - input_select.dropdown_bad_heizen_timer
    not_from:
      - unavailable
  - platform: event
    event_type:
      - timer.cancelled
      - timer.finished
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: event
    id: timer_start
    event_type:
      - timer.started
      - timer.restarted
    event_data:
      entity_id: timer.heizung_bad_timer
  - platform: state
    to: "off"
    id: climate_off
    not_from:
      - unknown
      - unavailable
    entity_id: climate.badezimmer
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: button
          - condition: template
            value_template: "{{ trigger.to_state.state | replace('h', '') | is_number}}"
        sequence:
          - service: timer.start
            data:
              duration: |
                {{ trigger.to_state.state | replace('h', '') | int * 3600 }}
            target:
              entity_id: timer.heizung_bad_timer
      - conditions:
          - condition: trigger
            id: timer_start
        sequence:
          - service: climate.set_temperature
            data:
              temperature: 24
              hvac_mode: heat
            target:
              entity_id: climate.badezimmer
      - conditions:
          - condition: trigger
            id: climate_off
        sequence:
          - service: input_select.select_option
            target:
              entity_id: input_select.dropdown_bad_heizen_timer
            data:
              option: Aus
    default:
      - condition: "{{ not is_state('climate.badezimmer', [ 'off', 'unavailable', 'unknown' ]) }}"
      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.badezimmer
mode: queued
max: 2

Thanks much @Didgeridrew. So far this is working as expected! I’ll update the original post.

1 Like