Mode: Morning, Afternoon, Evening

Hi lovely people,

I’m starting out with Home Assistant and I was wondering if you could help me.
I have an Input Select with 3 options.

  1. Morning
  2. Afternoon
  3. Evening

Can I create one automation which detects what time of day it is and based on that select morning, afternoon or evening? Or do I need to have one automation for each mode?

Would love to get some feedback.

Thanks!

1 Like

Assuming Morning is before 12 and afternoon is before 18 you can use a condition as below:

{%- if as_timestamp(now()) | timestamp_custom('%H') | int < 12 -%}Morning
{%- elif as_timestamp(now()) | timestamp_custom('%H') | int < 18 -%}Afternoon
{%- else -%}Evening{%- endif -%}

The full automation would be:

- alias: Set Input SelectTime of Day
  initial_state: false
  trigger:
    - platform: time
      hours: '/1'
      minutes: 0
      seconds: 0
  action:
      - service: input_select.select_option
        data_template:
          entity_id: input_select.time_of_day
          option: >
            {%- if as_timestamp(now()) | timestamp_custom('%H') | int < 12 -%}Morning
            {%- elif as_timestamp(now()) | timestamp_custom('%H') | int < 18 -%}Afternoon
            {%- else -%}Evening{%- endif -%}

You’d need to replace input_select.time_of_day with the actual entity name of your input_select and replace Morning/Afternoon/Evening with the actual options you have set up for your input_select (if different)

Note I’ve not tested the above but should get you well on your way

4 Likes

using the datetime component, you could also create a template sensor to do your dirty work:

sensor:
  - platform: time_date
    display_options:
      - 'time'
  - platform: template
    sensors:
      time_of_day:
        value_template: >
          {% set current_hour = strptime(states('sensor.time'), "%H:%M").hour %}
          {% if current_hour < 12 %}
            Morning
          {% elif 12 <= current_hour < 18 %}
            Afternoon
          {% else %}
            Evening
          {% endif %}

This way you don’t have an automation firing every minute which can hog resources.

FYI @lolouk44, you can grab the hour directly from now() without using a custom timestamp and converting it to an integer:

now().hour

So your stuff could be simplified:

           {%- if now().hour < 12 -%}Morning
           {%- elif now().hour < 18 -%}Afternoon
           {%- else -%}Evening{%- endif -%}
2 Likes

he he I had my automation running only once an hour on the hour so not sure which is less resource intensive now :wink:

Thanks for the tip, it’ll save me a lot of time

Yeah, it really only helps ease the pain if you are executing every minute. Every hour is not intensive at all.

EDIT: I just noticed that the original automation you wrote is /1 on the hour! Lol, I thought it was on the minute.

1 Like

indeed we’re comparing hours so no need to check every minute, THAT would be overkill and resource intensive :wink:

Hi all,

Thank you so much for the replies. I’ve added the following to my automations file but it doesn’t seem to be working. Any advise on what I am doing wrong?

- id: '1234123213'
  alias: Set House Mode
  initial_state: false
  trigger:
    - platform: time
      hours: '/1'
      minutes: 0
      seconds: 0
  action:
      - service: input_select.select_option
        data_template:
          entity_id: input_select.house_mode
          option: >
           {%- if now().hour < 12 -%}Morning
           {%- elif now().hour < 18 -%}Afternoon
           {%- elif now().hour < 0 -%}Evening
           {%- else -%}Night{%- endif -%}

maybe that’s why?
Your initial state should be true or you need some automation or manual action to enable this automation else it will never run…

Also you will never get evening as you check if the hour is less than 0 which will never be true… did you mean 20?

Also… 3 (e.g) is < 12 and < 18, so try to put any and in your if/else statements

no that should be fine because he’s using elif and not a standard if so 3 would be caught on the first if statement.
It does mean that as soon as you pass midnight it will be morning though, not night anymore…

1 Like

this needs to be reworked alittle the way it’s written. the last elif won’t be reached due to the fact that < 0 doesn’t exist when dealing with time, if you want it to be 18 to 24 hours, you should use 24 instead (which is essentiall midnight). Also, I’m guessing you don’t want night to never occur, so you need to add in the correct timing.

       {% if now().hour < 5 %}Night
       {% elif now().hour < 12 %}Morning
       {% elif now().hour < 18 %}Afternoon
       {% else %}Evening{% endif %}
1 Like

Thank you so much for your help! This fixed it!

I’m trying to use this, and keep getting this error, when I try to save:

Message malformed: extra keys not allowed @ data['hours']

It’s been a while but for those that come looking… I think the answer to @rlyons20 is that we need a time_pattern trigger. I went with a sensor template as per the above because you don’t have to wait until the top of the hour for a value to populate, but if you want to use an automation:

- id: 'id 37'
  alias: set time mode
  trigger:
    - platform: time_pattern
      minutes: 0
  action:
      - service: input_select.select_option
        data_template:
          entity_id: input_select.time_mode
          option: >
           {% if now().hour < 5 %}night
           {% elif now().hour < 12 %}morning
           {% elif now().hour < 18 %}afternoon
           {% else %}evening{% endif %}
1 Like

There is also the Times of Day component now:

1 Like

Found this looking for something like this. Lots of out of date stuff.
Now Stardate 20221004. Its 4 years on. Try:
Variable; ‘dayperiod’ stores the data and can be used else where in
programming .Written in Sensors.yaml.

dayperiod:
  friendly_name: 'DayPeriod'  
  value_template: >-
    {% if now().hour < 6 %}night
    {% elif now().hour < 12 %}morning
    {% elif now().hour < 18 %}afternoon
    {% else %}evening{% endif %}