Help with template to set state on input_boolean

Hello everyone,

I would like some help with an automation i am trying to build to turn on the kettle for our morning coffee. I use a smart plug and the automation should look on our alarms and 2 minutes before an alarm goes off, it should turn on the smart plug. I have implemented an input_boolean which i can manually select which of the 2 alarms should be taken into consideration. Here is the current automation i have:

Kettle - Automated - Home Automation Ideas (homeautomation-ideas.com)

While the above works, it requires a manual intervention to select the boolean that will define which alarm should be taken into consideration. I would like to have this part automated. The idea is to select the alarm that will go off first. For example, if my wife wakes up at 6:00 and i wake up at 6:30, it should consider my wife’s alarm.

Perhaps this template could potentially work:

value_template: >-
{{ states('sensor.michael_next_alarm_2') | float > states('sensor.barbie_next_alarm_2') | float }}

The problem with this is that if one of the alarms is not set, the state of the sensor in Home Assistant is “Unavailable” and the above template does not work. And this is exactly where i need help. The logic should be:

  • If both sensors are “Unavailable” then the automation should not run
  • If one of the 2 sensors is “Unavailable”, then consider the other alarm
  • If both sensors have a numeric value consider the one with the smallest value.

To this last one, if my alarm has smaller numeric value, it should set the input_boolean to on, and if my wife’s alarm has the smaller value it should set the input_boolean to off.

Please for your help!
Thank you

Without investing time in reading your automation (sorry), there is already a thing to add to your float conversion.

{{ states('sensor.michael_next_alarm_2') | float(-1) > states('sensor.barbie_next_alarm_2') | float(-1) }}

This will give a value of -1 if no value is given by the sensor (or do a large value in your case as you want the highest to be ignored probably)

1 Like

No worries about reading the actual automation, it’s logic is more or less written above.

One question please… The trigger of the automation is a numeric state of the next_alarm in minutes and it triggers if it is below 2 minutes. Adding the -1 in the float means that it will actually trigger 3 minutes before the alarm goes off right?

The idea is to solve your unavailable sensor values.
The float(-1) will replace unavailable by -1
It will therefore be possible to compare both sensor without issue and select the right alarms imo.
Might be that you have to put a very large value instead of -1, depending of the use case.

As an exemple, part of one my script

{% set temperature = states('sensor.darksky_outside') | float(-500) | round(0) | string %}
{% if temperature | int > -500 %} with {{temperature}} degrees. {% endif %}

Logic is, if sensor is unavailable, the temperature is considered -500 (which can not exist as it is lower than 0K)
Then, later in the script I can compare and only TTS the temperature if I know it.

Makes sense! I think i solved it with your suggestion and this is the full automation:

alias: Kitchen - Activate Kettle on Alarm
description: >-
  This automation will start the Kettle when either of our mobile alarms go off.
  It uses a toggle helper to determine which alarm it should take into
  consideration. 
trigger:
  - platform: numeric_state
    entity_id: sensor.michael_next_alarm_2
    for:
      hours: 0
      minutes: 0
      seconds: 0
    below: 2
    id: Michael's Alarm
  - platform: numeric_state
    entity_id: sensor.barbie_next_alarm_2
    for:
      hours: 0
      minutes: 0
      seconds: 0
    below: 2
    id: Barbie's Alarm
  - platform: state
    entity_id:
      - input_boolean.alarm_selection
    to: "on"
  - platform: state
    entity_id:
      - input_boolean.alarm_selection
    to: "off"
condition:
  - condition: state
    entity_id: switch.universal_plug_1
    state: "off"
action:
  - choose:
      - conditions:
          - condition: trigger
            id: Michael's Alarm
          - condition: state
            entity_id: input_boolean.alarm_selection
            state: "on"
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.universal_plug_1
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.universal_plug_1
      - conditions:
          - condition: trigger
            id: Barbie's Alarm
          - condition: state
            entity_id: input_boolean.alarm_selection
            state: "off"
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.universal_plug_1
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.universal_plug_1
    default:
      - if:
          - condition: template
            value_template: >-
              {{ states('sensor.michael_next_alarm_2') | float(-1) >
              states('sensor.barbie_next_alarm_2') | float (-1)}}
        then:
          - service: input_boolean.turn_on
            data: {}
            target:
              entity_id: input_boolean.alarm_selection
        else:
          - service: input_boolean.turn_off
            data: {}
            target:
              entity_id: input_boolean.alarm_selection
mode: single

I added the template as default actions and the states as trigger. With my phone it works but my wife is not home so i cannot test if it works for her as well.

Let me word your condition, you’ll tell me if this is what you tend to achieve:


