Sensor state based on time of day

Hi

I’ve been trying to get a sensor to change its state based on the time of day but I have had some trouble with the value template. I’m using the time platform as I thought it was easier than using the more code based %h.

What I am trying to do is have two values. Sleep and Nap, using these values I then use a script to run specific things for my sons room based on if its a nap during the day or the overnight sleep from a click of a xiaomi smart button.

I want sleep from 5pm - 2am and Nap the rest of the time.

Can anyone help with what I am doing wrong here. I think I’ve looked it at for too long.

sleep_periods:
  value_template: >-
    {%- if states.sensor.time.state <= "02:00" %}
    Sleep
    {%- elif states.sensor.time.state > "07:00" %}
    Nap
    {%- elif states.sensor.time.state >= "17:00" %}
    Sleep
    {%- else %}
    Nap
    {%- endif %}

How about this?

sleep_periods:
  value_template: >-
    {%- if now().hour <2 and now().hour >=17 -%}Sleep
    {%- else -%}Nap
    {%- endif -%}

I think the problem would be that >= 1700 is also > 0700

so, it would need to be

{%- elif states.sensor.time.state > "07:00" and states.sensor.time.state <= "17:59" %}

or similar, which is presuming that you can use < , > , = etc in that way with the time sensor.

Another implementation would be to use an automation that sets the sensor (although substituting an input_select for the sensor) at the appropriate time.

alias: Set sleep or nap
trigger:
  - platform: time
    at: "17:00:00"
  - platform: time
    at: "07:00:00"
action:
  service: input_select.set_option
  data_template:
    entity_id: input_select.sleep_nap_sensor
    option: >
      {% if now.hour() > 16 %} Sleep
      {% else %} Nap {% endif %}

Or something.

The first problem I see is that the times in your if statements don’t match what you said in your description. If you want Sleep from 5pm - 2am and Nap the rest of the time, then that would look like this:

{% if '02:00' < states.sensor.time.state < '17:00' %}
  Nap
{% else %}
  Sleep
{% endif %}

Next, this depends on the state of sensor.time always being in the form of ‘HH:MM’. If it is, then this works because of the way string comparisons work. But if it isn’t (e.g., if it includes the date, or seconds, or if hours before 10 are displayed with a single hour digit, such as ‘9:00’) then this won’t work. I don’t use sensor.time so I’m not sure how its state is rendered, but you can look on the States page to see.

Next, you could do like @lolouk44 suggests, but I’m not sure that this Template Sensor would actually update, since it’s not based on any entity (like sensor.time) whose state changes. Of course, you could use that in an automation as a condition or service/data template directly instead of having this sensor as a middleman.

If it were me, I’d do it something like @anon43302295 suggests. But I’d use an input_boolean, something like this:

input_boolean:
   sleep_period:
     name: Sleep period

automation:
  - alias: Update sleep period
    trigger:
      - platform: time
        at: '02:00'
      - platform: time
        at: '17:00'
      - platform: homeassistant
        event: start
    action:
      service_template: >
        {% if 2 <= now().hour < 17 %}
          input_boolean.turn_off
        {% else %}
          input_boolean.turn_on
        {% endif %}
      entity_id: input_boolean.sleep_period
2 Likes

That’s interesting, wasn’t aware of this. Will need to run some tests

They definitely will not update because there is nothing that triggers the update. If you switch off of the now() method and move to the sensor.time platform, it will work and update minutely.

EDIT: For example using this platform:

it would look like this:

sleep_periods:
  value_template: >-
    {% t = strptime(states('sensor.time'), '%H:%M') %}
    {%- if t.hour <2 and t.hour >=17 -%}Sleep
    {%- else -%}Nap
    {%- endif -%}
2 Likes

Thanks Everyone I will give these a crack.

Hi, @petro.

Wouldn’t this templating be compliant with ‘set’ instruction for defining that local variable?

    {% set t = strptime(states('sensor.time'), '%H:%M') %}
    {%- if t.hour <2 and t.hour >=17 -%}Sleep
    {%- else -%}Nap
    {%- endif -%}

Thanks.

I’m not sure what you mean, can you elaborate?

I think he means you forgot set in your template. I.e.,

{% t = strptime(states('sensor.time'), '%H:%M') %}

should be

{% set t = strptime(states('sensor.time'), '%H:%M') %}

yep, looks like I did. Probably wrote that without testing.