I have the following binary sensor which should return true if the current time falls in between the values of two input_datetime entities. If I set the “end” input_datetime to the current time the sensor reports True as expected. However, when the time moves past the end time the sensor still reports true.
I actually have an additional input_boolean as part of this binary_sensor (not shown) and if I turn it off and on after the time progresses the sensor reports the correct value.
Why isn’t the sensor updating every time “now().strftime(’%H%M’)” changes? Any ideas on how I can fix this?
range_sensor:
value_template: "{{
((states.input_datetime.starttime.attributes.timestamp | timestamp_custom('%H%M', False) | int ) | int <= (now().strftime('%H%M') | timestamp_custom('%H%M', False) | int)) and
((states.input_datetime.endtime.attributes.timestamp | timestamp_custom('%H%M', False) | int ) | int >= (now().strftime('%H%M') | timestamp_custom('%H%M', False) | int)) }}"
Because it doesn’t change (in the way you think it does).
now() is a function, not an entity. An entity has a state that Home Assistant can monitor for changes. A function produces a result when executed and at no other time.
You should be able to replace now() with as_timestamp(states(‘sensor.time’)) and get roughly the same result because sensor.time is an entity that will trigger the template to get recalculated.
What Steve said or add this to the Template Sensor’s configuration:
entity_id: sensor.time
Now the template will be evaluated every minute because you’ve instructed Home Assistant to monitor the state-changes for sensor.time (which changes every minute).
Ensure you define sensor.time in your configuration file (see docs).
So far, all three responders have suggested that you incorporate sensor.time
So put : -
Into your sensor, in line with the value_template but above it.
When I get home I’ll look at the whole template and see if it can be optimised. But sometimes ‘optimising’ can make it less readable and so harder to maintain.
It may be best just to get it working, as your current template reflects the way ‘your’ mind works and so you’ll be more comfortable with that.
Why convert it to a time stamp? Just use it as a string
Eg “{{ states(time.sensor) == states(‘input_datetime.start_time’) [0:5]}}”
This gets rid of the seconds to allow a direct comparison
or just use : -
now().weekday()
This returns the weekday number, 0 being Monday, 6 being Sunday
This is quick, easy and compact; to use in templates, but if you need Monday or Mon use : -
as_timestamp(now()) | timestamp_custom(’%A’)
or
as_timestamp(now()) | timestamp_custom(’%a’)
You already have the update from sensor.time so you don’t need the update from sensor.date
Looking at your whole template I think you don’t need sensor.time as sensor.date will do (you don’t have any time values that I can see)
Anyway, I’m not sure (because I don’t have any input_datetime’s with dates so you will have to check and edit the text strings accordingly) but I’d go with : -
mon_5:
enitity_id: sensor.date
value_template: "{{ (is_state('input_boolean.mon_5', 'on') and (now().weekday() == '0') and (states('input_datetime.monstart_date_5') == states('input_datetime.monend_date_5') or (states('input_datetime.monstart_date_5') <= states('sensor.date') <= states('input_datetime.monend_date_5'))) }}"
And I think you may be able to get away without the entity_id: bit too (as it’s in the template)
Edit: As I said, I can’t test this so you will have to test it yourself and feedback any issues - But it seems to me that you have here the following : -
Monday Binary enabled AND it’s a Monday AND ((start == end) OR (start <= today <= end))
Which seems odd to me, I’d have gone with
(Monday is enabled and it’s a Monday) or (it’s a Monday between these two dates)
mon_5:
enitity_id: sensor.date
value_template: "{{is_state('input_boolean.mon_5', 'on') and (now().weekday() == '0') or (states('input_datetime.monstart_date_5') <= states('sensor.date') <= states('input_datetime.monend_date_5')) }}"
Edit2: I’ve messed up with the brackets here, so check the brackets carefully
This example should meet the requirements you’ve described.
The template determines if the current time (represented as a timestamp) falls within a start datetime and an end datetime (also represented as timestamps).