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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:and the conditional in the script
flash_status_light
: