Skip to content
/ ping4pow Public

Monitor (ping) network resources as a condition for powering a connected device.

License

Notifications You must be signed in to change notification settings

rtyle/ping4pow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

165 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ping4pow

Motivation

Upon network recovery, sensitive equipment may need to be rebooted after things have settled. Some equipment may need to be rebooted to facilitate network recovery. For many such equipment, power to the device can be cycled to achieve this. Without automation, this must be done manually. It would be better with automation that could recognize such conditions and cycle power.

There are commercially available/configurable devices that address this issue.

This is a better solution.

Ping4pow can only switch loads that can be safely handled by its relay. Relay solutions that are embedded in its small footprint will only be able to switch low voltage loads. However, an external relay solution (like an iot-power-relay) can be controlled by a GPIO pin for more demanding loads.

Features

  • Small, attractive package
  • Display with touchscreen user interface
  • Display can be turned off
  • User interface can be locked
  • Home Assistant integrable but not required for automation
  • Wired (ethernet) access for reliable network monitoring
  • Powered by Power-over-Ethernet (PoE)
  • Flexible relay solutions for handling loads
  • Galvanically isolated switching of equipment power
  • Network health is determined by pinging multiple IP addresses
  • Network failure is when all addresses can not be pinged for a while.
  • Network recovery may be facilitated by cycling power; otherwise
  • Network recovery is when all addresses can be pinged for a while and then power is cycled.
  • Email notification of power cycle.

Architecture

Hardware

M5Stack products are used to provide a small and attractive hardware solution that does not require a custom enclosure for switching low voltage loads. Our stack needs a core with support from a base LAN PoE module.

To support both the core display and the ethernet LAN at the same time, a custom M5-Bus adapter must be used to resolve GPIO pin conflicts. This might be done using an M5Bus bodge-wired Module Proto. Alternately, the PCB of the Module Proto might be swapped out with one that has the bodge baked in (see adapter).

To switch the load we will need a relay. M5Stack provides a 4Relay Module. Alternately, the M5-Bus adapter might be expanded to provide a relay using the frame of an M5Stack Module13.2 Proto (see adapter_relay).

A Module13.2 Proto might also be used to bodge-wire the M5-Bus adapter and provide external access to the same GPIO pin used by the adapter_relay. This could be used to drive an external relay for more demanding loads.

Software

ESPHome is used because of its ability to support our chosen hardware and the potential for other choices. It can be configured in a high level language (YAML) and will only do what you tell it to do. A configured device can perform all the automations without any external support. Optionally, such a device can be used by Home Assistant.

Deployment

Hardware

The stack should be assembled with the core on top, followed by the relay solution, the adapter solution and finally the PoE base.

Module13.2 4Relay v1.1 and Module Proto adapter

This solution uses the Module13.2 4Relay v1.1 and a separate M5-Bus Module Proto based adapter. The adapter can be built from the adapter kicad project or hand made using its schematic for a reference. If hand made, the disconnected male pins should be clipped and the re-routing of signals made using bodge wires.

Only the first signal relay in the module will be used. It will be configured to provide module input power to relay output power in a Normally Closed (NC) fashion. We want the relay to operate in a NC fashion so that when power is removed from the stack the relay will be closed (power to the controlled device will be on).

Module input power must be galvanically isolated from the M5-Bus (stack) HPWR and system GND. Remove the jumpers that connect these.

Set the relay jumpers in the "load" configuration.

The relay is hard-wired on the module in a Normally Open (NO) fashion. That is, the relay output power is connected by PCB trace to the NO pin on the relay. Cut this trace and add a bodge wire to connect the relay ouput power with the NC pin on the relay.

Wire module input power pins to an adapter pigtail that accepts the plug of the power adapter of the controlled device. Alternately, cut the plug off the power adapter and wire the adapter directly to the 4relay input power plug. Wire relay power output pins to an adapter pigtail that provides the power plug expected by the controlled device. Alternately, cut the plug off the power adapter and wire the plug directly to the 4relay output power plug.

Module13.2 Proto adapter_relay

This solution uses a Module13.2 Proto frame with the PCB replaced with one built from the adapter_relay kicad project. There is no need for a separate M5-Bus adapter.

The adapter_relay uses a double-pole double-throw (DPDT) signal relay to switch both conductors of the galvanically isolated DC load. Jumpers must be installed in the normally-closed (NC) positions. The load is passed through the board using standard 5.5mm x 2.1mm DC barrel connections. Openings in the frame of the Module13.2 Proto must be expanded to accomodate the DC jacks. It doesn't matter which jack is used for which plug.

Base LAN PoE v1.2

Stack an M5-Bus adapter on top using one of the methods described above. Power, and supply network access, over the RJ45 ethernet port.

Software

These instructions are written for a Fedora Linux platform. Similar steps may be taken for other Linux, MacOS or Windows platforms.

Get the source from this repository by the appropriate method:

git clone https://github.com/rtyle/ping4pow.git
git clone git@github.com:rtyle/ping4pow.git

All commands documented here are executed from this directory.

cd ping4pow

Install python

sudo dnf install python

Create a python virtual environment for this project.

python -m venv .venv

Activate the virtual environment every time you want to use ESPHome within this project.

source .venv/bin/activate

With your virtual environment activated, install ESPHome using pip:

pip install esphome

Configure the order, address and name of each host to be ping-monitored. Each is specifed by an address, name pair in an m4 host macro invocation. Add a third argument for a host that must be power-cycled when all are not pingable for a while; otherwise, wait for all hosts to be pingable for a while before power-cycling.

cp config/hosts{.example,}.m4; vi config/hosts.m4

Optionally, configure (smtp) email notification.

cp config/smtp{.example,}.m4; vi config/smtp.m4

Configure secrets.yaml.

cp config/secrets{.example,}.yaml; vi config/secrets.yaml

These secrets will be protected by flash encryption on/by the device.

Choose an ESPHome configuration for M5Stack Module13.2 4Relay hardware (default) or a GPIO relay.

(cd config; m4 ping4pow.m4 > ping4pow.yaml)
(cd config; m4 -DGPIO_RELAY ping4pow.m4 > ping4pow.yaml)

The first firmware flash of this ESPHome configuration must be done with a USB cable between your computer and the M5Stack CoreS3. Do not interrupt this first boot!

esphome run config/ping4pow.yaml

Upon the first boot after the first flash, the secondary boot loader will encrypt the content of the flash in place. Subsequently, only use ESPHome to flash Over The Air (OTA) as ESPHome flashing by USB will cause the firmware to be unencrypted which will upset the first stage bootloader to no end:

[11:31:08.073]invalid header: 0x487325b7
...

To recover from this problem, the device must be flashed properly:

bin=.esphome/build/ping4pow/.pioenvs/ping4pow
python -m esptool --chip esp32s3 --port /dev/ttyACM0 write-flash --encrypt 0x0 $bin/firmware.factory.bin

Connect by ethernet to a power-over-ethernet capable port and unplug the USB cable. Connect the switched load to the relay.

Usage

Each ping target defined (by address & name) and ordered (#) in the hosts.m4 file will be periodically pinged. Each will be represented by a

  • ping # (address name) switch (where # is its order) to enable/disable pinging and summary consideration of the target.
  • ping # able binary sensor that reflects the pingability of the target.
  • ping # since sensor that reflects the time elapsed since the last change in pingability.

These target ping sensors will be summarized by a

  • ping none binary sensor that is true unless an enabled target is pingable.
  • ping all binary sensor that is true unless an enabled target is not pingable.
  • ping some binary sensor that is true if "ping none" and "ping all" are false.
  • ping count sensor that reflects the number of enabled and pingable targets.
  • ping since sensor that reflects the time elapsed since the last change in target pingability.

The automation provided by ping4pow is implemented as a state machine. These states are reflected in the user interface as switches. Only one state/switch can be active/on at a time. States can be entered through a switch action in the user interface. These states/switches are:

  1. stop. When on, the state machine is stopped. Turn off to advance to the next state.
  2. wait for ping none, then advance to the next state.
  3. wait while ping none, then advance to the next state; otherwise, the previous state.
  4. wait for ping all, then advance to the next state.
  5. wait while ping all, then advance to the next state; otherwise, the previous state.
  6. power cycle: turn power off, pause, turn power on and then start over.

States 3 and 4 are skipped if there is a host that must be power-cycled when all are not pingable for a while.

If there is In addition, ping4pow exposes

  • A power switch that reflects/controls power to the connected load.
  • A since boot sensor that reflects the time elapsed since booting the ping4pow device.
  • A since power cycle sensor that reflects the time elapsed since the power to the load was automatically affected.

All since sensors are in units of seconds.

A web-based user interface at http://ping4pow.local exposes these switches and sensors.

These are also presented locally on the ping4pow device's display.

Under the display are soft buttons on the bezel

  • Decrease display brightness
  • Navigate home to state tile
  • Increase display brightness

At the bottom of the display is a user interface lock and tile navigation buttons

  • Previous tile in rotation
  • User input is locked ( when not)
  • Next tile in rotation

The rest of the display is used for the current tile. Using the next and previous tile controls, one can rotate through them. The tiles are:

  • Splash tile
  • State tile
  • Since tile
  • Target tile (one for each)

Splash Tile

A ping4pow image is displayed briefly on boot before advancing to the next tile.

State Tile

The top row of buttons reflect states 1, 2, 3 and 4.

  • wait for ping none
  • wait while ping none
  • wait for ping all
  • wait while ping all

The middle row of buttons reflect state 0, power and state 5

  • stop ( when stopped)
  • power
  • power cycle

The bottom row reflects the summary ping sensors. At most, one of these will be on. The label on the widget reflecting state of the ping some binary sensor will reflect the ping count sensor value regardless.

  • ping none
  • ping some with ping count (#)
  • ping all

Since Tile

The three rows of this tile reflect times since an event. This time is formatted as either "N/A" (if there was never such an event) or the number of days, hours, minutes and seconds (D HH:MM:SS) since the event.

  • ping since
  • since power cycle
  • since boot

Target Tile

There is a target tile for each ping target in hosts.m4.

The first row of this tile reflects whether the target is enabled and its pingability.

  • ping # (address name) enabled ( when not)
  • ping # able ( when not)

The next two rows are for ping # since and for identifying the target by address and name.

  • ping # since
  • address name