Condition template to execute between two times (input variables)

Greetings folks,

I have an automation that works at the moment. It uses a ‘dumb’ heater and a temperature sensor to maintain the heat in a room at night within a heat band of +/- 1 degree ©.

- id: 'reading_night_heat_band'
  alias: Reading Room - Maintain heat at 18 degrees during night
  description: 'Heat bands for reading room - Night'
  trigger:
    platform: time_pattern
    minutes: "/1" 
  condition: # night and too cold - turn on heat
    condition: time
    after: '19:00:00'
    before: '07:00:00'
  action:
    service_template: >
      {% if states('sensor.temperature_158d0003928807')|float > states('input_number.reading_room_night_temp')|float +1 %} script.turn_off_heater
      {% elif states('sensor.temperature_158d0003928807')|float < states('input_number.reading_room_night_temp')|float -1 %} script.turn_on_heater
      {% else %} script.dummy
      {% endif %}

But I would like to change the time range to use an input variable that I have in Lovelace. In a perfect world - I’d just use a template which turned the input variable into times and replace these two lines

    after: '19:00:00'
    before: '07:00:00'

But I am aware that you can’t use templates here to replace values with input variables.
So I tried to write a condition template… something like this…

{{strptime(states("sensor.time_reading_on"), '%H%M') < strptime(states("sensor.time"), '%H%M') < strptime(states("sensor.time_reading_off"), '%HL%M')}}

But I have been messing around endlessly. When it’s past midnight - the above template evaluates as false - because midnight “00:00” is not considered greater than 7pm. I really want to use the ‘between’ like I have with the hardcoded values - but not sure how to craft this as a template that will work.

I would love it if someone could help me solve this!
Cheers,
-=Lip

Make two conditions out of the one condition. Use an OR condition, either time is after 19:00 OR before 7:00.
Something like this (untested):

condition: 
  - condition: or
    conditions:
      - condition: template
        value_template: "{{ strptime(states('sensor.time_reading_on'), '%H%M') < strptime(states('sensor.time'), '%H%M') }}" 
      - condition: template
        value_template: "{{ strptime(states('sensor.time_reading_off'), '%H%M') > strptime(states('sensor.time'), '%H%M') }}"
1 Like

Burnings solution is the direct answer to your solution (he always delivers :rofl: :+1: )

But I don’t get why you’re doing it this way.

Why not use any change in temperature as the trigger ?
Or better still, use the generic thermostat ? (admittedly you’d then have to set the temperature setpoint according to other criteria, eg (say) 4° if you are out or someone has a door/window open, 17° if between your hours and 15° if not) ?

1 Like

Looking at the above …
If you only ever evaluate the desired output between the two times, then, if it was on when the time expires, it will stay on untill it’s next evaluated (which will be the next time_on condition).

I would still go with the generic thermostat if I was after this functionality.
I don’t like the +/- 1° either and have reduced it to a 0.5 hysteresis (but the template below has been written for clarity and maintenance) and it’s easy to change the hyst value, This will evaluate constantly (well, every minute) and switch on or off accordingly. there is no problem turning a switch that is on, on or one that is off, off.

automation:
  - id: 'reading_night_heat_band'
    alias: Reading Room - Maintain heat at 18 degrees during night
    description: 'Heat bands for reading room - Night'
    trigger:
      platform: time_pattern
      minutes: "/1" 
    action:
      service_template: >
        {% set tme = states('sensor.time') %}
        {% set slt1start = states('input_datetime.time_reading_on') [0:5] %}
        {% set slt1stop = states('input_datetime.time_reading_off') [0:5] %}
        {% set slt1on = (slt1start <= time < slt1stop) if (slt1start < slt1stop) else (slt1start <= time or time < slt1stop) %}
        {% set snsr = states('sensor.temperature_158d0003928807') | float %}
        {% set trgt = states('input_number.reading_room_night_temp') | float %}
        {% set crnt = is_state('switch.reading_room_heater', 'on') %}
        {% set hyst = 0.5 %}
        {% set hon = true if (snsr < trgt - hyst) else false %}
        {% set hold = true if ((trgt - hyst) <= snsr <= (trgt + hyst)) else false %}
        {% set hon = true if (hon or (hold and crnt)) else false %}
        {% set rslt = (slt1on and hon) %}
        {% if rslt %}
          switch.turn_on
        {% else %}
          switch.turn_off
        {% endif %}
      entity_id: switch.reading_room_heater

