TL;DR: time-based template sensor is changing it’s value at the time that isn’t configured in the template.
long story:
I’ve got a time-of-day template sensor based on fixed hours and on sun setting time, that I use almost everywhere across my config. the main use is of course light scenes for rooms, bathrooms etc. I’ve got an automation that based on this sensor’s change and value, triggers an action to change input_select with scenes, and then an automation that is triggered by the input_select & it runs a script for scenes change. input_selects are just because sometimes I want to change the scene by hand - and they are not relevant for the problem I’m having (I guess), so we don’t have to worry about it for now
each part of day is configured as being from X:XX to Y:YY. I’m using “minutes after midnight” count, so the conditions would be easier to check. one time [day end/dusk start] is based on the time of next sun setting. there are some time shifts for weekend and dusk-based scening, but it’s just adding or substracting some minutes. there’s also a “fix” if something starts before midnight, but ends after [24 hrs = 1440 minutes are added to compensate that difference].
everything works fine at hours configured by my list, but there are some strange things happening during hours not configured in the “parts of day” list, when the sensor turns on to the “before value” - example below.
a typical, regular day:
- OK: at 6:30, “morning” is turned on, and it should last to 9:45.
- BUG: then, at 7:00, “sleep” pops in, of course all “sleep” automations are triggered [lights turns off etc.]
- next, at precisely 7:00:01, “morning” comes back [everything’s “back to normal” but that one-second change makes lights blink, or some of them, turned on by hand - are kept off]
- OK: at 9:45, “day” turns on
- BUG: at 10:00, “morning” turns on [also with triggering the “morning” automations and routines]
- at precisely 10:00:01, “day” comes back [again, new triggers]
- OK: at 21:00, “evening” turns on
- OK: at 22:45, “night 3” turns on
- BUG: at 23:00, “evening” comes back [triggers…]
- at precisely 23:00:01, “night 3” comes back
- OK: at 23:30, “night 2” turns on
- BUG: at 0:00, “night 3” comes back [triggers…]
- OK: at precisely 0:00:01, “night 1” turns on
- OK: at 0:30 “sleep” turns on without problems
I tried those times in the template tab of developer tools in the dashboard and it looks to be working fine… I have NO IDEA why there’s sensor change at 7:00 and 23:00 as those hours are not on the list… either I’m stupid/blind and can’t find the error in my template [despite that it works fine in template tester] or there’s something baked in the HomeAssistant that I’m not aware of. fun fact: my brother uses the same sensor [with different hour configurations] and he’s experiencing the same anomalies at 7 and 23hrs, so it’s not like the rest of my config is playing with me - our configurations are somewhat different.
my sensor’s yaml below. PLEASE somebody help in my misery…
sensor:
- platform: template
sensors:
0_cfg_tod:
value_template: >-
{# #################### current time, sensor & now() based to ensure updates -#}
{%- set t_now = states('sensor.time_date')[:2]|int*60 + now().minute|int -%}
{# #################### time shift for the weekend, so we can sleep/party little bit longer -#}
{%- set t_weekend = 30 if is_state('binary_sensor.0_cfg_weekend', 'on') else 0 -%}
{# #################### time shift for the dusk - start scene even before sunset -#}
{%- set t_before = 45 -%}
{# #################### parts of day -#}
{%- set t_list = {
0:{0:'# info ##########', 1:'# name ##########', 2:'# start #########'},
1:{0:'# 06:30 - 09:45 #', 1:'morning', 2:(6*60)+30},
2:{0:'# 09:45 - sett. #', 1:'day', 2:(9*60)+45},
3:{0:'# sett. - 21:00 #', 1:'dusk', 2:((as_timestamp(state_attr('sun.sun', 'next_setting'))|timestamp_custom("%H", false)|int*60)+(as_timestamp(state_attr('sun.sun', 'next_setting'))|timestamp_custom("%M", false)|int))-t_before-t_weekend},
4:{0:'# 21:00 - 22:45 #', 1:'evening', 2:(21*60)+0},
5:{0:'# 22:45 - 23:30 #', 1:'night 3', 2:(22*60)+45},
6:{0:'# 23:30 - 00:00 #', 1:'night 2', 2:(23*60)+30},
7:{0:'# 00:00 - 00:30 #', 1:'night 1', 2:(0*60)+0},
8:{0:'# 00:30 - 06:30 #', 1:'sleep', 2:(0*60)+30}
} -%}
{# #################### conditions loop -#}
{%- set t_tod = namespace(current=0) -%}
{%- for t in range(1, t_list|length) -%}
{# #################### pair last t_list value with first -#}
{%- set n = 1 if loop.last else t + 1 -%}
{# #################### read values from list -#}
{%- set t_start = t_list[t][2]|int + t_weekend -%}
{%- set t_stop = t_list[n][2]|int + t_weekend -%}
{# #################### "starts before midnight, ends after" fix -#}
{%- set t_temp = 1440 if (t_stop<t_start) else 0 -%}
{%- set t_stop = t_stop + t_temp -%}
{%- set t_now = t_now + t_temp if ((t_now < t_start) and (t_now < t_stop)) else t_now -%}
{# #################### check if current time fits in conditions -#}
{%- if ((t_now >= t_start) and (t_now < t_stop)) -%}{%- set t_tod.current = t_list[t][1] -%}{%- endif -%}
{%- endfor %}
{# #################### return sensor value -#}
{{ t_tod.current }}
icon_template: >-
{# #################### icon config -#}
{%- set t_icons = {
'morning': 'mdi:weather-sunset-up',
'day': 'mdi:weather-sunny',
'dusk': 'mdi:weather-sunset',
'evening': 'mdi:weather-sunset-down',
'night 3': 'mdi:brightness-1',
'night 2': 'mdi:brightness-2',
'night 1': 'mdi:brightness-3',
'sleep': 'mdi:weather-night'
} -%}
{{ t_icons[states('sensor.0_cfg_tod')] if states('sensor.0_cfg_tod') in t_icons.keys() else 'mdi:weather-sunny' }}
attribute_templates:
tod_value: >-
{# #################### numeric tod state -#}
{%- set t_numeric = {
'morning': 1,
'day': 2,
'dusk': 3,
'evening': 4,
'night 3': 5,
'night 2': 6,
'night 1': 7,
'sleep': 8
} -%}
{{ t_numeric[states('sensor.0_cfg_tod')] if states('sensor.0_cfg_tod') in t_numeric.keys() else 2 }}
(as you can see, first row [0:{}], and first column [0:’’] are ignored - it’s only an information, so my config looks more like a table and is easier to edit/understand starting hours.)