Sleep trainer for children using input_datetime and an RGB light

Tags: #<Tag:0x00007fc418a8ed80> #<Tag:0x00007fc418a8ec90> #<Tag:0x00007fc418a8eb78> #<Tag:0x00007fc418a8eab0>

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

Note It seems I messed up the code block, which causes the templates to fail after importing the blueprint. I’ll try to fix this later today.

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
3 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: