Time based template

I have searched, but I’ve had no luck finding the solution.

  - service_template: >
      {% if states.sensor.time.state < "21:30"  %}
        homeassistant.turn_on
      {% endif %}
    entity_id: 
      - switch.light_a
      - switch.light_b

This is a part of a larger automation. The rest of this automation works fine, but those lines does not seem to execute at all. It’s something with how I do the time comparison.

I have tested the condition in the Template validator in the frontend and I got the result I expected.

How do I get this part of the automation to work, i.e. to turn the two lights on if the time is before 21:30?

Convert the time strings to timestamps before doing the comparison.

1 Like

I tried this:

  - service_template: >-
      {% if strptime((states.sensor.time.state),"%H:%M") < strptime(("21:30"),"%H:%M")  %}
        homeassistant.turn_on
      {% endif %}        
    entity_id: 
      - switch.light_a
      - switch.light_b

Tomorrow afternoon I’ll know if it’s working

You shouldn’t have to put a filter on the time sensor, I have multiple automations set up like the following that work every day:

  - service_template: >-
      {% if states.sensor.time.state < '21:30' | timestamp_custom('%H:%M', False) %}
        homeassistant.turn_on
      {% endif %}        

This seems to work just fine for me:

  - service_template: >-
      {% if states.sensor.time.state < '21:00' | timestamp_custom('%H:%M') %}
        homeassistant.turn_on
      {% endif %}    
    data:
      entity_id: 
        - switch.light_a
        - switch.light_b

As you can se, I removed the “false” from @walrus_parka suggestion.

What does that “false”-thing do anyway? Cannot google that.

False turns your timestamp into local time. True (or omitted) turns it into UTC. You’ll want False. But to be quite honest, that conversion is doing nothing because ‘21:00’ is not a timestamp.

For safety, you really should be converting the time and your other time to a single mathematical unit and compare them that way as @tom_l said. Relying on string comparisons is not the way to go because it doesn’t work the way you think it does. I.E '9' is not less than '10' in the string world:

1 Like

@petro thanks for your suggestion.

For me, and for future readers, whats the best way to convert that timestamp to UNIX-time or something similar in order to be able to do that comparison?

Well inside an automation/script, I wouldn’t use sensor.time. I’d use now().

{{ now().hour * 60 + now().minute < 21 * 60 + 30 }}
                                    ^ hours   ^ minutes

This is another way. You replace the current time with values you want.

{{ now() < now().replace(hour=21).replace(minute=30).replace(second=0).replace(microsecond=0) }}
2 Likes

Here’s what’s actually working:

  - service_template: >
      {% if now().strftime('%T') < strptime('21:30:00', '%T') %}
        switch.turn_on
      {% endif %}           
    entity_id: 
      - switch.light_a
      - switch.light_b

not sure how that is working because now().strftime(’%T’) is a string where strptime(‘21:30:00’, ‘%T’) is a datetime object. They are not comparable. You may have problems with this in other ways and you shouldn’t mark it as a solution as it will steer other people in the wrong direction. In fact, the strptime isn’t actually converting it to a datetime, it’s keeping it a string. In the string world, 9 is greater than 10.

@petro I removed the “Mark as solved” on this issue. Np.

Well, you are right in all the ways I can think of, but it does work. I have been running this for a few days now just in order to be sure it does what I want, and it sure does.

1 Like

no harm in leaving the thread ‘unsolved’, i’m leery of having bad time information out there because it’s the hardest templating thing in HA to deal with.

In the string world, 9 is greater than 10.

While this is indeed true, it doesn’t apply here because you won’t be comparing 9 and 10 but 09 and 10.

One of the great things about ISO 8601 times (and dates and datetimes) is that they are lexicographically comparable because they are ordered from largest to smallest unit of time and has leading zeroes.

You can see how and why this works with this short example:

In [1]: import datetime

In [2]: datetime.datetime(2020, 3, 18, 9, 00, 00).strftime("%T")
Out[2]: '09:00:00'

In [3]: datetime.datetime(2020, 3, 18, 9, 00, 00).strftime("%T") < "10:00:00"
Out[3]: True

So {% if now().strftime('%T') < '21:30:00' %} will work without issues.

I don’t think you understood my post. He was comparing a datetime object to a string. They are not comparable.

EDIT: Just to clarify for you. that would be eqivalent to:

{% if now() < '21:30:00' %} 

Sure, but you can compare what you get from strftime("%T") with a string as long as you include the leading zeroes. You seem to imply that this shouldn’t be done since you disqualify string comparisons with your example of comparing 9 and 10.

He was very close to the actual solution, which looks like:

- service_template: >
      {% if now().strftime('%T') < '21:30:00' %}
        switch.turn_on
      {% endif %}           
    entity_id: 
      - switch.light_a
      - switch.light_b

actually that solution won’t work because you don’t have an else statement for the service_template, which will result in an error.

The best solution to fit his needs would have just been a string comparision of %H:%M if he’s not using seconds, and place that in a separate conditional check prior to the service call. But you don’t even need that because he can use the normal, non template condition which many people understand better.

- condition: time
  before: '21:30'
- service: switch.turn_on
  entity_id:
  - switch.light_a
  - switch.light_b
  

I have animated solar inverter event and I came up with the following:

#---------------------------------------Inverter Animation-----------------------------------------------#
#---sensor.power - solar power, sensor.pgrid - grid power, sensor.pinverter - battery power -------------#
  - platform: template
    sensors:
      charger_card: 
        value_template: >-
          {% if states.sensor.power.state | float > 50 and states.sensor.pgrid.state | float > -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}     
           1
          {% elif states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}  
           2          
          {% elif states.sensor.power.state | float < 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}   
           3  
          {% elif states.sensor.power.state | float > 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}   
           4
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}    
           5   
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float > -50 and now().strftime('%T') > '7:00:00' and now().strftime('%T') < '18:00:00' %}    
           6   
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float < 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '18:00:00' and now().strftime('%T') < '22:00:00' %}    
           7  
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float > -50 and now().strftime('%T') > '18:00:00' and now().strftime('%T') < '22:00:00' %}    
           8  
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float > -50 and now().strftime('%T') > '22:00:00' and now().strftime('%T') < '23:59:59' %}   
           9
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float > -50 and now().strftime('%T') < '7:00:00' %}   
           9           
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float < 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '22:00:00' and now().strftime('%T') < '23:59:59' %}   
           10
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float < 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') < '7:00:00' %}   
           10           
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') > '22:00:00' and now().strftime('%T') < '23:59:59' %}   
           11
          {% elif states.sensor.power.state | float < 50 and states.sensor.pinverter.state | float > 50 and states.sensor.pgrid.state | float < -50 and now().strftime('%T') < '7:00:00' %}   
           11
          {% else %}
           NONE          
          {% endif %} 
          
#---1 - # solar power, no grid
#---2 - # no solar power, battery power and grid power, day
#---3 - # no solar power, grid power, day
#---4 - # solar power, grid power, day
#---5 - # foggy, battery power, grid power, day
#---6 - # foggy, battery power, day
#---7 - # foggy, only grid power, day
#---8 - # battery power, noon
#---9 - # only battery power, night
#---10 -# only grid power, night
#---11 -# battery and grid power, night         
#-----------------------------------------------END---------------------------------------------------------#

lovelace:

type: picture-glance
title: Inverter animation
entities:
  - sensor.power
state_image:
  '1': /local/gif/inverter/day.gif
  '2': /local/gif/inverter/day_batt_grid.gif
  '3': /local/gif/inverter/day_grid.gif
  '4': /local/gif/inverter/day_grid_solar.gif
  '5': /local/gif/inverter/foggy_batt_grid.gif
  '6': /local/gif/inverter/foggy_batt.gif
  '7': /local/gif/inverter/foggy_grid.gif
  '8': /local/gif/inverter/noon.gif
  '9': /local/gif/inverter/night_battery.gif
  '10': /local/gif/inverter/night.gif
  '11': /local/gif/inverter/night_batt_grid.gif
entity: sensor.charger_card

Not sure if this can be done easier somehow, please check and let me know any other way of animating event based on time of the day.

For future reference, if you use variables within your template, it becomes easier to read and maintain. For example:

  value_template: >-
    {% set power = states('sensor.power') | float %}
    {% set pinv = states('sensor.pinverter') | float %}
    {% set pgrid = states('sensor.pgrid') | float %}
    {% set t = now().hour %}
    {% if power > 50 and pgrid > -50 and 7 <= t < 18 %} 1
    {% elif pinv > 50 and pgrid < -50 and 7 <= t < 18 %} 2
    {% elif power < 50 and pgrid < -50 and 7 <= t < 18 %} 3  
    {% elif power > 50 and pgrid < -50 and 7 <= t < 18 %} 4
    {% elif power < 50 and pinv > 50 and pgrid < -50 and 7 <= t < 18 %} 5
    {% elif power < 50 and pinv > 50 and pgrid > -50 and 7 <= t < 18 %} 6
    {% elif power < 50 and pinv < 50 and pgrid < -50 and 18 <= t < 22 %} 7
    {% elif power < 50 and pinv > 50 and pgrid > -50 and 18 <= t < 22 %} 8
    {% elif power < 50 and pinv > 50 and pgrid > -50 and t >= 22 %} 9
    {% elif power < 50 and pinv > 50 and pgrid > -50 and t < 7 %} 9     
    {% elif power < 50 and pinv < 50 and pgrid < -50 and t >= 22 %} 10
    {% elif power < 50 and pinv < 50 and pgrid < -50 and t < 7 %} 10  
    {% elif power < 50 and pinv > 50 and pgrid < -50 and t >= 22 %} 11
    {% elif power < 50 and pinv > 50 and pgrid < -50 and t < 7 %} 11
    {% else %} NONE          
    {% endif %}
2 Likes

Thanks will take into reference!