Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.
A lamp that asks Home Assistant for sunset stops when the hub or the Wi-Fi does. This firmware asks the sun for its elevation on the ESP32 itself. SNTP and, when it is reachable, Home Assistant time both set the clock. After a reboot the relay and the dimmer come back to the last state, then the schedule takes over again once the clock and the sun reading are valid.
Latitude, longitude, and timezone in the file are placeholders (0.0, 0.0, UTC). Set them before the first flash. Do not publish the real coordinates.
Mains stays on a relay that is listed for that load, in an enclosure, wired by someone qualified. A 12 V strip can use the MOSFET pin instead. Do not put mains on the MOSFET.
What problem it solves
You want an outdoor lamp on around dusk and off around dawn, plus an optional late-night gap, without a hub in the decision.
How it works
The board is any ESP32 that matches esp32dev. ESPHome computes sun elevation from the substitutions. A template select is the mode. Template numbers are the thresholds. Both outputs follow one decision: a GPIO relay (pack default GPIO4, active-low) and a 1000 Hz LEDC dimmer (pack default GPIO16) driving a monochromatic light.
- Mode —
Onforces both outputs on.Offforces them off.Autouses the schedule. The choice is restored after a reboot. - Sun — in Auto, the lamp turns on when elevation is at or below On at or below (pack default −0.8°, near the horizon). It turns off when elevation is at or above Off at or above (same default). If the two numbers overlap, the lamp holds its current state instead of chattering.
- Clock — elevation is ignored until the clock year is 2024 or later and the sun sensor is a real number. Until then the decision text reads
waiting for timeorwaiting for sun, and the outputs stay where restore left them. - Night gap — Night off hour (0–23, pack default 23) and Morning on hour (0–23, or 24 to disable, which is the default) define a stretch where Auto forces the lamp off even if the sun is still down. A morning hour of 24 with an off hour of 12 or later means “off from that hour until noon.” Set both hours inside 0–23 to wrap across midnight when the off hour is later than the morning hour.
- Dim level — 5–100%. The relay is only on or off. The dimmer uses this percent. Wire the output you actually have; the unused one can stay unconnected.
- When it runs — on boot, every 60 seconds, when either time source syncs, and when you change a number or the mode. A text sensor named Lamp decision shows
on,off,sun,day,night cutoff, orhold.
There is no web page on the device. Wi-Fi credentials and the API key stay in secrets.yaml.
Hardware notes
- Board. Classic ESP32, ESPHome board
esp32dev, ESP-IDF. An ESP32-C6 or C3 Super Mini needs a differentboard:line and a pin check before you flash this file. - Relay. GPIO4,
inverted: true, because many 5 V modules are active-low. If the lamp comes on when the log says off, fliprelay_inverted. The module’s JD-VCC jumper and a separate coil supply are the usual way to keep coil current off the ESP32’s 3.3 V pin. The ESP32 ground and the coil ground still have to meet. - Mains. A hobby relay module is not a mains enclosure. Use a relay rated for the lamp voltage and current, a box, strain relief, and a person who is allowed to wire it. This pack does not include a mains diagram.
- Dimmer. IRLZ44N or another MOSFET that is actually on at 3.3 V. Low side of a 12 V strip: drain to the strip negative, source to ground, gate toward GPIO16. About 220 Ω between the pin and the gate, and about 10 kΩ from gate to source, so the strip stays off while the pin floats at boot. Common ground with the ESP32. 12 V never touches a GPIO.
- Placeholders.
latitude: "0.0"andlongitude: "0.0"are the Gulf of Guinea, not a house. Elevation there is not your dusk. Set both, andtimezone, insubstitutionsbefore you trust Auto.
Snippet
The schedule lives in the script in the pack. The substitutions you must edit first are these.
substitutions:
device_name: outdoor-lamp
latitude: "0.0"
longitude: "0.0"
timezone: UTC
relay_pin: GPIO4
relay_inverted: "true"
dimmer_pin: GPIO16
Setup outline
- Copy
esphome/secrets.example.yamlinto your ESPHome secrets and fill Wi-Fi, a new API key, OTA, and the fallback hotspot password. - Paste the device YAML. Set latitude, longitude, and timezone. Leave the mode on Auto.
- Validate, then flash over USB. Confirm Lamp decision leaves
waiting for timeonce SNTP syncs. - Set mode to On and Off and confirm the relay (or the strip) follows. Set Auto again.
- Nudge On at or below above the live elevation and confirm the lamp comes on. Put the numbers back to about −0.8 unless you want civil twilight instead of the horizon.
- If you want the lamp dark after 23:00 even in winter, leave Night off hour at 23 and set Morning on hour to the hour it may turn on again (6 is a common choice). 24 means that morning gate is disabled.
Troubleshooting
- It stays on
waiting for time. SNTP never synced and Home Assistant time is not connected. Check Wi-Fi and the timezone string (America/Denver, not an offset pasted from a browser). - It stays on
waiting for sun. The clock is valid but elevation is still empty. Give the sun sensor one 60 second update after time sync. - The lamp is on in the middle of the day. Off at or above is below the current elevation, or the mode is On. Read Lamp decision.
daymeans the sun threshold turned it off.sunmeans it is supposed to be on. - It never turns off after midnight. Night off hour is 24, which disables the gap, or Morning on hour is 24 and the off hour is in the morning. The text sensor should say
night cutoffinside the gap. - Relay is backwards. Flip
relay_invertedand reflash. Do not “fix” that by swapping mains conductors. - Dimmer barely lights. The MOSFET is not logic-level, or the dim level is still at the minimum of 5%. A plain IRF520 module will not turn on from 3.3 V.
- A reboot left the lamp on until the clock synced. That is restore. Auto does not change the outputs until time and elevation are both valid.
Credits
Based on ESPhome-outdoor-lamp-controller. That project schedules an outdoor lamp from the sun, with twilight presets and a group of lamps that stay in step. This pack is a single lamp: local elevation, a mode select, a night gap, and one relay plus one PWM dimmer. It does not sync a group, watch a wall switch, or use a daylight sensor.