Input_time as a condition

Struggling here folks…down to my ‘newness’ at all this :slight_smile:

I have two input_times defined in configuration.yaml- dark_mode_start / dark_mode_end ( just messing about still )

  input_datetime:
  dark_mode_start:
    has_date: false
    has_time: true
    initial: '23:30:00'
    
  dark_mode_end:
    has_date: false
    has_time: true
    initial: '07:00:00'

and an automation - 'if there is motion, and the time is between the ‘dark_mode_start’ and ‘dark_mode_end’ times, turn the hall lights on. I’ve snipped the full automation as it worked when the ‘condition’ was hardcoded to 23:30:00 and 07:00:00. But using value templates and input_time doesn’t trigger a thing!! Convinced it’s my time formatting here. On a side note, is there anyway to debug / console.write values out anywhere? I found the sample online and doctored it.

Thanks Folks!

condition: 
    condition: and
    conditions:
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M") > states.input_datetime.dark_mode_start.state }}'
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M") < states.input_datetime.dark_mode_end.state }}'

Try removing the ’ at the end of your }}

Side note, I use the TOD binary sensor for things like this.

https://www.home-assistant.io/integrations/tod/

no!!! If that is it - I will hang up my keyboard…give me a few minutes…

No joy - it’s 2AM here now, so calling it a night - good spot though - had missed that - but still nothing.

  condition: 
    condition: and
    conditions:
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M") > states.input_datetime.dark_mode_start.state }}
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M") < states.input_datetime.dark_mode_end.state }}

[edit] : will take a look at the TOD sensor as well tomorrow - can’t have too many options at the moment.

Cheers

[edit 2]

hate giving up. Because it spans midnight - the logic operator should be an ‘or’. Doh. Anyway - at least i can see where i am going now as i head off to bed :).

condition: 
    condition: or
    conditions:
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M:%S") > states.input_datetime.dark_mode_start.state }}
    - condition: template
      value_template: >
        {{ now().strftime("%H:%M:%S") < states.input_datetime.dark_mode_end.state }}

You cant compare strings (e.g. hh:mm) with >

You need to convert them to timestamps. Which is a pain for input datetimes with no date.

You can use == to compare strings, so you could use:

      value_template: >
        {{ now().strftime("%H:%M") == states('input_datetime.dark_mode_start')[0:5] }}

Note the formating used to remove the seconds from the input datetime too.

Otherwise you need to add today’s date to the input datetime.

Here’s an example of a binary sensor that adds the date back:

    dining_heating_pm_automation_time_active:
      friendly_name: "Dining PM Automation Time Active"
      entity_id:
      - sensor.time # required to update now()
      - input_datetime.dining_pm_on_time
      - input_datetime.dining_pm_off_time
      - input_boolean.dining_pm_heat_automation
      value_template: >-
        {% set d = now().strftime("%Y-%m-%d ") %}
        {% set t = now().timestamp() %}
        {% set pm_start = strptime(d + states('input_datetime.dining_pm_on_time'), '%Y-%m-%d %H:%M:%S').timestamp() %}
        {% set pm_end = strptime(d + states('input_datetime.dining_pm_off_time'), '%Y-%m-%d %H:%M:%S').timestamp() %}
        {{ (pm_start <= t <= pm_end) and is_state('input_boolean.dining_pm_heat_automation', 'on')  }}

i think you can compare as strings as long as the hours / minutes have leading spaces - as

“01” will ‘sort’ before “02” and “23” will come after “22” if you sort based on they char values- which is standard. So ‘for now’, whilst i am sill getting my head around this, it works. It also, as you said, prevents me constructing a full date / timestamp and i can just use the hours.

Adding the date back in is a good method, but not sure your implementation will handle time spans that cross teh date line - eg. start at 11pm and end at 2am. I think you’re adding teh same ‘date’ onto the start and end - which is good for jobs that start / end same day.

I will definitely take a look at teh date handling / formatting here as when I was googling / searching it seems to be a very common problem.

Cheers

I compare strings like that all the time

1 Like

