LED Night Light Controller Help

Greetings… I wrote the code below quite some time back, and whilst I know it’s not perfect it has done the job in our 8 year old daughters bedroom.

Our daughter has been asking lately if I can tweak the program to have the lights come on at bedtime around 9pm at 20% brightness so the room is not dark. And when the PIR detects any movement during the night the lights increase to 70 or 80% brightness, and then go back to 20% brightness when the PIR doesn’t detect any movement.

I will admit I am not the greatest yaml programmer, so perhaps this is a good time to revamp the code, add the new features our daughter is seeking, and perhaps simplify the code based on some recommendations from the gurus in this forum.

Here’s the current code…

substitutions:
  off_hour: '5'

esp8266:
 board: d1_mini
 framework:
  version: recommended
  
esphome:
  name: esp4-bdrmlights 
  on_boot:
    - light.turn_off:
        id: bdrm_led_lights
        transition_length: 2.5s

status_led:
  pin: GPIO2

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "<REDACTED>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp4-Bdrmlights Fallback Hotspot"
    password: "<REDACTED>"

captive_portal:

script:
  - id: turn_off
    mode: restart
    then:
      - delay: 90s
      - light.turn_off:
          id: bdrm_led_lights
          transition_length: 7.5s
      - logger.log: "LED lights are OFF"

binary_sensor:
  - platform: gpio
    pin: D5
    id: bdrm_pir
    name: "Bdrm PIR Sensor"
    device_class: motion
    on_press:
      then:
      - if:
          condition:
            and:
              # If it's night time
              - sun.is_below_horizon:
              - lambda: |-
                  auto hour = id(my_time).now().hour;
                  return hour > 12 || hour < ${off_hour};
          then:
              #Turn on the LED lights
              - light.turn_on:
                  id: bdrm_led_lights
                  brightness: 40%
                  effect: random
              - logger.log: "LED lights are ON"
    on_release:
      - script.execute: turn_off

sun:
  latitude: !secret latitude
  longitude: !secret longitude

time:
  platform: homeassistant
  timezone: !secret timezone
  id: my_time
  on_time:
  - hours: ${off_hour}
    minutes: 0
    seconds: 0
    then:
    - light.turn_off:
        id: bdrm_led_lights

light:
  - platform: neopixelbus
    variant: WS2812
    pin: D1
    num_leds: 54
    type: GRB
    name: "FastLED WS2812B Light"
    id: bdrm_led_lights
    default_transition_length: 7.5s
    effects:
      # Use default parameters:
      - random:
      - random:
          name: "Slow Random Effect"
          transition_length: 30s
          update_interval: 20s
      - random:
          name: "Fast Random Effect"
          transition_length: 4s
          update_interval: 5s
      - pulse:
      - pulse:
          name: "Fast Pulse"
          transition_length: 0.5s
          update_interval: 0.5s
      - pulse:
          name: "Slow Pulse"
          # transition_length: 1s      # defaults to 1s
          update_interval: 2s
      - addressable_rainbow:
      - addressable_rainbow:
          name: "Rainbow Effect"
          speed: 10
          width: 50
      - addressable_color_wipe:
      - addressable_color_wipe:
          name: "Color Wipe Effect"
          colors:
            - red: 10%
              green: 90%
              blue: 25%
              num_leds: 5
            - red: 35%
              green: 15%
              blue: 60%
              num_leds: 1
          add_led_interval: 100ms
          reverse: false
      - addressable_fireworks:
      - addressable_fireworks:
          name: "Fireworks Effect"
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: true
          fade_out_rate: 120
      - addressable_scan:
      - addressable_scan:
          name: "Scan Effect"
          move_interval: 100ms
          scan_width: 5
      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random "Twinkle Effect"
          twinkle_probability: 15%
          progress_interval: 32ms
      

I was thinking I could just set a timer based on the position of the sun… i.e. so when the sun is below the horizon the lights come on at 20% brightness. But I am not sure how I might integrate that into the existing code?

Here’s something I thought I might be able to use…

sun:
  latitude: !secret latitude
  longitude: !secret longitude
  on_sunset:
  - elevation: -10°
    then:
    - light.turn_on:
        id: bdrm_led_lights

I am sure there’s a much better way to do this… so any ideas/tips appreciated.

Still trying to make it work… haven’t been able to figure out multiple light triggers under different circumstances.

This code doesn’t work, so will keep trying options. Code highlighted with ** is my attempt at having the LED lights come on at 9pm, dimmed to 10%, and in red color only.

substitutions:
  off_hour: '5'
  on_hour: '9'

esp8266:
 board: d1_mini
 framework:
  version: recommended
  
esphome:
  name: esp4-bdrmlights 
  on_boot:
    - light.turn_off:
        id: bdrm_led_lights
        transition_length: 2.5s

