When do made-up sensors get re-evaluated?

Hi -

I have a template sensor which doesn’t seem to be updating - so I guess the first question that I have is “when are they updated?”

This is in my sensors.yaml:

  - platform: template
    sensors: 
      (... a couple of other sensors...)

      time_of_day:
        friendly_name: 'Time of Day'
        entity_id:
          - sensor.time_of_day
        value_template: >-
          {% if as_timestamp(now()) >= as_timestamp(now().date() ~ ' 00:00:00') and as_timestamp(now()) < as_timestamp(now().date() ~ ' 06:00:00') %}
          wee_hours
          {% elif states.sun.sun.state == 'above_horizon' and as_timestamp(now()) < as_timestamp(now().date() ~ ' 12:00:00') %}
          morning
          {% elif states.sun.sun.state == 'above_horizon' and as_timestamp(now()) >= as_timestamp(now().date() ~ ' 12:00:00') %}
          afternoon
          {% elif states.sun.sun.state == 'below_horizon' and now().date() == states.sun.sun.attributes.next_rising | truncate(10, True, '') %}
          twilight
          {% elif states.sun.sun.state == 'below_horizon' and as_timestamp(now()) < as_timestamp(now().date() ~ ' 18:00:00') %}
          early_evening
          {% elif states.sun.sun.state == 'below_horizon' and as_timestamp(now()) < as_timestamp(now().date() ~ ' 20:30:00') %}
          evening
          {% elif states.sun.sun.state == 'below_horizon' and as_timestamp(now()) >= as_timestamp(now().date() ~ ' 20:30:00') %}
          late_evening
          {% else %}
          nobody_knows
          {% endif %}

When I run that whole template in the dev tools it says afternoon, which is right. On my view which has this, it says morning. When I run {{ states.sensor.time_of_day }} through the template tool it says:

<template state sensor.time_of_day=morning; friendly_name=Time of Day @ 2018-02-04T10:06:01.452237-05:00>

This is probably the last time I bounced my container.

What might be going on here? What causes made-up sensors like this to get re-evaluated?

Thanks,

-jamie

Strange, when I run it today it still points implies that the last time that it was run was yesterday morning:
<template state sensor.time_of_day=morning; friendly_name=Time of Day @ 2018-02-05T07:52:19.666247-05:00>

Not sure, but as long as i know, template sensors only update if an entity in the value_template changes it’s state.
In the moment your template get’s only evaluated on sun state change.
You could use the time_date sensor to replace the as_timestamp(now()) in your template.

Thanks, that is very helpful!

I wrote a helper sensor so I didn’t have to do the math a bunch of times:

      current_time_float:
        entity_id:
          - sensor.current_time_float
        value_template: >-
          {{ (states.sensor.time.state.split(':')[0] | float) + (states.sensor.time.state.split(':')[1] | float / 60) }} 

then switched it to :

      time_of_day:
        friendly_name: 'Time of Day'
        entity_id:
          - sensor.time_of_day
        value_template: >-
          {% if ((states.sensor.current_time_float.state | float) > 0) and ((states.sensor.current_time_float.state | float) < 6) %}
          wee_hours
          {% elif ((states.sun.sun.state == 'above_horizon') and ((states.sensor.current_time_float.state | float) < 12.0)) %}
          morning
          {% elif ((states.sun.sun.state == 'above_horizon') and ((states.sensor.current_time_float.state | float) > 12.0)) %}
          afternoon
          {% elif states.sun.sun.state == 'below_horizon' and now().date() == states.sun.sun.attributes.next_rising | truncate(10, True, '') %}
          twilight
          {% elif ((states.sun.sun.state == 'below_horizon') and ((states.sensor.current_time_float.state | float) < 18.0)) %}
          early_evening
          {% elif ((states.sun.sun.state == 'below_horizon') and ((states.sensor.current_time_float.state | float) < 20.5)) %}
          evening
          {% elif ((states.sun.sun.state == 'below_horizon') and ((states.sensor.current_time_float.state | float) >= 20.5)) %}
          late_evening
          {% else %}
          nobody_knows
          {% endif %}

And it at least looks like it is updating in the interface.

Thanks again!

We will see if the lights turn off :wink:

I might refactor once I give it more thought

1 Like

Well this morning it still says afternoon, so something still doesn’t work.

No, that was unintentional, thanks for pointing it out.

I gave up and deleted all of those sensors from my setup.

I know this is late to the party but…

ha_config_uptodate:
    value_template: '{{ states("sensor.ha_config_current") == states("sensor.ha_config_last") }}'

I don’t get what you are trying to do with this sensor… what is making those 2 sensors in the states()? if its a component, then those states should return a string, and the strings need to match exactly.

alarmtime:
        value_template: '{{ now().strftime("%H:%m") == states("input_datetime.wakeup")[:-3] }}'

This one seems odd to me. According to the docs, you can pull the hour and minute out. So why wouldn’t you do this:

alarmtime:
  value_template: '{{ now().hour == states.input_datetime.wakeup.attributes.hour && now().minute == states.input_datetime.wakeup.attributes.minute}}'

I’ve never used the input_datetime object before but the documentation lead me to believe its the same as the now() object. Maybe give that a whirl?

These sensors should update every time something they reference updates.

I’m not sure a true/false equals on/off. You may need to do this:

ha_config_uptodate:
    value_template: >
      {% if states('sensor.ha_config_current') == states('sensor.ha_config_last') %}
        'off'
      {% else %}
        'on'
      {% endif %}

This should update whenever sensor.ha_config_current or sensor.ha_config_last changes.

do these sensors even work? sensor.ha_config_current, sensor.ha_config_last

In the template editor, what is returned when you use:

{{ states(“sensor.ha_config_current”) }}
{{ states(“sensor.ha_config_last”) }}

For me, I get:

does {{ states(“sensor.ha_config_current”) ==states(“sensor.ha_config_last”) }}
evaluate as true?

It looks like they are both strings and it should evaluate as true. If it does, then you should watch and see when each of these sensors change. You should be able to see it in history. If the sensors aren’t changing, then any sensor based on them won’t change.

I wonder if the event is getting suppressed somehow? Have you ran with logger in debug? It’s going to make your hass.log file huge but you’ll get to see all the crap firing back and forth.

the dash just removes whitespace. The way he is using it is useless and doesn’t modify the expression. If he used it during a for loop, it would remove the carriage return between each object.