Skip to content

Instantly share code, notes, and snippets.

@mpflaga
Last active December 30, 2023 02:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpflaga/9bc5586a42d191477e4ba077c710f765 to your computer and use it in GitHub Desktop.
Save mpflaga/9bc5586a42d191477e4ba077c710f765 to your computer and use it in GitHub Desktop.
ESPHome recipe using SonOff S31 as an external Ping Watchdog.

This watchdog will power cycle the relay after the prescribed number of ping failure occurs. Additionally, the package is setting up metering sensors for testing and monitoring purposes.

Notes:

  1. This project relies on trombik/esphome-component-ping. The ./components/ping/. directory and files must be manually installed/copied into the `./esphome/config/.' directory, or equivalent, that will be compiling the firmware. It is straightforward, just follow the installation instructions on the Github README.

  2. Substitutions in the main homeassistant-watchdog-ping.yaml have been provided allowing "End Users" to customize the target_ip_address, ping_loss_threshold, off_delay and possibly the ping_hold_off to fit their specific needs.

  3. api.reboot_timeout is disabled by default, assuming this project is not used with Home Assistant. If desired then substitute api_loss_threshold with your desired time out.

  4. ESPHome - homeassistant API watchdog may be a better and simpler solution for watchdog monitoring of Home Assistant itself via its native API connection to the ESP device. As it is a simpler implementation using only native components, no external libraries or components.

  5. This project has multiple files arranged as packages for modular setup of hardware, network and features.

    • homeassistant-watchdog-ping.yaml - Top level file, that combines the below.
      • .ping-watchdog.yaml - Abstracting particulars for the watchdog.
      • .network.yaml - Abstracting network setup.
      • .sonoff-s31.yaml - Abstracting hardware setup.
      • ./components/ping/. - Directory containing non-standard ping component.
  6. The . dot prefix hides the files from ESPHome's HomeAssistant integration. The same can be done with the main file. As to prevent it from getting updated by the ESPHome's "UPDATE ALL" command. As the "UPDATE ALL" sequence may or may not be desired and may result in a premature power cycling of "order critical" devices, such as Home Assistant/ESPHome. Given it likely would not be the last in the upgrade order.

  7. The off_delay should be specified to a sufficiently long enough time, to ensure all dependent devices power cycle and not just the Rpi. Such as any USB-SSD devices and any other USB devices. The default is set to 5s.

# ESPHome Package for basic network setup of remote device
# example use:
# substitutions:
# esphome_name: living-room
# packages:
# board: !include .shellyplus1.yaml
# network: !include .network.yaml
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
domain: .lan # My network uses this domain, yours may vary.
ap:
ssid: ${esphome_name}
password: !secret wifi_password
captive_portal:
web_server:
port: 80
auth:
username: !secret web_server_username
password: !secret web_server_password
api:
encryption:
key: !secret api_encryption_key
ota:
password: !secret ota_password
sensor:
- platform: wifi_signal
name: "WiFi Signal"
# update_interval: 60s # default is 60s
binary_sensor:
- platform: status
name: "API/MQTT Connection"
id: apimqtt_connection
# ESPHome package for watchdog monitoring of remote device's IP connection.
# Required:
# relay, should be defined by main or other yaml.
# target_ip_address: 192.168.20.121 # IP address to monitor.
# Optional:
# ping_loss_threshold: 3 # Number of minutes without pings to trigger relay.
# Typically 30 for real and 3 for testing.
# ping_hold_off: "5" # number of minutes after trigger, before pings are
# monitored again.
# api_loss_threshold: "0min" # The default is 15 min, 0 is disabled.
# # Should be disabled when not used with HA.
#
# example use:
# esphome_name: homeassistant-watchdog
# friendly_name: HomeAssistant Watchdog
# packages:
# board: !include .sonoff-s31.yaml
# network: !include .network.yaml
# watchdog: !include .ping-watchdog.yaml
#
# recommended hardware:
# https://www.amazon.com/Sonoff-S31-SONOFF-Plug-White/dp/B08TNF4835
substitutions:
# IP address to monitor.
target_ip_address: "127.0.0.1"
# Number of minutes without pings to trigger relay.
# Note - Typically 30 for real and 3 for testing.
ping_loss_threshold: "3"
# Number of minutes after trigger, before pings are monitored again.
ping_hold_off: "5"
api_loss_threshold: "0min" # The default is 15 min, 0 is disabled.
off_delay: "5s" # Off time of relay, Select a time as to avoid "brown-out".
# Note this is time for all hardware. Rpi and SSD, etc...
# Caution - needs to be longer than startup of HA.
# Other reboots default to 15, e.i WiFi. So lets give them a chance first.
# Dependancies
esphome:
libraries:
- ESP8266WiFi # Load a none standardard Platform IO library, used by below.
- https://github.com/akaJes/AsyncPing # Load an externally sourced library for new ping component
external_components:
# The ping library should be placed into the following directory.
# See README.md at https://github.com/trombik/esphome-component-ping
- source: # include locally custom component.
type: local
path: ./components
# Enable Home Assistant API.
api:
# When ping target is HA then api.reboot_timeout should be extended then
# ping_loss_threshold.
reboot_timeout: ${api_loss_threshold} # 15min is default
# Variable to hold counter of successive failed pings,
# it is updated after every ping update period.
# When negative value is a holdoff.
globals:
- id: ping_loss_counter
type: signed int
restore_value: false
initial_value: "0"
switch:
# This is very important, as the default is ALWAYS_OFF
- id: !extend relay
restore_mode: ALWAYS_ON
binary_sensor:
# Remove prior button actions as dict.
- id: !extend button
on_press: {}
# Then create a new action guarenteed to turn back on.
- id: !extend button
on_press:
- switch.turn_off: relay
- delay: ${off_delay}
- switch.turn_on: relay
wifi:
# Watchdog of ESP device itself for missing Wi-Fi.
# Caution - needs to be longer than startup of network equipment
reboot_timeout: 15min # 15min is default
sensor:
# Uptime component is helpful for monitoring watchdog timeouts events.
# This can be compared to HA's uptime, for problem solving.
- platform: uptime
name: Uptime
id: esp_uptime
# Custom ESPHome Component PING
# https://github.com/trombik/esphome-component-ping
- platform: ping
ip_address: ${target_ip_address}
num_attempts: 2
timeout: 2sec
update_interval: 60s # Typically 60s for real and 10s for testing.
loss:
name: Packet loss
id: loss
on_value:
then:
- logger.log:
format: PING percent_packet_loss=%0.1f, ping_loss_counter=%d
args: [id(loss).state, id(ping_loss_counter)]
- if:
condition:
# when there are some PINGs and not in hold off
lambda: !lambda |-
return (id(loss).state < 100) && id(ping_loss_counter) > -1;
then:
# When Pings are good, reset the counter
- logger.log:
format: There are pings, clearing ping_loss_counter.
- globals.set:
id: ping_loss_counter
value: "0"
else:
- if:
condition:
# increament counter and check ping counter vs threshold
lambda: !lambda |-
if (id(ping_loss_counter) < ${ping_loss_threshold}) {
// only increament when below max limit, else it may eventually roll
id(ping_loss_counter)++;
}
ESP_LOGD("main", "ping_loss_counter= %d", id(ping_loss_counter));
return (id(ping_loss_counter) > (${ping_loss_threshold} - 1));
then:
# When there have been no pings, for to long.
- logger.log:
format: No pings for %d seconds. Too long, resetting relay
args:
- !lambda |-
id(ping_loss_counter)
- switch.turn_off:
id: relay
- switch.turn_on:
id: relay
- globals.set:
id: ping_loss_counter
value: -${ping_hold_off}
latency: # not needed for this use case.
name: Latency
accuracy_decimals: 3
id: latency
on_value:
then:
- logger.log:
format: PING average_response_ms=%0.1f
args: id(latency).state * 1000
# ESPHome Package for hardware setup of Shelly Plus 1
# example use:
# substitutions:
# esphome_name: living-room
# friendly_name: Living Room
# packages:
# board: !include .sonoff-s31.yaml
# network: !include .network.yaml
substitutions:
model_name: "Sonoff S31"
esphome:
name: ${esphome_name}
friendly_name: ${friendly_name}
esp8266:
board: esp01_1m
logger:
baud_rate: 0 # (UART logging interferes with cse7766)
uart:
rx_pin: RX
baud_rate: 4800
switch:
- platform: gpio
name: "${model_name} Relay"
pin: GPIO12
id: relay
restore_mode: ALWAYS_OFF # The default is ALWAYS_OFF
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "${model_name} Button"
id: button
on_press:
- switch.toggle: relay
sensor:
- platform: wifi_signal
name: "${model_name} WiFi Signal"
update_interval: 60s
- platform: cse7766
current:
name: "${model_name} Current"
accuracy_decimals: 1
voltage:
name: "${model_name} Voltage"
accuracy_decimals: 1
power:
name: "${model_name} Power"
accuracy_decimals: 1
id: my_power
- platform: total_daily_energy
name: "${model_name} Daily Energy"
power_id: my_power
time:
- platform: sntp
id: my_time
status_led:
pin:
number: GPIO13
inverted: True
substitutions:
esphome_name: homeassistant-watchdog
friendly_name: HomeAssistant Watchdog Ping
target_ip_address: "192.168.20.121" # IP address to monitor.
ping_loss_threshold:
"3" # Number of minutes without pings to trigger relay.
# Typically 30 for real and 3 for testing.
ping_hold_off:
"5" # number of minutes after trigger, before pings are
# monitored again.
packages:
board: !include .sonoff-s31.yaml
network: !include .network.yaml
wathdog: !include .ping-watchdog.yaml
logger:
level: VERBOSE
#wifi:
# use_address: 192.168.20.?
@mpflaga
Copy link
Author

mpflaga commented Dec 30, 2023

Added "off_relay" delay to control proper off time as a managed variable.

@mpflaga
Copy link
Author

mpflaga commented Dec 30, 2023

Added to Readme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment