Skip to content

Instantly share code, notes, and snippets.

@zeroping
Created January 17, 2022 07:15
Show Gist options
  • Save zeroping/3da939a547a09654170f88a1d4cd6a7a to your computer and use it in GitHub Desktop.
Save zeroping/3da939a547a09654170f88a1d4cd6a7a to your computer and use it in GitHub Desktop.
An ESPHome config for the Linkind two-button relay switch - implements local timer behavior
# Basic Config
#---
#substitutions:
# https://esphome.io/guides/configuration-types.html#substitutions
# device_name: esp-br3 # hostname & entity_id
# warn_seconds: '60' #time to switch to red LED to indicate upcomming expiry
# increase_seconds: '(60 * 7)' # how much time to add each press
# This is for the Linkind WS240010008 two-button relay switch
# This config implements a fan or light timer.
# A long press on the top button set the output for continous on
# A short press on the bottom turns the output off
# Multiple short presses on the top button add time in a configurable increment. More presses adds more time.
# The LED blinks to indicate how many time peroids are left
# When time has almost run out, the LED turns red
esphome:
name: ${device_name}
esp32:
board: esp32dev
framework:
type: esp-idf
sdkconfig_options:
CONFIG_FREERTOS_UNICORE: y
wifi:
# https://esphome.io/components/wifi
#captive_portal:
# doesn't work under esp-idf
#web_server:
#port: 80
# https://esphome.io/components/web_server.html
# doesn't work under esp-idf
logger:
# https://esphome.io/components/logger
api:
#password: !secret esphome_api_password
# https://esphome.io/components/api
reboot_timeout: 0s #disable auto-reboot if homeassistant is not connecting
ota:
#password: !secret esphome_ota_password
# https://esphome.io/components/ota
light:
- platform: binary
id: relaylight
name: ${device_name} relay
output: relay
#on_turn_on:
#- output.turn_on:
#id: green_led
#on_turn_off:
#- output.turn_off:
#id: green_led
- platform: binary
id: greenlight
name: ${device_name} green led
output: green_led
- platform: status_led
id: redlight
name: ${device_name} red led
pin: GPIO26
internal: true
output:
- platform: gpio
# https://esphome.io/components/output/gpio.html
pin: GPIO5
inverted: false
id: relay
- platform: gpio
# https://esphome.io/components/output/gpio.html
pin: GPIO14
inverted: false
id: green_led
#pin: GPIO25 might or might not be hooked up to something? Not clear.
#- platform: gpio
## https://esphome.io/components/output/gpio.html
#pin: GPIO26
#inverted: false
#id: red_led
#replaced with the status_led entity above
binary_sensor:
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
pin:
number: GPIO32
inverted: true
mode: INPUT_PULLUP
name: ${device_name} Top Button
internal: false
on_click:
- script.execute: add_time_action
on_multi_click:
- timing:
- ON for at least 1s
then:
- script.execute: hold_on_action
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
pin:
number: GPIO33
inverted: true
mode: INPUT_PULLUP
name: ${device_name} Bottom Button
internal: False
on_click:
- script.execute: turn_off_action
globals:
- id: seconds_remaining
type: int
restore_value: no
initial_value: '0'
- id: blinks_completed
type: int
restore_value: no
initial_value: '0'
script:
# immediately stops the timer and turns everything off
- id: turn_off_action
then:
- output.turn_off:
id: green_led
- light.turn_off:
id: redlight
- light.turn_off:
id: relaylight
- globals.set:
id: seconds_remaining
value: '0'
- logger.log:
format: "turning off"
# gives a way to hold the fan in the on state
- id: hold_on_action
then:
- output.turn_on:
id: green_led
- light.turn_on:
id: redlight
- light.turn_on:
id: relaylight
- script.stop: timer_countdown
- globals.set:
id: seconds_remaining
value: '0'
- logger.log:
format: "holding output on by request"
- id: blink_remaining_script
mode: restart
then:
# we will count up, so if seconds_remaining increases while we're blinking, we keep going
- globals.set:
id: blinks_completed
value: "0"
- logger.log:
format: "blinking %d times"
args: [ 'id(blinks_completed)' ]
- while:
condition:
lambda: |-
return(id(blinks_completed) < ( (id(seconds_remaining) + 5) / ${increase_seconds} ) );
then:
- light.turn_on: redlight
- delay: 0.15s
- light.turn_off: redlight
- delay: 0.15s
- lambda: |-
id(blinks_completed) += 1;
# adds time to the runtime, turning things on if off
- id: add_time_action
then:
- output.turn_on:
id: green_led
- light.turn_off:
id: redlight
- light.turn_on:
id: relaylight
- lambda: |-
id(seconds_remaining) += ${increase_seconds};
- if:
condition:
not:
script.is_running: timer_countdown
then:
script.execute: timer_countdown
- if:
condition:
not:
script.is_running: blink_remaining_script
then:
script.execute: blink_remaining_script
- logger.log:
format: "adding time, total %d s"
args: [ 'id(seconds_remaining)' ]
# once started, this counts down until intervals_remaining is off
- id: timer_countdown
then:
- while:
condition:
lambda: |-
return(id(seconds_remaining) > 0);
then:
- if:
condition:
lambda: |-
return(id(seconds_remaining) < ${warn_seconds});
then:
- output.turn_off:
id: green_led
- light.turn_on:
id: redlight
- logger.log:
format: "seconds_remaining %d"
args: [ 'id(seconds_remaining)' ]
- delay: 1s
- lambda: |-
id(seconds_remaining) -= 1;
- script.execute: turn_off_action
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment