In a quest not to need an external button press, have the system boot as soon as DC power is available, and allow the system to shutdown gracefully, I have developed the following method and want to share for those that will benefit.
This aims to:
- Safely (gracefully) shutdown the pi
- Enter EDM mode, just before halt, reboot, or poweroff (as catch alls, the behavior is the same)
- Allow the system to boot without external intervention as soon as power is applied (no button press)
As mentioned in other posts, a “shutdown” using this method will result in a system reboot. This is intentional and desired behavior in my use case. Alter as needed. When no DC power is connected, the system will shutdown (into EDM) and power down all connected peripherals.; if DC is (re)connected, the system will boot.
The EDM function does NOT shut the system down or bring the runlevel down to 0 gracefully, it simply cuts power and puts the HAT into EDM. That’s bad, and this is how to avoid it.
The method works by starting a service that stays running that must be stopped before the systemd reboot.target, halt.target, etc., are allowed to be entered. This is when the stop command runs. This is the last possible moment to execute something on the system and the system is considered to be in a safe state. All other programs have safely shutdown (and files closed), by design. This is the safest possible method to enter EDM.
The basics of this method consist of:
- Writing an enter_edm.py script
- Writing a service file to call the script when the service is killed (just before shutdown)
- Enabling the service
- Verifying behavior
** EDIT: ** Sometimes the ‘remove_all_scheduled_events’ fails and the script exits erroneously, I have had better luck without it, but I still remove the events in a different script, but strictly speaking it is not necessary to make that function call. I have a ‘watch’ script that monitors inputs, signals temp to the system (so that fan automation works), and initiates a shutdown sequence when DC current is 0 and battery powered (high power use can draw battery power, or has for me in the past). This script may interfere with the shutdown command in my use case, but this change helps make my system work as expected.
1. Writing an enter_edm.py script
$ sudo nano /usr/local/sbin/enter_edm.py
from power_api import SixfabPower, Definition, Event
#api.remove_all_scheduled_events(200) # removed because if can fail
while True: api.set_edm_status(1, 1000)
2. Writing a service file to call the script when the service is killed (just before shutdown)
$ sudo nano /lib/systemd/system/shutdown_edm.service
Description=script to put UPS HAT in Easy Deployment Mode
Before=reboot.target halt.target poweroff.target unmount.target
ExecStop=/bin/sh -c ‘/usr/bin/python3 /usr/local/sbin/enter_edm.py’
WantedBy=default.target reboot.target halt.target poweroff.target
3. Enabling the service
$ sudo systemctl enable shutdown_edm.service
$ sudo systemctl start shutdown_edm.service
3a. Disabling the service
$ sudo systemctl disable shutdown_edm.service
(Don’t run the stop, it will immediately poweroff/reboot the system)
4. Verifying behavior
$ sudo systemctl status shutdown_edm.service
The command should show that the service is active.
When shutdown on DC power, the system will reboot. This is by design of the Easy Deployment Mode.
When shutdown not on DC power, the system will shutdown and all attached hardware will power down (including GPIO, USB, everything).
When power is reapplied to the UPS hat, the system will immediately boot by leaving EDM.
Hope this helps others. I don’t think anything needs to be made executable, at minimum, everything needs to be