Automation service template using times in if else block fails

I’m attempting to merge two working simple automations into one because having one automation to switch on a thermostat and a second automation to switch it off lacks elegance and means two automations have to be managed.

I’m attempting to create my first service template which uses a very basic if/else block based on times. The times come from helpers, the values are input from lovelace.

All that has to happen is the generic thermostat is switched on if it’s within the on and off times. Simple, right? Code below. I think I’m probably tangled up in time formats but there may be more. I’ve spent hours reading finity’s EPIC Time Conversion thread and searching. I’ve gone snowblind :cry: Why is this automation not turning the thermostat on and off?

- id: '1612078816753'
  alias: Warm the bed 2
  description: description
  trigger:
  - platform: time
    at: input_datetime.underblanket_on
  condition: []
  action:
  - service_template: >
      {%- set t_now = now().time() %}
      {%- set t_on = strptime(input_datetime.underblanket_on, '%H:%M') %}
      {%- set t_off = strptime(input_datetime.underblanket_off, '%H:%M') %}
      {% if t_now >= t_on and t_now < t_off %}
        climate.turn_on
      {% else %}
        climate.turn_off
      {% endif %}
    data: {}
    entity_id: climate.underblanketthermostat
  mode: single

There is plenty of elegance in simplicity and trying to merge simple things into one does not necessarily keep it simple (as this post is proof of) :slight_smile:

The displayed automation triggers only at the time that is defined by input_datetime.underblanket_on. I guess your forgot a second time-trigger at input_datetime.underblanket_off.

Btw: Take a look at choices that can be used in the action part of an automation too. They elegantly simplify what your service template is trying to mimic.

because input_datetime.underblanket_on & off are not passed into the states() method and they aren’t in quotes. So t_on and t_off are never correct. You can also just change t_now to be a string and it’ll work.

Also, you can shorten your time comparision. on <= now < off is more readable and correct syntax.

This is why your template wasn’t working…

      {%- set t_now = now().time() %}
      {%- set t_on = strptime(states('input_datetime.underblanket_on'), '%H:%M') %}
      {%- set t_off = strptime(states('input_datetime.underblanket_off'), '%H:%M') %}
      {% if t_on <= t_now < t_off %}
        climate.turn_on
      {% else %}
        climate.turn_off
      {% endif %}

but I recommend using this instead:

      {%- set t_now = as_timestamp(now()) | timestamp_custom('%H:%M') %}
      {%- set t_on = states('input_datetime.underblanket_on') %}
      {%- set t_off = states('input_datetime.underblanket_off') %}
      {% if t_on <= t_now < t_off %}
        climate.turn_on
      {% else %}
        climate.turn_off
      {% endif %}

Also, use the template editor. You would have seen right away that using input_datetime.underblanket_on would throw an error in the template editor without quotes and outside the states() method.

1 Like

There is plenty of elegance in simplicity and trying to merge simple things into one does not necessarily keep it simple (as this post is proof of) :slight_smile:

Never a truer word said! This was also an exercise to expand my limited knowledge, so I kinda wanted it to be difficult!
Thanks for the link to choices. I shall review.

Many thanks @petro petro. That has advanced my limited understanding further.
I confess I struggled with the template editor. I haven’t tried templates before, and I’m not a coder, so even though the editor may be really helpful once I understand a bit more, it didn’t help me this time. I shall continue the learning journey step by step!

I suspect some of the struggles I’m having with automation and input_datetime fields is due to a bug.

Summary of similar/related threads, github issues and Pull Requests: