Last active
June 2, 2024 12:08
-
-
Save billchurch/787fd7b0032889c7bad0871981c5c5bd to your computer and use it in GitHub Desktop.
An example of an ESPHome based light (martin jerry MJ-S01) with an on-device timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
substitutions: | |
device_name: garage-light | |
friendly_name: Garage Light | |
default_delay: '900' # default delay of 15 minutes (900 seconds) | |
pre_off_warning: '30' # pre-off warning period in seconds | |
location: Garage | |
ha_timer_number: input_number.garage_light_timer | |
switch_name: Garage Interior Light Switch | |
motion_sensor_name: binary_sensor.motion_garage_motion_2 | |
esphome: | |
name: ${device_name} | |
comment: ${friendly_name} | |
platform: ESP8266 | |
board: esp01_1m | |
esp8266_restore_from_flash: true | |
globals: | |
- id: delay_length_global | |
type: int | |
restore_value: yes | |
initial_value: ${default_delay} | |
- id: flash_count | |
type: int | |
restore_value: no | |
initial_value: '0' | |
wifi: | |
ssid: !secret wifissid | |
password: !secret wifipass | |
fast_connect: off | |
domain: !secret domain | |
power_save_mode: none | |
ap: | |
ssid: "${device_name} Fallback Hotspot" | |
password: !secret wifipass | |
logger: | |
baud_rate: 0 | |
api: | |
encryption: | |
key: !secret esphome_key | |
reboot_timeout: 0s | |
services: | |
- service: start_${device_name}_timer | |
then: | |
- script.execute: start_timer | |
- service: update_delay_length | |
variables: | |
delay_length: int | |
then: | |
- lambda: |- | |
id(delay_length_global) = delay_length; | |
ESP_LOGD("main", "Delay length updated to %d seconds", delay_length); | |
id(start_timer).execute(); | |
ota: | |
# Device Specific Config | |
output: | |
- platform: gpio | |
pin: GPIO12 | |
id: relay1 | |
- platform: gpio | |
pin: GPIO4 | |
id: statuslight | |
light: | |
- platform: binary | |
name: ${friendly_name} | |
output: relay1 | |
id: lightid | |
on_turn_on: | |
then: | |
- script.execute: start_timer | |
- script.execute: flash_status_light | |
on_turn_off: | |
then: | |
- output.turn_off: statuslight | |
binary_sensor: | |
- platform: gpio | |
pin: | |
number: GPIO13 | |
mode: INPUT_PULLUP | |
inverted: True | |
name: "${switch_name}" | |
on_multi_click: | |
# single click | |
- timing: | |
- ON for at most 1s | |
- OFF for at least 0.5s | |
then: | |
- light.toggle: lightid | |
- script.execute: flash_status_light | |
- if: | |
condition: | |
light.is_on: lightid | |
then: | |
- script.execute: start_timer | |
# double click | |
- timing: | |
- ON for at most 1s | |
- OFF for at most 1s | |
- ON for at most 1s | |
- OFF for at least 0.2s | |
then: | |
- switch.toggle: timer_disable | |
# long click | |
- timing: | |
- ON for at least 1.5s | |
then: | |
- switch.turn_off: timer_disable | |
internal: true | |
id: switchid | |
- platform: status | |
name: "${friendly_name} Status" | |
- platform: homeassistant | |
name: "${motion_sensor_name}" | |
entity_id: ${motion_sensor_name} | |
id: motion_sensor | |
status_led: | |
pin: GPIO5 | |
text_sensor: | |
- platform: version | |
name: ${friendly_name} ESPHome Version | |
sensor: | |
- platform: homeassistant | |
entity_id: ${ha_timer_number} | |
id: delay_length_sensor | |
internal: true | |
on_value: | |
then: | |
- lambda: |- | |
id(delay_length_global) = int(id(delay_length_sensor).state); | |
ESP_LOGD("main", "Delay length updated to %d seconds from Home Assistant", int(id(delay_length_sensor).state)); | |
interval: | |
- interval: 2min | |
then: | |
- if: | |
condition: | |
wifi.connected: | |
then: | |
- homeassistant.service: | |
service: homeassistant.update_entity | |
data: | |
entity_id: ${ha_timer_number} | |
script: | |
- id: flash_status_light | |
then: | |
- output.turn_off: statuslight | |
- delay: 500ms | |
- output.turn_on: statuslight | |
- id: start_timer | |
mode: restart # Change mode to restart | |
then: | |
- if: | |
condition: | |
- switch.is_off: timer_disable | |
then: | |
- delay: !lambda "return (id(delay_length_global) - ${pre_off_warning}) * 1000;" | |
- logger.log: | |
format: "Script has hit pre_off_warning: ${pre_off_warning} seconds" | |
- repeat: | |
count: ${pre_off_warning} | |
then: | |
- output.turn_off: statuslight | |
- delay: 1s | |
- output.turn_on: statuslight | |
- delay: 1s | |
- if: | |
condition: | |
binary_sensor.is_on: motion_sensor | |
then: | |
- script.execute: start_timer | |
- light.turn_off: lightid | |
- output.turn_off: statuslight | |
switch: | |
- platform: template | |
name: "Timer Disable" | |
id: timer_disable | |
optimistic: true | |
on_turn_on: | |
then: | |
# this is kind of lame but i wanted a different | |
# flash and this was the easiest way for me | |
- script.execute: flash_status_light | |
- delay: 2.1s | |
- script.execute: flash_status_light | |
on_turn_off: | |
then: | |
- if: | |
condition: | |
light.is_on: lightid | |
then: | |
- script.execute: start_timer | |
time: | |
# when the clock strikes 12, re-enable the timer | |
- platform: homeassistant | |
id: homeassistant_time | |
on_time: | |
- seconds: 0 | |
minutes: 0 | |
hours: 0 | |
then: | |
- switch.turn_off: timer_disable |
Updated to add a motion sensor in Home Assistant referenced by the substitution motion_sensor_name
.
This will check to see if a motion sensor is showing occupied or (on) right before timer turns off the switch, if it shows occupied it starts the script again for the defined time.
If you're not using a motion sensor or want this functionality, then you'll need to remove any references to that in the binary_sensor
section:
- platform: homeassistant
name: "${motion_sensor_name}"
entity_id: ${motion_sensor_name}
id: motion_sensor
and the conditional in the script flash_status_light
:
- if:
condition:
binary_sensor.is_on: motion_sensor
then:
- script.execute: start_timer
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Garage Light Switch with ESPHome and Home Assistant Integration
This project demonstrates the integration of an ESP8266-based light switch this Martin Jerry MJ-S01 with Home Assistant. The setup includes functionality for handling on/off commands, a timer with a countdown warning, and integration with various sensors and Home Assistant services.
ESPHome Configuration
Substitutions
Home Assistant Automation
Define Input Numbers
This allows for control of the timer delay from Home Assistant. The
garage_light_timer_previous
is meant to hold the value ofgarage_light_timer
temporarily in the event you want to set a different timer via automation, and then revert back. Neither are required if you want to leave it up to the device.Automation to Update Previous Timer
This stores the value in case you want to change it temporarily, if you want to change it back just do the reverse of this.
Automation to Trigger the Switch
You can create an automation that triggers the switch based on various sensors such as door or motion detectors.
Features
Local Timer Reset at Midnight:
time
component in ESPHome.Disable Timer:
Flashing Status Light:
Persistence Across Reboots:
restore_value
option in theglobals
component.Usage