If you have a 1 line template, and you put it on the same line as the value_template: then you don’t need the ‘>’ but you do need the external quotes (as Malcolm was sort of trying for).
If you use the multiline template with the ‘>’ = you don’t
If you are using input datetimes you never know what your users will put in to them (even if the user is you) so you always have to test.
Here is a sample test that I use for my switches (it is for two time slots in the day, but you get the idea) and it compares strings : -

        value_template: >
          {% set time = states('sensor.time') %}
          {% set slt1en = is_state('input_boolean.ib_switch_pifi01_timeslot1_enable', 'on') %}
          {% set slt1start = states('input_datetime.id_switch_pifi01_tmeslt1_on') [0:5] %}
          {% set slt1stop = states('input_datetime.id_switch_pifi01_tmeslt1_off') [0:5] %}
          {% set slt2en = is_state('input_boolean.ib_switch_pifi01_timeslot2_enable', 'on') %}
          {% set slt2start = states('input_datetime.id_switch_pifi01_tmeslt2_on') [0:5] %}
          {% set slt2stop = states('input_datetime.id_switch_pifi01_tmeslt2_off') [0:5] %}
          {% set slt1on = (slt1start <= time < slt1stop) if (slt1start < slt1stop) else (slt1start <= time or time < slt1stop) %}
          {% set slt2on = (slt2start <= time < slt2stop) if (slt2start < slt2stop) else (slt2start <= time or time < slt2stop) %}
          {{ (slt1on and slt1en) or (slt2on and slt2en) }}

1 Like

‘sort of trying for’ :laughing:

I am sort of trying for any successes where I can. I am trying to get fairly ‘wide’ across HA before i start doing real automations beyond testing with a few bulbs and sensors.

This is a great forum though - I hope in time I can contribute back.

see if this helps you any:

1 Like

Bejesus finity, what time do you get up in the morning?

I’m always up…:persevere:

:wink:

My work schedule is screwy. I work a rotating 12 hour shift, 4 days on day shift, 4 days off, 4 days on night shift, 4 days off & then back to day shift. I just happen to be on night shift now.

You poor SOB, I hope they pay you well for that.
Your body clock must be screwed

fortunately, they do. :dollar::dollar::dollar::heavy_dollar_sign::heavy_dollar_sign::heavy_dollar_sign::laughing:

Unfortunately, it is.

I’ve been working a rotating schedule for so long I don’t know how I would act if I ever worked a straight day schedule. Between 10 years in the Navy and then working rotating shifts in various forms as factory maintenance I’ve been doing rotating shifts for almost 35 years.

I think I’ll probably need to keep on a rotating “shift” even after I retire in a few years or my head will probably explode…:exploding_head:

Hello,

Maybe someone will be interested in my solution.
I have create 2 input_datetime helpers.
And next I have defined binary_sensor which is working like TOD.
Code of binary_sensor below:

- platform: template
  sensors:
    tod_switch_internet_offperiod:
      value_template: >-
        {% if (states("input_datetime.switch_internet_offat") == states("input_datetime.switch_internet_onat")) %}
        {{ false }}
        {% elif (strptime(states("input_datetime.switch_internet_offat"), "%H:%M:%S").time() < strptime(states("input_datetime.switch_internet_onat"), "%H:%M:%S").time()) %}
        {{ (strptime(states("input_datetime.switch_internet_offat"), "%H:%M:%S").time() < now().time()) and (now().time() < strptime(states("input_datetime.switch_internet_onat"), "%H:%M:%S").time()) }}
        {% else %}
        {{ (now().time() < strptime(states("input_datetime.switch_internet_onat"), "%H:%M:%S").time()) or (now().time() > strptime(states("input_datetime.switch_internet_offat"), "%H:%M:%S").time()) }}
        {% endif %}

Finally it is working just like typical TOD (state = on if now() is between ‘offat’ and ‘onat’).

1 Like

Thanks for the solution @luke76 . I was attempting to use the tod platform, but it doesn’t appear to accept templating:

- platform: tod
  name: "Quiet Time"
  after: '{{ state(input_datetime.quiet_time_start) }}'
  before: '{{ state(input_datetime.quiet_time_end) }}'

Your solution is a great work around for creating a boolean_sensor entity from a range of two arbitrary times.

I defined this sensor in my generic template: integration config, and was able to improve the readability using variables:

- binary_sensor:
    - name: "Quiet Time"
      state: >
        {% set on_time = strptime(states("input_datetime.quiet_time_on"), "%H:%M:%S").time() %}
        {% set off_time = strptime(states("input_datetime.quiet_time_off"), "%H:%M:%S").time() %}

        {% if on_time == off_time %}
          {{ false }}
        {% elif on_time < off_time %}
          {{ (on_time < now().time()) and (now().time() < off_time) }}
        {% else %}
          {{ (now().time() < off_time) or (now().time() > on_time) }}
        {% endif %}
1 Like