what is the exact logic that you’re trying to achieve which doesn’t work with the above?
the way you currently wrote it, if the time is within one of the ranges, then the condition would return true as at least 1 condition is true (set with OR)
I assumed {{ input_datetime.lounge_ac_am_on_time }}
would have to be in a condition: template
rather than condition: time
to actually evaluate. Though I haven’t tested it yet.
I tested it. It did not work.
Hmm. Not like this either:
- condition: or
conditions:
- condition: template
value_template: {{ (states('sensor.time') >= states.input_datetime.lounge_ac_am_on_time.state) and (states('sensor.time') < states.input_datetime.lounge_ac_am_off_time.state) }}
- condition: time
- condition: template
value_template: {{ (states('sensor.time') >= states.input_datetime.lounge_ac_pm_on_time.state) and (states('sensor.time') < states.input_datetime.lounge_ac_pm_off_time.state) }}
Error loading /config/configuration.yaml: invalid key: "OrderedDict([("(states('sensor.time') >= states.input_datetime.lounge_ac_am_on_time.state) and (states('sensor.time') < states.input_datetime.lounge_ac_am_off_time.state)", None)])" in "/config/automations.yaml", line 569, column 0
Found another way not that does not pass validation:
- condition: or
conditions:
- condition: template
value_template: "{{ (states('sensor.time') >= states.input_datetime.lounge_ac_am_on_time.state[0:5]) and (states('sensor.time') < states.input_datetime.lounge_ac_am_off_time.state[0:5]) }}"
- condition: time
- condition: template
value_template: "{{ (states('sensor.time') >= states.input_datetime.lounge_ac_pm_on_time.state[0:5]) and (states('sensor.time') < states.input_datetime.lounge_ac_pm_off_time.state[0:5]) }}"
You need to add todays date to your input_datetimes and you can use now() to check against. Also, you can just do the check in seconds:
condition:
- condition: template
value_template: >
{% set current_date_string = now().strftime("%Y-%m-%d ") %}
{% set current_time = now().timestamp() %}
{% set lounge_am_start = strptime(date+state('input_datetime.lounge_ac_am_on_time'), '%Y-%m-%d %H:%M').timestamp() %}
{% set lounge_am_end = strptime(date+state('input_datetime.lounge_ac_am_off_time'), '%Y-%m-%d %H:%M').timestamp() %}
{% set lounge_pm_start = strptime(date+state('input_datetime.lounge_ac_pm_on_time'), '%Y-%m-%d %H:%M').timestamp() %}
{% set lounge_pm_end = strptime(date+state('input_datetime.lounge_ac_pm_off_time'), '%Y-%m-%d %H:%M').timestamp() %}
{{ lounge_am_start <= current_time <= lounge_am_end or lounge_pm_start <= current_time <= lounge_pm_end }}
ok, so are you trying to ensure that current time (e.g. now()) is between these timestamps?
If so that’s what you need:
- condition: or
conditions:
- condition: template
value_template: '{{ (as_timestamp(now()) -(states.input_datetime.lounge_ac_am_on_time.attributes.timestamp | default(0)) | int > 0) and ((states.input_datetime.lounge_ac_am_off_time.attributes.timestamp - as_timestamp(now()) | default(0)) | int > 0)}}'
- condition: template
value_template: '{{ (as_timestamp(now()) -(states.input_datetime.lounge_ac_pm_on_time.attributes.timestamp | default(0)) | int > 0) and ((states.input_datetime.lounge_ac_pm_off_time.attributes.timestamp - as_timestamp(now()) | default(0)) | int > 0)}}'
@tom_l I’ve never used input_datetimes, so if they have timestamps then it’s even easier. Assuming the timestamp has today’s date.
Also, you don’t need default(0) when using this method because strings converted to int’s default to zero when it can’t convert (if the string returns any character that’s not a number).
condition:
- condition: template
value_template: >
{% set current_time = now().timestamp() %}
{% set am_start = states('input_datetime.lounge_ac_am_on_time', 'timestamp') | int %}
{% set am_end = states('input_datetime.lounge_ac_am_on_time', 'timestamp') | int %}
{% set pm_start = states('input_datetime.lounge_ac_am_on_time', 'timestamp') | int %}
{% set pm_end = states('input_datetime.lounge_ac_am_on_time', 'timestamp') | int %}
{{ am_start <= current_time <= am_end or pm_start <= current_time <= pm_end }}
The datetimes I am using have time only. And this trigger has worked for me before:
trigger:
platform: template
value_template: "{{ states('sensor.time') == (states.input_datetime.lounge_ac_pm_on_time.state[0:5]) }}"
So I was attempting to adapt it for a condition for a range of times.
However I have just discovered an errant “)” in a completely unrelated automation miles away from where I was working that wasn’t there when I validated the config yesterday. This was causing errors unrelated to this current effort. Ugh.
It is unlikely that my time ranges will ever cross a date boundary but I like the the idea of accounting for it just in case.
Thank you both for your ideas. I’ll have a bit of an experiment and let you know how I go.
Success. This passes the validation check but the off times must be > the on times (i.e. not cross a date boundary).
- condition: or
conditions:
- condition: template
value_template: "{{ (states('sensor.time') >= states.input_datetime.lounge_ac_am_on_time.state[0:5]) and (states('sensor.time') < states.input_datetime.lounge_ac_am_off_time.state[0:5]) }}"
- condition: template
value_template: "{{ (states('sensor.time') >= states.input_datetime.lounge_ac_pm_on_time.state[0:5]) and (states('sensor.time') < states.input_datetime.lounge_ac_pm_off_time.state[0:5]) }}"
This will do for now. Sleep time.
That’s comparing strings and will not work.
let me clarify, that will pass config check but will not properly give you the correct true/false time checks.
Really?
It has been for the trigger I posted above. And it works in the template editor.
Ah. Never mind. == works for strings!
Ok back to the drawing board. Tomorrow.
you should just be able to copy and paste what @lolouk44 wrote or what I wrote without any issues…
Ha. Good example.
FYI what I wrote above is what I use for my holidays automation so I know it works
however I use a date and time input_date…
Ok I’ll paste it in and see what happens tomorrow morning. Thanks for your help folks.
Oh good lord. There’s another problem I’ve just disovered in my action template,
This:
{% if (states.input_select.lounge_ac_mode.state != 'Normal Cool')%}
Needs to account for ‘Silent Cool’ and ‘Powerful Cool’ as well. Is there a way to test for the string ‘Cool’ in states.input_select.lounge_ac_mode.state?
{% if 'Cool' not in states.input_select.lounge_ac_mode.state %}
or
{% if (states.input_select.lounge_ac_mode.state not in ['Normal Cool','Silent Cool','Powerful Cool'] %}