If michael > barbie or michael is unknown or (micheal is known and barbie is unknown)
  on kettle
else
  off kettle

And I think something is missing for your wife to get hot tea :slight_smile:

If it is me, I’d replace everything in a template trigger, let me explain

trigger:
  - platform: template
    value_template: >
      {# set sensor value to 1000 so it will never be less than the other or less than 2 if unknown #}

      {% set michael = states('sensor.michael_next_alarm_2') | int(1000) %}
      {% set barbie= states('sensor.barbie_next_alarm_2') | int(1000)  %}
      {% set alarm = states('input_boolean.alarm_selection')  %}

      {% if michael < 2 and alarm == true %}
         {# michael is known and is less than 2 minutes, return true to trigger automation for him #}
         true
      {% elif barbie < 2 and alarm == true %}
         {# barbie is known and is less than 2 minutes, return true to trigger automation for her #}
         true
      {% else %}
         {# michael is  > 2 or unknown and the same for barbie, return false as automation shouldn't start #}
         false
      {% endif %}      

{# these are comment for you to understand #} but remove them in the ifs as nested Jinja is not allowed in HA

EDIT Not sure to get all the details of your automation, it is more for you to be inspired

1 Like

Thank you Olivier, i will give this a try! As you understood i am not so good in templating :slight_smile:

Ce qui se conçoit bien s’énonce clairement, et les mots pour le dire arrivent aisément.
Nicolas Boileau, French poet and critic

It means: What you understand well, you enunciate clearly
I believe that if you write your logic as a template, it will be much more clear to get what you want to do in your automation.
First, use English:
If Michael is home and the alarm is set to turn off in less than 2 minutes and if the selected alarm switch is on and the kettle switch is off then I’d like the kettle to turn on.

It will come to Jinja easily, believe me.

{% states('person.michael') == 'home' and 
   (state_attr('sensor.alarms','next_event') | default(0,true) | as_timestamp()) - (now() | as_timestamp()) > 2 * 60) and
   is_state('binary_sensor.selected_alarm', true) and
   is_state('switch.universal_plug_1','off')
%}

Fictitious exemple but you get the idea, right :slight_smile:

Hey Olivier,

Unfortunately i have to report that the proposed solution didn’t work for me. Most probably it didn’t work because i didn’t give you all the background i guess (which i have in the post on my site). So to make this easier let me give you some more information. HA takes the the data from the companion app and creates 2 entities: sensor.michael_next_alarm and sensor.barbie_next_alarm which have the time of the alarm in date format.

What i have done in order to get the minutes is that i have the following code in my configuration file for both the above sensors:

- platform: template
  sensors:
    barbie_next_alarm:
      friendly_name: Barbie's Next Alarm (min)
      unit_of_measurement: 'm'
      value_template: "{{((states('sensor.barbie_next_alarm')|as_timestamp|int - now()|as_timestamp|int)/60)|int}}"

However, if an alarm is not set, the value of the sensors in minutes is “Unavailable”. I believe that we need to adjust the above code to have a pre-defined value even if the alarm is not set (avoid being unavailable. Do you may have any suggestions?

Thanks
Kind Regards
M

If states('sensor.barbie_next_alarm') (resp. states('sensor.michael_next_alarm ') ) might be unknown if not set, this is probably the place to put you default values?

Because | as_timestamp and | int will fail if it is unknown.

I also think that it is better to trigger on the alarm time then, instead of the minutes remaining, like

trigger:
- platform: template
  value_template: "{{ now() >= today_at(states('sensor.barbie_next_alarm')) - timedelta(minutes = 2) }}"
  id: barbie
- platform: template
  value_template: "{{ now() >= today_at(states('sensor.michael_next_alarm')) - timedelta(minutes = 2) }}"
  id: michael
conditions:
  kettle is off, ...
action:
  - if:
    - and:
      - condition: trigger
        id: michael
      - condition: template
        value_template: "{{ states('sensor.michael_next_alarm') < states('sensor.barbie_next_alarm') | default(today_at('23:59:59')) }} 
    then: []
    else: []
  - if:
    - and:
      - condition: trigger
        id: barbie
      - condition: template
        value_template: "{{ states('sensor.barbie_next_alarm') < states('sensor.michael_next_alarm') | default(today_at('23:59:59')) }} 
    then: []
    else: []

This is not the solution, it is a sample where you trigger based on timestamp (one of the 2 alarms is in 2 minutes) and then, test who’s first to get tea (triggered by michael and his alarm is before barbie’s or triggered by barbie and her alarm is before michael’s)

Please note that I’m writing code on a forum, this is not a copy/paste of a working automation, it might be wrongly/poorly written, even if I try my best to put it in the proper way.

1 Like