status_led:
  pin: GPIO2

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:
  password: "<REDACTED>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp4-Bdrmlights Fallback Hotspot"
    password: "<REDACTED>"

captive_portal:

script:
  - id: turn_off
    mode: restart
    then:
      - delay: 90s
      - light.dim_relative:
          id: bdrm_led_lights
          relative_brightness: 10%
          transition_length: 0.1s
      - logger.log: "LED lights are Dimmed"

binary_sensor:
  - platform: gpio
    pin: D5
    id: bdrm_pir
    name: "Bdrm PIR Sensor"
    device_class: motion
    on_press:
      then:
      - if:
          condition:
            and:
              # If it's night time
              - sun.is_below_horizon:
              - lambda: |-
                  auto hour = id(my_time).now().hour;
                  return hour > 12 || hour < ${off_hour};
          then:
              #Turn on the LED lights
              - light.turn_on:
                  id: bdrm_led_lights
                  brightness: 40%
                  effect: random
              - logger.log: "LED lights are ON"
    on_release:
      - script.execute: turn_off

sun:
  latitude: !secret latitude
  longitude: !secret longitude

time:
  platform: homeassistant
  timezone: !secret timezone
  id: my_time
  on_time:
  - hours: ${off_hour}
    minutes: 0
    seconds: 0
    then:
    - light.turn_off:
        id: bdrm_led_lights
 
 **time:**
**  platform: homeassistant**
**  timezone: !secret timezone**
**  id: bdrm_on_time  **
**  on_time:**
**  - hours: ${on_hour}**
**    minutes: 0**
**    seconds: 0**
**    then:**
**    - light.turn_on:**
**        id: bdrm_led_lights**
**        brightness: 10%**
**        red: 100%**
**    - logger.log: "LED lights are Dimmed"**
        
light:
  - platform: neopixelbus
    variant: WS2812
    pin: D1
    num_leds: 54
    type: GRB
    name: "FastLED WS2812B Light"
    id: bdrm_led_lights
    default_transition_length: 7.5s
    effects:
      # Use default parameters:
      - random:
      - random:
          name: "Slow Random Effect"
          transition_length: 30s
          update_interval: 20s
      - random:
          name: "Fast Random Effect"
          transition_length: 4s
          update_interval: 5s
      - pulse:
      - pulse:
          name: "Fast Pulse"
          transition_length: 0.5s
          update_interval: 0.5s
      - pulse:
          name: "Slow Pulse"
          # transition_length: 1s      # defaults to 1s
          update_interval: 2s
      - addressable_rainbow:
      - addressable_rainbow:
          name: "Rainbow Effect"
          speed: 10
          width: 50
      - addressable_color_wipe:
      - addressable_color_wipe:
          name: "Color Wipe Effect"
          colors:
            - red: 10%
              green: 90%
              blue: 25%
              num_leds: 5
            - red: 35%
              green: 15%
              blue: 60%
              num_leds: 1
          add_led_interval: 100ms
          reverse: false
      - addressable_fireworks:
      - addressable_fireworks:
          name: "Fireworks Effect"
          update_interval: 32ms
          spark_probability: 10%
          use_random_color: true
          fade_out_rate: 120
      - addressable_scan:
      - addressable_scan:
          name: "Scan Effect"
          move_interval: 100ms
          scan_width: 5
      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: Random "Twinkle Effect"
          twinkle_probability: 15%
          progress_interval: 32ms
      

One of the awesome gurus on ESPHome discord gave me this code… but not being a C++ person I am unsure how to integrate it into my yaml. The idea behind this code is to simplify the entire yaml, and just use time of day rather than sunrise/sunset approach.

binary_sensor:
  - platform: template
    lambda: |-
      auto now = id(my_time).now();
      if (!now.is_valid())
        return {};
      int hour = now.hour;
      return ((hour > ${on_hour}) && (hour < ${off_hour}));

I think I am just going to start from scratch :laughing:

Took a radical approach… based on the code I was given.

binary_sensor:
# New code for turning lights on/off
  - platform: template
    id: my_time
    lambda: |-
      auto now = id(my_time).now();
      if (!now.is_valid())
        return {};
      int hour = now.hour;
      return ((hour > ${on_hour}) && (hour < ${off_hour}));
    on_hour:
      - light.turn_on:
          id: bdrm_led_lights
          brightness: 40%
          effect: random
      - logger.log: "LED lights are ON"
    off_hour:
      - light.turn_off
          id: bdrm_led_lights
      - logger.log: "LED lights are OFF"

Only… it complains about this section?

    off_hour:
      - light.turn_off
          id: bdrm_led_lights
      - logger.log: "LED lights are OFF"

Specifically the id: bdrm_led_lights

Missing a colon after light.turn_off

Thank for the feedback… turns out the code is quite wrong… having had some feedback from the ESPHome discord. Back to the drawing board :joy: