I have added a template in a blueprint
{{ ((strptime(states(next_t), "%H:%M:%S")).replace(day=now().day, year=now().year, month=now().month, hour=strptime(states(next_t), "%H:%M:%S").hour - retry_t | int)).time() }}
With next_t being a variable that stores the selected input from the time helpers and retry_t does the same with number helpers.
When I try it with in the Developer/Template environment with the helpers added manually, it works flawlessly. However, when I use it in a blueprint, it says that a value was expected but got none.
The full blueprint here
blueprint:
name: HVAC Daily Schedule, local version
description: Set the target HVAC temperature based on its mode.
domain: automation
input:
climate_id:
name: Thermostat
description: The thermostat to control.
selector:
entity:
domain: climate
multiple: false
cooling_temp:
name: Cool Set Point
description: The target temperature when cooling.
selector:
entity:
domain: input_number
multiple: false
#selector:
#number:
#min: 0.0
#max: 100.0
#step: 1.0
#mode: slider
#unit_of_measurement: "°C"
heating_temp:
name: Heat Set Point
description: The target temperature when heating.
selector:
entity:
domain: input_number
multiple: false
#selector:
#number:
#min: 0.0
#max: 100.0
#step: 1.0
#mode: slider
#unit_of_measurement: "°C"
set_temp:
name: Current selected temperature
description: The input that stores the currently selected temperature
selector:
entity:
domain: input_number
multiple: false
set_mode:
name: Current selected climate mode
description: The input that stores the currently selected climate mode
selector:
entity:
domain: input_select
multiple: false
at_time:
name: Time
description: The time to update this device
selector:
entity:
domain: input_datetime
# selector:
# time: {}
next_time:
name: Next schedule
description: The next scheduled time of this automation. If this is e.g. \"Daytime\" then you should select \"Nighttime\" here.
selector:
entity:
domain: input_datetime
retry_timeout:
name: Retry timeout
#description: How many hours before the selected next schedule the automation times out
description: When the automation times out.
#selector:
# time: {}
#selector:
# number:
# min: 1.0
# max: 4.0
# step: 1.0
# mode: slider
# unit_of_measurement: "Hours"
selector:
time: {}
on_monday:
name: Monday
default: true
selector:
boolean: {}
on_tuesday:
name: Tuesday
default: true
selector:
boolean: {}
on_wednesday:
name: Wednesday
default: true
selector:
boolean: {}
on_thursday:
name: Thursday
default: true
selector:
boolean: {}
on_friday:
name: Friday
default: true
selector:
boolean: {}
on_saturday:
name: Saturday
default: true
selector:
boolean: {}
on_sunday:
name: Sunday
default: true
selector:
boolean: {}
source_url: http://localhost
variables:
weekly_schedule:
- !input on_monday
- !input on_tuesday
- !input on_wednesday
- !input on_thursday
- !input on_friday
- !input on_saturday
- !input on_sunday
heating_t: !input heating_temp
cooling_t: !input cooling_temp
current_m: !input climate_id
next_t: !input next_time
retry_t: !input retry_timeout
trigger:
- platform: time
at: !input at_time
condition:
- condition: template
value_template: '{{ weekly_schedule[now().weekday()] }}'
action:
- if:
- condition: and
conditions:
- condition: time
before: !input "retry_timeout"
#before: '{{ ((strptime(states(next_t), "%H:%M:%S")).replace(day=now().day, year=now().year, month=now().month, hour=strptime(states(next_t), "%H:%M:%S").hour - retry_t | int)).time() }}'
- condition: state
entity_id: !input "climate_id"
state: unavailable
then:
- repeat:
until:
condition:
- condition: time
before: !input "retry_timeout"
#before: '{{ ((strptime(states(next_t), "%H:%M:%S")).replace(day=now().day, year=now().year, month=now().month, hour=strptime(states(next_t), "%H:%M:%S").hour - retry_t | int)).time() }}'
sequence:
- if:
condition:
- condition: state
entity_id: !input "climate_id"
state: unavailable
then:
- delay: 00:01:00
else:
- choose:
- conditions:
- condition: state
entity_id: !input "climate_id"
state: heat
sequence:
- service: climate.set_temperature
entity_id: !input "climate_id"
data:
temperature: '{{ states(heating_t) | float }}'
- service: input_number.set_value
entity_id: !input "set_temp"
data:
value: '{{ states(heating_t) | float }}'
- service: input_select.select_option
entity_id: !input "set_mode"
data:
option: '{{ states(current_m) }}'
- conditions:
- condition: state
entity_id: !input "climate_id"
state: cool
sequence:
- service: climate.set_temperature
entity_id: !input "climate_id"
data:
temperature: '{{ states(cooling_t) | float }}'
- service: input_number.set_value
entity_id: !input "set_temp"
data:
value: '{{ states(cooling_t) | float }}'
- service: input_select.select_option
entity_id: !input "set_mode"
data:
option: '{{ states(current_m) }}'
else:
if:
- condition: and
conditions:
- condition: time
before: !input "retry_timeout"
#before: '{{ ((strptime(states(next_t), "%H:%M:%S")).replace(day=now().day, year=now().year, month=now().month, hour=strptime(states(next_t), "%H:%M:%S").hour - retry_t | int)).time() }}'
- not:
- condition: state
entity_id: !input "climate_id"
state: unavailable
then:
- choose:
- conditions:
- condition: state
entity_id: !input "climate_id"
state: heat
sequence:
- service: climate.set_temperature
entity_id: !input "climate_id"
data:
temperature: '{{ states(heating_t) | float }}'
- service: input_number.set_value
entity_id: !input "set_temp"
data:
value: '{{ states(heating_t) | float }}'
- service: input_select.select_option
entity_id: !input "set_mode"
data:
option: '{{ states(current_m) }}'
- conditions:
- condition: state
entity_id: !input "climate_id"
state: cool
sequence:
- service: climate.set_temperature
entity_id: !input "climate_id"
data:
temperature: '{{ states(cooling_t) | float }}'
- service: input_number.set_value
entity_id: !input "set_temp"
data:
value: '{{ states(cooling_t) | float }}'
- service: input_select.select_option
entity_id: !input "set_mode"
data:
option: '{{ states(current_m) }}'
else:
- stop: Still unavailable
mode: single
If there’s a better way to achieve what I’m trying to do (subtract from time) I’m very interested as it’s very clunky. I know it’s a bit convoluted, I thought that by converting time to datetime it would handle rollovers i.e. 00:00:00 - 1 would become 23:00:00 but it just became -1 and therefore an invalid time so it’s more than needed.