Sleep trainer for children using input_datetime and an RGB light

Tags: #<Tag:0x00007fc3ddeb5bb0> #<Tag:0x00007fc3ddeb5ac0> #<Tag:0x00007fc3ddeb59d0> #<Tag:0x00007fc3ddeb58e0>

Github gist: Sleep trainer blueprint for Home-Assistant (github.com)

This is a blueprint to create a ‘sleep trainer’ for smaller children who can’t tell time yet. It allows you to set a time at which the configured light(s) will be turned green, indicating it is OK to get out of bed.

15 minutes before the light turns green it will turn purple, to indicate that it is almost time to get up.

Other than that a start time and stop time can be configured and the brightness for the light can be set.

The times to get up can be inserted using input_datetime entities. These can easily be configured in the front end if you want to change the time the light should turn green.

Blueprint code
Import this blueprint using the forum topic, or click the badge below if you are running HA 2021.3.1 or higher.
Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: Sleep trainer light using time and RGB light
  description:  'Creates a sleep trainer using an RGB(w) light to 
    
    indicate if it is time to get out of bed or not. 
    
    Usefull for smaller children who cant tell time yet.
    
    
    At the start time the light is turned on red.
    
    15 minutes before the wake up time the light is changed to purple-ish
    
    At the configured wake up time the light is changed to green.
    
    At the stop time the light is turned off again.
    
    
    As target several options are available to choose from.
    '
  domain: automation
  input:
    enable_trainer_light:
      name: Enable light
      description: Enable the actions of the automation to set the ligtht's  state. Select an input_boolean entity for this input.
      selector: 
        entity:
          domain: input_boolean
    time_start:
      name: Time to start
      description: Time to turn on the light red before it's OK to get up
      default: "05:30:00"
      selector:
        time:
    time_stop:
      name: Time to stop
      description: Time to turn off the light 
      default: "09:00:00"
      selector:
        time:
    time_monday:
      name: Monday time
      description: Time to get up on Mondays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_tuesday:
      name: Tuesday time
      description: Time to get up on Tuesdays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_wednesday:
      name: Wednesday time
      description: Time to get up on Wednesdays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_thursday:
      name: Thursday time
      description: Time to get up on Thursdays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_friday:
      name: Friday time
      description: Time to get up on Fridays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_saturday:
      name: Saturday time
      description: Time to get up on Saturdays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    time_sunday:
      name: Sunday time
      description: Time to get up on Sundays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime
    target_light:
      name: Light
      description: Light entity to use
      selector:
        target:
          entity:
            domain: light
    brightness:
      name: Brightness
      description: Brightness of the light(s) when turning on
      default: 10
      selector:
        number:
          min: 0.0
          max: 100.0
          mode: slider
          step: 1.0
          unit_of_measurement: '%'
mode: restart
max_exceeded: silent

trigger:
  - platform: time
    at:
      - !input time_start
      - !input time_stop
      - !input time_monday
      - !input time_tuesday
      - !input time_wednesday
      - !input time_thursday
      - !input time_friday
      - !input time_saturday
      - !input time_sunday
  - platform: homeassistant
    event: start

variables:
  timestart: !input 'time_start'
  timestop: !input 'time_stop'
  timemonday: !input 'time_monday'
  timetuesday: !input 'time_tuesday'
  timewednesday: !input 'time_wednesday'
  timethursday: !input 'time_thursday'
  timefriday: !input 'time_friday'
  timesaturday: !input 'time_saturday'
  timesunday: !input 'time_saturday'
  
condition:
  - condition: state
    entity_id: !input enable_trainer_light
    state: 'on'
    
