Standalone time-based light on

I’m looking to deploy a light at a friends house, they want this light to come on at certain times and go off at certain times as a driveway light. As the seasons change they just want to be able to bring up the WebUI and change when that on / off time is.

Right now I’ve got:

wifi:
  ap:
    ssid: "DrivewayLEDs

captive_portal:

web_server:
  port: 80

output:
  - platform: ledc
    pin: 22
    frequency: 850 hz
    id: pwm_output1
    inverted: false
  - platform: ledc
    pin: 21
    frequency: 850 hz
    id: pwm_output2
    inverted: false

light:
  - platform: monochromatic
    output: pwm_output1
    gamma_correct: 1.0
    name: "DrivewayLED1"
    id: "DrivewayLED1
  - platform: monochromatic
    output: pwm_output2
    gamma_correct: 1.0
    name: "DrivewayLED2"
    id: "DrivewayLED2"

time:
  - platform: sntp
    id: sntp_time

They’re less technical so the idea is that I can flash an M5Stack Atom Lite, and then send it across the country to them.

We know it’ll work with the ledc like this, hooked into their LED driver, but I just ideally wanna now give them a way to set:

  • Time on
  • Time off

And have it do the same every single day without fail, 365 days a year.
Then, 2-3x a year they can log in to the WebUI of it and change it from, say, lights turning on at 1800 to make them come on at like 2100 in the summer.

What’s the best way to make this work all self-contained on the unit itself?

This is not something I’ve tried so I don’t know if the value can be edited from the ESPhome web UI of the device but how about trying a number as the hour value for ‘turn on light’ and another for the hour value of ‘turn off light’.

You will need to create the automations in ESPhome to grab those ‘hour’ values and use them to control the light.

Yeah that was what I wasn’t sure about, but it’s nifty being able to adjust the LED brightness… Now to just have a timer that’s easily adjustable :sweat_smile:

I just did a quick test and the number can be edited from the ESPhome web UI.

Code:

number:
  - platform: template
    name: "Template number"
    optimistic: true
    min_value: 16
    max_value: 23
    step: 1

Using the above you could create an ESPhome automation to use that number value in place of the hour value of the light.turn_on.

See if you can create a lambda for the hour section in the below, to use the above number entity.

When I used:

time:
  - platform: sntp
    id: sntp_time
  - platform: sntp
    on_time:
      - seconds: 0
        minutes: 00
        hours: 19
        then:
          - light.turn_on: DrivewayLED1
      - seconds: 0
        minutes: 0
        hours: id.time_off()
        then:
          - light.turn_off: DrivewayLED1

It’s just complaining with:
image

I’m not familiar enough with lambdas or global variables to make that last aspect work sorry :frowning:
Any help would be greatly appreciated

I’m not experienced with lambda’s either unfortunately.

Try creating the time value like:

number:
  - platform: template
    name: "Template number"
    id: ontimehour
    optimistic: true
    min_value: 16
    max_value: 23
    step: 1

The have an automation something like:

time:
  - platform: sntp
    on_time:
      - seconds: 0
        minutes: 0
        hours: !lambda |-
          return id(ontimehour)
        then:
          - switch.turn_on: DrivewayLED1

Then a similar setup for the ‘off time’

image

Well, damn :frowning:

OK. So we need to tackle it a little differently.

automation:
  - alias: "Turn on Light at Specific Time"
    trigger:
      # Trigger every minute to check the time
      platform: time
      minutes: "/1"  # Every minute
    action:
      # Check if the current hour matches the number value
      - condition:
          lambda: |-
            return id(ontimehour).state == id(sntp_time).now()
      - light.turn_on:
          id: DrivewayLED1

Oohhhhhh very cool, thanks @sparkydave ! I’ve had to head out of the house for a bit, but I’ll give that a try upon my return.

Very grateful, thankyou :slight_smile:

No worries mate. I’m keen to hear how it pans out as it’s the kind of thing I might do for a project of my own.

OK so I tried:

time:
  - platform: sntp
    id: sntp_time

interval:
  - interval: 1min
    then: 
    - if:
        condition:
          lambda: |-
           'return id(time_on_hour).state == id(sntp_time).now()'
           'return id(time_on_mins).state == id(sntp_time).now()'
        then:
        - light.turn_on:
            id: DrivewayLED1

But unfortunately it didn’t like that when compiling:

/config/esphome/m5stack-poesp32-3.yaml:95:7: warning: character constant too long for its type
            'return id(time_on_hour).state == id(sntp_time).now()'
       ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/config/esphome/m5stack-poesp32-3.yaml:96:7: warning: character constant too long for its type
            'return id(time_on_mins).state == id(sntp_time).now()'
       ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/config/esphome/m5stack-poesp32-3.yaml: In lambda function:
/config/esphome/m5stack-poesp32-3.yaml:95:55: error: expected ';' before '\x6f772829'
            'return id(time_on_hour).state == id(sntp_time).now()'
                                                       ^
                                                       ;
            'return id(time_on_mins).state == id(sntp_time).now()'
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/config/esphome/m5stack-poesp32-3.yaml:97:3: warning: no return statement in function returning non-void [-Wreturn-type]
         then:
   ^
*** [/data/m5stack-poesp32-3/.pioenvs/m5stack-poesp32-3/src/main.cpp.o] Error 1

I think I need to adjust the id(sntp_time).now() to be either minutes, or hours using strftime:

As I couldn’t get the “automation:” to work as that seemed more like HA YAML for putting into configuration.yaml than for use in esphome?

Yeah sorry. I was running that without too much thought (supposed to be working!) so got the two switched up.

Again, this bit is something I’m not confident with, but maybe something like:

interval:
  - interval: 1min
    then: 
    - if:
        condition:
          lambda: |-
           'return id(time_on_hour).state == id(sntp_time).now.hour()'
           'return id(time_on_mins).state == id(sntp_time).now.minute()'
        then:
        - light.turn_on:
            id: DrivewayLED1

Gave that a shot but it’s still complaining about the lambda unfortunately :frowning: Even adding the semicolon it wants

Maybe try:

interval:
  - interval: 1min
    then: 
    - if:
        condition:
          lambda: |-
           if id(time_on_hour).state == id(sntp_time).now.hour()
        then:
        - light.turn_on:
            id: DrivewayLED1

I’ve simplified it to just the hour for now until we get it working, then we try adding in the minute section. I figure ‘small steps’!

Unfortunately no joy still :frowning:
image

Appreciate your patience and continued attempts though

Hopefully someone else with better ESPhome lambda experience can chime in for us.

1 Like

Thought I’d bump this thread up and see if anybody else has any ideas. I’d kinda put it on hold for the last 6 weeks but got reminded that it was still a thing :sweat_smile:

Any guidance would be greatly appreciated.