Note :

  1. This has been written for ‘packages’ so you will most likely have to reduce the line spacing (beginning of each line) by 2
  2. There is ONLY 1 ‘automation:’ header (again, unless you are using packages) do not duplicate this line
  3. I have assumed the name of the heater switch, correct as required.
  4. I am using string comparisons for the time, these WILL work (and make the template simpler) but are not date aware ( [0:5] truncates the value to ignore seconds to match sensor.time )
  5. I have used your input_number as the target temperature (you can adjust this to other conditions as discussed above)
  6. I have ‘assumed’ two off, input_datetime’s (has_date: false (or just leave out)) for the start and stop times, they check if wrap_around midnight is required so will perform as stated (on = on and off as off, no matter the values (though I’ve never tested if you ever set the same time for both) - you have sensors providing times - Why ? Date times are easier to set and not bad on the eye.
  7. Beware of 00:00 as automations ‘sometimes’ interact unpredictably with this as a value.
  8. I do not have these entities so could not test this in anger, it should work but if you have problems come back.
  9. The above checks every minute as did yours. given the thermal inertia of your room and power of your heater, you may be better triggering on sensor (temp change). Mine update given a delta T or minimum time. But that would only reduce evaluations by a factor of 5 and 1/minute is trivial.
  10. You can get rid of your scripts as well now
  11. Why are your temperature sensor names so obscure ???
  12. The logic is a bit complicated by your need to incorporate hysteresis (which is incorporated into the generic thermostat)

Edit1 20200623 12:11GMT : found an error, corrected above

1 Like

Perhaps split the problem up? I do a similar thing with a binary sensor that decides if the heating is in day or night mode based of three input_datetimes. Lovelace frontend:

image

The binary sensor (uses workday integration):

binary_sensor:
  - platform: template
    sensors:
      heating_daytime:
        friendly_name: "Heating in daytime mode"
        entity_id:
          - sensor.time
          - input_datetime.weekday_heating_start
          - input_datetime.weekend_heating_start
          - input_datetime.heating_end
        value_template: >-
          {% if states('binary_sensor.workday_sensor') == 'on' %}
            {{ (states('sensor.time') >= states('input_datetime.weekday_heating_start')[0:5]) and (states('sensor.time') < states('input_datetime.heating_end')[0:5]) }}
          {% else %}
            {{ (states('sensor.time') >= states('input_datetime.weekend_heating_start')[0:5]) and (states('sensor.time') < states('input_datetime.heating_end')[0:5]) }}
          {% endif %}

and one of the three automations (day setting week, day setting weekend, night setting). This one triggers when the binary sensor above turns on, or if any of the relevant settings are adjusted whilst the sensor is already on, and only if it’s the weekend (or public holiday), setting the climate set point to the daytime temperature:

- id: '1588162183825'
  alias: Central heating day setting (weekend)
  description: ''
  trigger:
  - platform: state
    entity_id: binary_sensor.heating_daytime
    to: 'on'
  - entity_id: input_number.heating_day_temperature
    platform: state
  - entity_id: input_datetime.weekend_heating_start
    platform: state
  - entity_id: input_datetime.heating_end
    platform: state
  condition:
  - condition: state
    entity_id: binary_sensor.heating_daytime
    state: 'on'
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: 'off'
  action:
  - data_template:
      temperature: "{{ states('input_number.heating_day_temperature') }}"
    entity_id: climate.central_heating
    service: climate.set_temperature

I could probably combine these, but no point.

Generic thermostat can be set to 0.5°C resolution, and hysteresis adjusted to 0.1°C precision via cold_tolerance and hot_tolerance settings. I have mine set to ±0.2°C which works well with my central heating.

1 Like

Thank you so much everyone!

Mutt’s very tidy automation is much better than what I kludged together… so I might try to work more that way in the future - I like having all the evaluations in the action rather than a condition template. For now I have a condition value template that looks like this for my night band. It’s a bit of a hack - essentially testing if it’s ‘not’ the day band (which all has time that doesn’t cross midnight - so easy to do an integer operation)

 condition: # night band and too cold - turn on heat
    condition: template
    value_template: >
      {{ not (states("input_datetime.heat_band_day_begins")[0:2] |int  < now().hour and states("input_datetime.heat_band_day_ends")[0:2] |int > now().hour) }}

Thanks folks - love the support here! I’m going to re-write as a service_template when I get the chance - that seems to provide a better readable structure for evaluation and execution.

Cheers, -=Lip

Okay, so you test for ‘day time hours’, invert that and use it to then switch.
This will still leave the switch in it’s last state (when the window closes) which therfore could be on all day ???

Sorry… I STILL have my action template…
So I am using my condition template to determine whether I am in a day heat band (warmer) and whether I’m in a night heat band (cooler) - in separate automations. :anguished:. Then I use the service template to decide what to do with the heater. I much prefer how you managed to get ALL the logic for day and night bands AND heater control in the service template - and that’s where I’d like to end up!

Okay, you should always work at your own pace and only dick with stuff you understand so you have a plan and that’s fine.
:+1:
But for my curiosity, why do you have “sensor.temperature_158d0003928807” ?

Why not rename it to “sensor.temperature_reading_room” or similar ???

Sorry, a little feedback on your plan vs what I do.

My heating (uses the generic thermostat, I know I keep banging on about it :rofl: ).
Any time the input number target temp value changes there is an automation fires to squirt that into the the set point. Done.
I then change the input number according to my needs,
Frost Protection is absolute minimum - 4° (sorry, that looks like a negative number, it’s not ! )
If doors/windows open - 4° (4° is basically meant to be off, but with frost protection :roll_eyes: )
if we are beyond 12km (from house) - 4°
If anybody (from the house) is within 12km - 15°
If the house is occupied and at night - 17°
If the house is occupied and during the day - 17.5°
If the house is occupied and evening - 18°

The heating runs 24/365 but the last time it actually ran the boiler was 3 days 18 hours and 18 mins ago (for 42 mins ‘on’ time)
It’s simple, comfortable and forgettable.
Try not to write automations for specific time bands write one for all and then tweak the knob by what you want to happen.
This will save a LOT of time and the WAF is exponential
:rofl:

If you wish, you can write that template this way. The variables serve to make the final line shorter and easier to comprehend what is the time range.

 condition: # night band and too cold - turn on heat
    condition: template
    value_template: >
      {% set begins = states("input_datetime.heat_band_day_begins")[0:2] | int %}
      {% set ends = states("input_datetime.heat_band_day_ends")[0:2] | int %}
      {{ not (begins < now().hour < ends) }}

You’ll notice that final line has no logical AND. It is implicit because the current hour is sandwiched between begins and ends. The current hour must be greater than begins and less than ends (the not obviously takes the opposite of the result).

Also, you may want to take a closer look at Troon’s suggestion. Had it not been presented, that’s what I would’ve suggested. Use Generic Thermostat to control the heater and a separate automation to control the Generic Thermostat’s operating schedule.

  • The Generic Thermostat manages the heater and maintains the temperature at a given setpoint. Much of the arithmetic you’re doing is already handled by Generic Thermostat. It lets you specify cold_tolerance and hot_tolerance which determine the ‘deadband/hysteresis’ (i.e. amount of variance from the setpoint temperature before heating is enabled/disabled). Plus this entity is rendered as a proper thermostat in the UI (as opposed to merely a toggle switch).

  • The automation manages the thermostat’s schedule using either fixed or variable hours and days based on input_datetime, input_booleans, workday sensor, or whatever else you wish to use to specify a schedule. The automation’s action simply sets the thermostat’s hvac_mode to either heat or off.

I’m genuinely interested. But. What’s the difference between turning the heating ‘off’ vs setting the setpoint to a low level such that it shouldn’t ever come on to service the requirement ?

My boiler switch has a manual over-ride (I’ve not ever needed it yet but if needs be I can just manually force (switch) it on and set the boiler to operate in timed mode instead. During testing though I went through some issues (switching mode) where ‘heat’ and ‘off’ collided such that it just wouldn’t work. I spent an hour or so fruitlessly diagnosing the issue before giving up (I needed the heat on). But if you could educate me (re: the benefits of mode) I’d appreciate it.

I guess there’s little practical difference when controlling a simple source of heating or cooling. If the heater had some sort of temperature or activity indicator (an LCD display or simple indicator light) I would expect it to continue to display status if hvac_mode is set to off. In contrast, if I set its master power switch to off then I would expect its indicator to be disabled as well.

Hmmm !
My boiler switch does not have such an indicator nor does my danfoss thermostat (though I’m now using a qubino thermostat and that doesn’t even have a display)
I have configured a binary_sensor to display the switch with a pause symbol if the temperature is above set point (and switch is off) else fire symbol if heat being called. That’s the best I’ve got
No biggie.
Thanks

Thanks everyone for all your help…
I’m still learning here and JUST started to use input variables!
My latest challenge - which I’ve already wasted probably 2 hours trying to understand.

I have a input variable for start time and then an input variable for time length.
E.g. Start time is 02:00 and length is 10 hours
I’m struggling to figure out how to ‘add 10 hours’ to 02:00 and then create a sensor which shows 12:00 as a time. It sounds so SIMPLE - but to do this I think I need to convert ‘time’ to integers, perform an integer operation and then craft a formatted ‘time’ for my sensor - so that when time length changes - the sensor updates and displays the end time.

I’ve tried using my very small box of tools - converted the time to an integer (2) , added 10 to that… but then turning (12) into 12:00 is escaping me!

How would the brains trust essentially ‘add x hours to a time input variable and create an end time’?? Thanks in advance!!

Time stamps are measured in seconds, since the Unix epoch which is accepted to be Jan 1st 1970
So adding 10 hours is timestamp(now()) + 10 * 60 * 60
It’s debatable how you store this
Having a 10 hour delay or timer is ‘ropey’ as it won’t survive a restart
You might just be best having two datetime’s, set the first and an automation sets the second for you (it might need to be date aware but probably not)

Edit, ideally you should start a new topic for a new problem. Though the question is quite common, have you searched the forum ?

1 Like

Thanks @Mutt

I have done lots of trawling to find solutions - came close… Agree this is a bit off the original topic - but is also time management and calcs… but a bit different.

Yeah I have three things - which are controlling this…
An inital start time (HH:MM) - input variable set in the UI
An ‘length’ input variable - with two possibilities (12 hours or 18 hours)
A sensor ‘calculated end time’ - which I would like to be -
‘start time’ + length in format (HH:MM)

I found posts that did something like this…

{{(states('sensor.time_lamp_on').strftime("%s") | int + (15*60) | timestamp_custom("%H:%M")  }}

But my input_variable (sensor.time_lamp_on) isn’t a time- it’s a string so that doesn’t work for me like it does for now() and I get error - Error rendering template: UndefinedError: ‘str object’ has no attribute ‘strftime’

Yeah… so I don’t want to have a delay for 12 or 18 hours… I’m trying to calculate a sensor with a ‘finish time’ so I can trigger automation off that. Might be a terrible approach - but trying to use the ‘pieces’ I’m familiar with.

Cheers,

-=Lip

Okay, the weird bit about this is your sensor ‘calculated end time’
Three Four questions : -

  1. Why ? - and how is it set ? (events, context etc.)
  2. Paste us your sensor configuration, so we can see what we are dealing with (I have several sensors that basically just display an input_datetime but it’s for font size and not accidentally editable these would all be easily convertable back to timestamps)
  3. From the timing of your posts, I assume you are in Europe ?
  4. You still haven’t answered why your temperature sensors have such obscure names.

Edit:
Extras : To help you with home assistant (not directly linked to this topic) : -
A. What are you running HA on ?
B. What is your workstation (mainly it’s OS)
C. What are you using as an editor ?
D. You haven’t mentioned the GUI editors (thank goodness (as I haven’t a clue, Petro has had a play but most semi-advanced members are past needing it (petro ‘plays’ to help people struggling with it) ) ) So you must have been dabbling with HA for a reasonable amount of time, how long ? (helps me get an idea of your awareness of the landscape)

Edit2: Regardless of your level, anyone dealing with ‘time’ should be aware of finity’s EPIC Time Manipulation thread - virtually the standard reference on the subject.
Just search for it. It may not help you now but you’ll need it before too long.

Edit3: Time never needs converting to integers (unless you are OCD, but then that’s typical of the members here)
:rofl:

Ok… few questions!

  1. Why - this automation is to provide me with a fancy UI for seedlings I am growing in my laundry. I have an arlo camera pointed at them and I’m taking a timelapse and my daughters have grown cucumbers, carrots and cherry tomatoes (currently about 1cm) on a desk with desk lamps and a heat map - from seeds. I want to have a UI for them so they can see all the automation, temperature and humidity - this was a ‘lockdown’ hobby we have done together.

I want to have to lighting presets - vegetative and flowering - and a start time of the day. The girls will set the light time and I’ll be showing them how when we change from vegetative to flowering the lamp isn’t on for as long! Vegetative (18 hours), Flowering (12 hours)

My lamp off time is currently hardcoded - which makes me sad… so instead of changing it once in my code (below) - I’ve spent about 4 hours trying to figure out how to take a start time input_variable and calculate and reference an end time :rofl:

  - platform: template
    sensors:
      time_grow_lamp_off:
        friendly_name: "Grow lamp turn off time"
        # unit of measurement: 'time'
        value_template: >-
          {% if is_state("input_select.growth_cycle", "Vegetative") -%}
          20:00
          {%- else -%}
          14:00
          {%- endif -%}
  1. I’m in Australia - I just only really get to do this stuff in the middle of the night - 2 girls, single parent!
  2. Temperature sensors have terrible names because I only (yesterday) relalised where you can rename them (I have friendly names in UI)! They are Xiaomi zigbee sensors which are connected to a Mija hub.

A. On a Pi 4.

System Health
arch	armv7l
chassis	embedded
dev	false
docker	true
docker_version	19.03.8
hassio	true
host_os	HassOS 4.10
installation_type	Home Assistant
os_name	Linux
os_version	4.19.126-v7l
python_version	3.7.7
supervisor	227
timezone	Australia/Melbourne
version	0.111.4
virtualenv	false
Lovelace
dashboards	1
mode	storage
resources	5
views	9

B. Win 10
C. Visual Studio with HA Config helper Add On
D. I have been playing for about six months I guess - have quite a bit hooked in there - but really just still taking baby steps in the scripting part. Have lighting, plex, motion sensors, Blue Iris, Roborock, Arlo, doors, Kodi, windows, temp, humidity, Google Home etc.

So… the problem in essence (again) - I have a UI set time 02:00 and I want to add either 12 or 18 hours to it based on another UI selection!

Cheers, and thanks for your time helping / welcoming me to the forum.

Okay, There’s a LOT to answer here. The ‘forum software’ doesn’t particularly like ‘multiple answers’ to a single post so I’ll probably reply once and edit it (as you’ve seen) as each step comes up and I address it (so keep checking the thread as you may not get notifications)

Single Parent Dad, Two Girls, Lockdown Project (an interesting / biology / engineering / photographic lockdown project (Proper STEM - I approve) ) = ‘hero’ in my book (but I have low standards :rofl: ) (the equal of the hamster odometer project I’ve seen here too ! )

I’m in the UK but that doesn;t really matter, we have a LOT of excellent members from Oz (to name but a few : tom_l , kanga_who and DavidFW1960 + many others )

One of the biggest obstacles in helping people with automations is overcoming their premise’s (that’s not saying that I don’t have any myself) but about 1/3 of my career has been spent thus, discarding what “they think they want” to get them “what they need” so I generally ask a lot of “Why ?” questions (seeking forgiveness in advance)

Using quotes takes up a lot of space, so I’ll just copy : -

  1. “vegetative / flowering” - Okay, Why is that not : - “Flowering 12hr” and “Vegetative 18hr” just to make it crystal clear ?
  2. “The girls will set the light time” - is that related to 1. ? I mean how do you set the light ‘start’ time ? Do you really want a start time or is it at ‘sunrise’ or do you want the middle of the ‘on’ time to be ‘solar noon’ - how do you wish to proceed ? I see that you’ve set 14:00 and 20:00 as the output so working back you normally have 02:00 as the start time for both. Is there a reason for that ? Don’t you get any natural light ‘spill’ in that location that can then be topped up by the light ? or are you being ‘green’ in trying to use ‘low demand periods’ and therefore reduce generation/distribution demands ? Do the girls not check up on the plants ? When is that likely to be ? Do the lights need to be on at that time ? (you don’t need to answer any of the last. I just need you to consider them). - so (reconsider) start time ???
  3. “sensors have terrible ‘entity’ names” - Yeah ! making the names identifiable makes coding a LOT easier. (see later when I discuss VSC)
  4. A - Okay, B - Okay, C - Excellent D - In which case you are a star ! (Though I think the point of most home automation is not having to deal with it, let it get on with it and interact with it minimally (so tinkering with automations/scripts takes up ALL of your time rather than playing with the interface which then just becomes a universal remote control - For ‘me’ the interface is secondary (my opinion is all - a LOT disagree, as they like to ‘show off’ their fancy remote control :rofl: )
  5. Okay I more or less processed as reading, so I just came across the 02:00 which I’d surmised above

So : -
Changing names - It’s easy with VSC, assuming we are using ‘sensor.temperature_158d0003928807’ as an example, Click on the entity anywhere in the UI, click on the ‘cog’, Open VSC and have it look at your ‘config’ folder via Samba (or however you use it, it should already be pointed there), copy the entiy_id (‘sensor.temperature_158d0003928807’), In VSC got to ‘Edit’ - ‘Replace in Files’, paste sensor.temperature_158d0003928807 into the ‘Search’ box and what you want to rename it as, in the ‘Replace’ box, Hit the ‘Replace All’ button, Copy what you typed into the ‘Replace’ box, Paste that into the entity_id in the browser box you should still have open, Save - Done !
It gets more complicated when you are changing ‘created’ entities as you ‘may’ need to (for example) Search for “temperature_158d0003928807” and replace. but be careful as I have entities such as input_datetime.id_heat_boiler_last_on_time and sensor.s_heat_boiler_last_on_time ie. pretty much the same name. The ‘id_’ denotes input_datetime and ‘s_’ denotes sensor to help differentiate (the ‘heat_’ denotes that the entity is configured in my ‘heat’ package, packages allow ALL items concerned with a particular ‘thing’ (your choice, room, occupancy, heating, etc. ‘as you think best’) to live in a ‘thing’ file so bed1.yaml or climate.yaml or media.yaml etc. within a package everything specific to that ‘thing’ is set - automations, scripts, input_booleans, binary_sensors etc. So I could send you an alarm_clock.yaml and providing you have the necessary dependencies set, eg sensor.time in that case, you have a working alarm clock. I could also send a lovelace card snipet so you can interact with it (editing that to match your needs)

The s_heat_, id_bed1_ etc. helps you identify things, find things and sort things (alphabetically) so I’ll use these conventions, edit as you see fit.

Your ‘sensor’, inherently this is ‘awkward’ to deal with as it’s not ‘standard’ (standard in this case means common UI elements with accepted means of conversion which is the bread and butter of the forum so lots of examples exist to copy from and adapt), so rather than : -

  - platform: template
    sensors:
      time_grow_lamp_off:
        friendly_name: "Grow lamp turn off time"
        # unit of measurement: 'time'
        value_template: >-
          {% if is_state("input_select.growth_cycle", "Vegetative") -%}
          20:00
          {%- else -%}
          14:00
          {%- endif -%}

if you use an automation instead (with two input_datetime 's ) : -

  - id: au_project_plant_growth_lamp_set
    alias: Plant Growth Lamp Set
    description: 'What it says on the Tin'
    trigger:
      - platform: state
        entity_id: input_select.is_project_growth_cycle
      - platform: state
        entity_id: input_datetime.id_project_lamp_start
      - platform: state
        entity_id: input_datetime.id_project_lamp_finish
    action:
      - service: input_datetime.set_datetime
        entity_id: input_datetime.id_project_lamp_finish
        data_template: >
          {# This is a comment #}
          {# This template assumes '02:00' as the start time set from input_datetime.id_project_lamp_start #}
          {# This will set input_datetime.id_project_lamp_finish, which will be manually editable but we could ... #}
          {# ... just add another trigger, if that happens, to 'reset' the input_datetime.id_project_lamp_finish ... #}
          {# ... back again, so it won't matter and it appears that it is 'fixed'. See trigger above #}
          {% set strt = states('input_datetime.id_project_lamp_start') %}
          {% set tsstrt = as_timestamp(now().strftime('%Y-%m-%d ' ~ strt)) %}
          {% set drtn = 12 if is_state('input_select.is_project_growth_cycle', 'Flowering') else 18 %}
          {% set tsfnsh = tsstrt + (drtn * 60 * 60) %}
          {{ tsfnsh | timestamp_custom('%H:%M:00') }}

This is quite advanced, above introduces template comments, note that we convert the start time (anyday) to a specific instant so that we can get a specific instant in the future of that time, then convert it back to an ‘anyday’ value.
This will give you an ‘odd’ error going through DST changes, but you’d have that anyway and it wouldn’t go through that either in the duration 01:01 to 23:59 regardless.

The automation for then switching the lamp ‘on’ becomes : -

  - id: au_project_plant_growth_lamp_on
    alias: Plant Growth Lamp
    description: 'What it says on the Tin'
    trigger:
      - platform: template
        value_template: "{{ states('sensor.time') == states('input_datetime.id_project_lamp_start') [0:5] }}"
    action:
      - service: light.turn_on
        entity_id: light.plant_growth_lamp

Your homework is to do the switch ‘off’ :smiley:

Note that if HA goes down at any switching point the light will remain in it’s previous state. There are ways of dealing with that (I’m also quite lazy). But if you restart because of a config change I used to just check if I’d missed anything and switch it manually.

Phew, that was a long one, I’ll let someone else get on the soap box.

“Oooops !” - Forgot to say, the automation (for setting the finish time) will trigger twice (as it sets ‘A’ then is triggered by ‘A’ ) but thereon ‘A’ doesn’t change so it won’t re-trigger. If you trust your ‘users’ not to mess with the finish time you could remove that trigger.

Oooops2 - VSC also can use ‘rainbow spacing’ and ‘rainbow brackets’ I really recommend the first (for yaml) and I find the second is pretty useful too.

Oooops3 - Again I don’t have these entities - so not tested in anger, but it passes config check and I’ve tested the template in the ‘Developer Tools’ - ‘Template’ section of HA (This is a godsend and should be used a LOT more by everybody) - get back with problems

1 Like