action:
- choose:
  - conditions:
      - condition: time
        after: !input time_stop
    sequence:
    - service: light.turn_off
      target: !input target_light
      data:
        transition: 2
  - conditions:
    - condition: template
      value_template: |
        {% set cdate = now().strftime("%Y-%m-%d ") %}
        {% set ctime = (now().timestamp() + 1) | int %}
        {% if now().weekday() in (0,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timemonday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (1,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timetuesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (2,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timewednesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (3,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timethursday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (4,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timefriday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (5,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesaturday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (6,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesunday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% endif %}
        {% set starttime = as_timestamp(strptime(cdate + timestart, '%Y-%m-%d %H:%M:%S')) | int %}
        {{ starttime < ctime < wakeuptime }}
    sequence:      
    - service: light.turn_on
      target: !input target_light
      data:
        transition: 2
        color_name: 'red'
        white_value: 0
        brightness_pct: !input brightness
    - wait_template: |
        {% set cdate = now().strftime("%Y-%m-%d ") %}
        {% if now().weekday() in (0,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timemonday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (1,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timetuesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (2,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timewednesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (3,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timethursday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (4,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timefriday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (5,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesaturday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (6,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesunday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% endif %}
        {% set curTime = as_timestamp(strptime(cdate + states('sensor.time'), '%Y-%m-%d %H:%M')) | int %}
        {{ curTime > (wakeuptime - (60 * 15)) }}
    - service: light.turn_on
      target: !input target_light
      data:
        transition: 2
        rgb_color: [255,0,170]
        white_value: 0
        brightness_pct: !input brightness
  - conditions:
    - condition: template
      value_template: |
        {% set cdate = now().strftime("%Y-%m-%d ") %}
        {% set ctime = (now().timestamp() + 1) | int %}
        {% if now().weekday() in (0,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timemonday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (1,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timetuesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (2,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timewednesday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (3,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timethursday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (4,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timefriday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (5,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesaturday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% elif now().weekday() in (6,) %}
          {% set wakeuptime = as_timestamp(strptime(cdate + states(timesunday), '%Y-%m-%d %H:%M:%S')) | int %}
        {% endif %}
        {% set stoptime = as_timestamp(strptime(cdate + timestop, '%Y-%m-%d %H:%M:%S')) | int %}
        {{ wakeuptime < ctime < stoptime }}
    sequence:      
    - service: light.turn_on
      target: !input target_light
      data:
        transition: 2
        color_name: 'green'
        white_value: 0
        brightness_pct: !input brightness

Changelog

  • 2021-06-11: Update descriptions to indicate use of entity_id’s instead of direct input.
  • 2021-03-20: Initial version
4 Likes

Great idea! Now to find a small rgb lamp to use this with

I’m using an LED strip with a diffuser, this gives a really nice effect :slight_smile:

Koos, i’ve made a nice slaaptrainer from an (ikea bedlight with ESP and WS2812) for my 2,5 yo boy.

But I do not get your blueprint saved as an automation.
The following error is displayed in the core-logs.

2021-06-07 14:55:16 ERROR (MainThread) [homeassistant.components.automation] Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '8:01:00'), ('time_start', '5:31:00'), ('time_monday', '7:01:00'), ('time_tuesday', '7:01:00'), ('time_wednesday', '7:01:00'), ('time_thursday', '7:01:00'), ('time_friday', '7:01:00'), ('time_saturday', '7:01:00'), ('time_sunday', '7:01:00'), ('target_light', OrderedDict([('entity_id', 'light.slaapkamer_niek_lidl')])), ('brightness', 18)]): Entity ID on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None

Any help is much appriciated.

Hi Niek,

You are inputting time directly in the Automation settings, but the blueprint is intended to be used with input_datetime helpers.

You can create several (or one) input_datetime entities from the configuration page. Make sure to add them as Time entities!

image

Then input the entity id’s of the created helpers in the automation configuration. That should fix your problem.

Only start and end time are fixed times in the automation’s configuration.

I’ve opted to use input helpers so I can make the settings available in the frontend. This way the times can be adjusted easily without going in the automation’s configuration. Makes it more user friendly for other HA users :slight_smile:

Yes, solved.!
Enable/Disable + WeekTimes had to be an input boolean.
Logical setup, but the pre defined field with the time set me on the wrong foot.
Thanks for your response.

Hi, I get similar problem as @niekbruggeman. I create the helpers for a week day and weekends I think that my problem is whith the fist entity value that is by default “on”, I dont find any entity to put there no idea what to do there either. sorry, I am pretty new at this.
Bellow it is my log

Logger: homeassistant.components.automation
Source: components/automation/__init__.py:637
Integration: Automation (documentation, issues)
First occurred: 1:28:56 PM (19 occurrences)
Last logged: 1:28:56 PM

Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '9:00:00'), ('target_light', OrderedDict([('entity_id', 'light.extended_color_light_3_2')])), ('time_monday', 'input_datetime.trainerw'), ('time_tuesday', 'input_datetime.trainerw'), ('time_wednesday', 'input_datetime.trainerw'), ('time_thursday', 'input_datetime.trainerw'), ('time_friday', 'input_datetime.trainerw'), ('time_saturday', 'input_datetime.trainerwkd'), ('time_sunday', 'input_datetime.trainerwkd')]): Entity ID on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None
Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '9:00:00'), ('target_light', OrderedDict([('device_id', 'd882b1273e93f8df5aa33063aff01d81')])), ('time_monday', 'input_datetime.wakeup'), ('time_tuesday', 'input_datetime.wakeup'), ('time_wednesday', 'input_datetime.wakeup'), ('time_thursday', 'input_datetime.wakeup'), ('time_friday', 'input_datetime.wakeup'), ('time_saturday', 'input_datetime.wakeup'), ('time_sunday', 'input_datetime.wakeup')]): Entity ID on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None
Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '9:00:00'), ('time_monday', 'input_datetime.wakeup'), ('time_tuesday', 'input_datetime.wakeup'), ('time_wednesday', 'input_datetime.wakeup'), ('time_thursday', 'input_datetime.wakeup'), ('time_saturday', 'input_datetime.weekend'), ('time_sunday', 'input_datetime.weekend'), ('target_light', OrderedDict([('entity_id', 'light.extended_color_light_3_2')])), ('time_friday', 'input_datetime.wakeup'), ('time_start', '6:30:00')]): Entity ID on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None
Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '10:00:00'), ('time_monday', 'input_datetime.wakeup'), ('time_tuesday', 'input_datetime.wakeup'), ('time_wednesday', 'input_datetime.wakeup'), ('time_thursday', 'input_datetime.wakeup'), ('time_friday', 'input_datetime.wakeup'), ('time_saturday', 'input_datetime.weekend'), ('time_sunday', 'input_datetime.weekend'), ('target_light', OrderedDict([('device_id', 'd882b1273e93f8df5aa33063aff01d81')])), ('time_start', '6:00:00'), ('enable_trainer_light', 'Migush_lamp_1 is on')]): Entity ID Migush_lamp_1 is on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None
Blueprint Sleep trainer light using time and RGB light generated invalid automation with inputs OrderedDict([('time_stop', '9:00:00'), ('target_light', OrderedDict([('entity_id', 'light.extended_color_light_3_2')])), ('enable_trainer_light', 'on'), ('time_monday', 'input_datetime.wakeup'), ('time_tuesday', 'input_datetime.wakeup'), ('time_wednesday', 'input_datetime.wakeup'), ('time_friday', 'input_datetime.wakeup'), ('time_saturday', 'input_datetime.weekend'), ('time_thursday', 'input_datetime.wakeup'), ('time_sunday', 'input_datetime.weekend'), ('time_start', '6:00:00')]): Entity ID on is an invalid entity ID for dictionary value @ data['condition'][0]['entity_id']. Got None

The problem is indeed similar, the blueprint expects an input_boolean entity to be used in order to enable/disable the sleep trainer light. This way it can be turned off easily from the frontend.

So you need to create a helper entity ‘input_boolean’ type and select this entity in ‘enable trainer light’.

I will update the blueprint with some better descriptions on what is expected as inputs.

Super yes I added a toggle and problem solved thanks alot :smile:

Glad it works now! I’ve updated the blueprint to have better descriptions and removed the defaults to prevent confusion :slight_smile:

Hi @koosvanw ,

Is the note, stating that the code block is faulty, still relevant? I just bought an IKEA rgb lamp and I really want to try out this blueprint :vulcan_salute:

It seems to be ok, think I forgot to remove that line. If you run into any problems let me know!

Thanks @koosvanw !
Will check it out this week.
Thanks for the code! :vulcan_salute:

Hi @koosvanw ,

Just set the automation up and it works like a charm!
I have two questions:

  1. I would like use a helper for the start and stop time as well. Is this easy for me to do?
  2. When I turn on the light after the automation ends it’s green. Is there an easy fix to set the light to warm white after the automation?

Hi @Bliksembaard,

Sorry for the late response.

For the helper, this shouldn’t be too hard. You could look at the other times to see how this is set up, I think it should work correctly if you change it. I’ll have a closer look at it later.

You could set up another automation which triggers at the end time and sets the light to warm white, then switches it off? Other option is to add it to the action in the blueprint. Currently I have no PC at hand, I’ll send a sample later.

Hi @koosvanw ,

I finally got around to it and figured the first part uit quite quickly:
afbeelding
I added manuel settings as well for the on/off toggle and a one-click for the colors. This part is not included in the automation but a separate card with vertical stack in card so it’s visually part of the same card.

Now to add the warm white to the automation so when turning the light on in the middel of the night via remote it’s not green (current setup doesn’t have the WAF status :wink: )

Would this do the trick?

action:
- choose:
  - conditions:
    - condition: time
      after: !input 'time_stop'
    sequence:
    - service: light.turn_on
      target: !input 'target_light'
      data:
	    color_mode: color_temp
		brightness: 200
		color_temp: 454
    - service: light.turn_off
      target: !input 'target_light'
      data:
        transition: 2

@Bliksembaard Yes that should do it. You can test the service call itself separately to make sure it is the color etc you want, but changing the blueprint like that would make sure the light is back in a normal state after the wake-up sequence has run.

Nice! I have basically the same setup, also with the quick color toggles using the vertical stack in card :wink:

Hi @koosvanw ,

Sorry for the late reply!
Changing the manual inputs in the blueprint to date/time helpers doesn’t work yet.
The first one does. It turns the light on with the low level red color.
But when the second helper triggers the light does nothing.
I checked the log and it looks like the script checks for a state and expects a boolean ‘off’ state.


The log entry says ‘no action taken’:
2021-07-30 16_42_33-Instellingen - Home Assistant

This is the scipt. I only changed the selectors. I left the rest as is:

blueprint:
  name: Slaaptrainer
  description: 'Creates a sleep trainer using an RGB(w) light to

    indicate if it is time to get out of bed or not.

    Usefull for smaller children who cant tell time yet.


    At the start time the light is turned on red.

    15 minutes before the wake up time the light is changed to purple-ish

    At the configured wake up time the light is changed to green.

    At the stop time the light is turned off again.


    As target several options are available to choose from. '
  domain: automation
  input:
    enable_trainer_light:
      name: Enable light
      description: Enable the actions of the automation to set the ligtht's  state.
        Select an input_boolean entity for this input.
      selector:
        entity:
          domain: input_boolean
    time_start:
      name: Time to start
      description: Time to turn on the light red before it's OK to get up
      selector:
        entity:
          domain: input_datetime
    time_stop:
      name: Time to stop
      description: Time to turn off the light
      selector:
        entity:
          domain: input_datetime
    time_monday:
      name: Monday time
      description: Time to get up on Mondays. Pick the correct entity_id
      selector:
        entity:
          domain: input_datetime

Do you know what could be the problem?