If you're like me, you have uninterruptible power supplies (UPSs) protecting your valuable equipment. But what happens when your UPS runs out of battery power? Hopefully you're either around to shut everything down before that happens or your backup system manufacturers provided software to shut your PCs down. But what about your Raspberry Pi (RPi). A power loss might mess with your RPi's operating systems. In this project, I use Home Assistant (HA) on a Raspberry Pi, MySensors, and an Arduino power sensor to detect AC power loss and to initiate shutdown procedures for the RPi, PCs and potentially other vulnerable devices on your network.
The method is simple; an Arduino AC power sensor is connected to an UPS which detects the power loss by monitoring a 5VDC supply plugged into a outlet that is not backed up, and once detected initiates a process of coordinated activities between the Arduino and HA that instructs equipment on the network to shutdown, then shuts down down the RPi. The Arduino is left powered by the UPS. Should power be restored, the Arduino reboots the Raspberry with Hassio installed. Once the Raspberry is up and running, the Arduino sends messages to Home Assistant (HA) to apply power to the PC, causing it to boot. This completes a reboot of the system. The same process is easily expanded to include booting any number of PCs.
If we consider the system to be the Arduino, the Raspberry, the network, and any attached PCs, then the system has the following states:
- SystemOn - the system (all the equipment) is on. This is an idle state for the Arduino, as it has nothing to do. It's just waiting for a change in the powerState. In this case, for the power to be lost.
- SystemOff - the system (all the equipment with the possible exception of the Arduino) is off. This is again an idle state for the Arduino, as it has nothing to do but wait for power to be restored.
- powerRestored - power has returned after a power outage. This is an active transition state in which the Arduino initiates a reboot of the system, by first applying power to the Raspberry, and then once it's booted, communicating with HA to turn on Wemo switches that power the PCs. The BIOS of the PCs has to be set for boot on Power Up. Every PC is different and the user must investigate each on his own.
- powerLossed - power has been lost. This is another active transition state in which the Arduino initiates a shutdown of the PCs. This is accomplished by communicating with HA which uses an 'Add-on' called 'RPC shutdown' to initiate the shutdown of networked PCs using their network addresses. Once a sufficient amount of time has passed to allow all PCs to shut down, the Arduino instructs HA to turn off the Wemo switches that power the PCs. Then, the Arduino tells HA to shut Hassio down. Again, after a sufficient delay, the Arduino removes power from the RPi.
So what happens if the network goes down after the UPS runs out of power? When power is restored to the Arduino, it immediately turns on the relay that provides power to the RPi causing it to boot. It also delays for a sufficient amount of time to allow the RPi to boot and the Network to re-establish itself. With the RPi up and running HA, the Arduino commands HA to boot the PC by simply turning on the Wemo Smart Plug powering the PC.
System Configuration and AssemblyIn Figure 1 below is a schematic representation of the Power Monitoring System. A custom circuit board (Fritzing file attached) is designed to hold an Arduino Nano, a relay, an NRF24 radio, and a simple AC voltage rectifier circuit. The Nano monitors the output of the rectifier circuit to determine if home AC power is still active. The Arduino also controls a relay which switches power to the RPi on and off. To reboot the RPi, it is only necessary to turn it on. Communication with the RPi from the Arduino is accomplished through the MySensors mesh radio network. The RPi, which hosts Home Assistant must be attached to the same network as the PCs it intends to control. Each PCs network address is required to be provided to Home Assistant through it's Yaml configuration files.
Assembly of the system hardware is a simple matter of populating the Custom PCB and mounting it in the 3D printed enclosure (FreeCAD file provided). I used the attached Fritzing file and exported Gerber production files. These I sent to JLCPCB (PCB Prototype & PCB Fabrication Manufacturer - JLCPCB), a Chinese board manufacturer, who made the boards for a few dollars and charged about twenty dollars for shipping.
In order to shut down the PCs, I installed the add-on called RPC Shutdown. The documentation included with the installation is well written and easy to follow. You will need to determine the IP address of each PC you would like to shut down. This information is then included in a configuration file that is part of the RPC Installation and accessible and updateable there. Finally, you will need to include a automation that shuts down the PC when needed. Along with the code I've included is the automation I currently use.
Circuit DesignFigure 2 below shows a schematic diagram of the circuit used in this project. The main elements of the circuit are the Arduino, the NRF24 radio, and the relay. The Arduino communicates with the NRF24 radio to get and send information to the Home Automation system (here Home Assistant). The main purpose for this circuit is to control the relay, which in turn connects power to the RPi. The Arduino gets its power from the UPS, so even when the AC power is lost, the Arduino, and of course all the other backed up equipment stays alive. The RPi is responsible for shutting down any designated PCs through an HomeAssistant automation. Then, through another automation, the RPi shuts itself down. When that process has completed, the Arduino opens the relay so that power to the RPi is removed. The Arduino remains powered as long as the UPS can maintain it. When power returns the Arduino closes the relay, providing power to the RPi. Once the RPi is booted, it takes over the process of powering up all designated PCs.
This board is designed with some built in versatility. I find this useful because you typically have to purchase five PCBs with each order. Those leftover boards could be applied to other projects. In this spirit, I've also provided access to the terminals of the relay. Additionally, the Analog Outputs are brought out to a header as are five of the digital outputs.
The boards I had fabricated suffer because even the widest trace available does not seem capable of providing enough current to keep the RPi from complaining about low voltage. To counter this, I added 18 awg jumpers that connect the poles of the relay directly to the 2.1 mm power plugs. This seems to have solved the problem.
TestingIncluded in the attached code is a Yaml file called "Power Monitor Test Automation." This automation removes the portions that turn off the PC's Wemo switch and the portion that shuts down the RPi. With this code, you can test the coordination between the Arduino hardware/software and Home Assistant running on the RPi without the danger of crashing either. The automations send emails to your google account (which can be set up in Home Assistant as a notification - see Home Assistant On-line Documentation). So, with your portable device of choice, you can receive those messages real time.
I included a simple test program to check that the relay and analog input are working properly on the PCB.
To check the radio (MySensors) communication with Home Assistant, just load the Arduino software which has the #define MY_DEBUG active. Use the serial port to see that the radio does indeed communicate with the gateway.
In my system testing, I put the Wemo switch on an extension cord so that I could easily see when its on and when its off. I attached a 5 Volt supply to the same extension cord and plugged its 2.1 mm connector into the Power Monitor's 5 Volt input bulkhead connector. I then connected the Arduino Nano programing port to the PC I used for programming the Arduino. Please note that just plugging in the 2.1 mm connector will surprisingly power the Arduino even though it is only connected to an analog input. Opening up the serial port will reset the Arduino. The code has significant printouts to let you know where it stands. You will see that the software will check the power and decide that it is on. This will cause it to run through the boot up process. If you have Home Assistant open on your browser, you can observe the boot process. Keep in mind that the portion that involves booting the Raspberry doesn't seem to do anything. This is because in a real situation, with both the Raspberry and the PC(s) shut down, the first portion of the recovery process is booting the Raspberry. But, of course, if the Raspberry is not booted then Home Assistant is not available. Therefore, this portion of the process simply waits until the communication with Home Assistant is established. This can only happen when the Raspberry is actually booted. Also remember that the Wemo switch can not be turned on until Home Assistant is active.
Below is a picture of the system set up for testing. The circuit board is installed in its enclosure with the Arduino Nano mounted on an extension board so that the micro USB port is accessible. It is situated at a location remote from the RPi and the PC. The automations have been inhibited as described above. As can be seen, the power to the RPi and from the UPS is not connected. Thus, turning on and off the relay, does not effect the RPi, but the red LED near the relay can be observed to verify its operation. The RPi is operational and HASS is running, so the functioning of the system can be observed with your browser on the designated Lovelace screen. The PC is connected directly to power and running while the Wemo switch is connected to an extension cord only. It can be observed to go on an off when commanded to do so by HASS. The serial port is monitored on the Arduino IDE. If the Arduino is reset, it will transition through the power-up routine. Observing the action on the serial port, you will see MySensors communications as the system tests and determines that the RPi is already up and running. At that point, you will see the "PC transitioning" binary sensor go on. If you use the time settings in the attached version, the transition period takes 12 seconds which can be observed both on the serial port and on Lovelace. After that transition period, the serial port will indicate that the system is booted and Lovelace will show the "System Condition" as being "SystemOn." Pulling the 5V AC sensor will cause the system to enter the shutdown process. Power indications on Lovelace will show the power is off. A 12 second delay will count up on Lovelace, after which, the transition flags will show that the PC is transitioning power down. After 12 seconds, the transition flags will switch to indicate that the RPi is shutting down and the countup timer will count for 12 seconds at which point, the relay will open and the LED indicator will turn off. The shutdown process has completed.
Two other items to check are the power recovery during the shutdown delay. If the 5V AC sensor is plugged back in, the system should stop the shutdown process and revert to the "SystemOn" condition. A second type of test is allowing the system to enter into either a power up or power down process, then either pulling the 5V AC sensor, or replacing it. Should that happen, the system should continue the process it has already started until it is completed. It will then reverse course and execute the opposite process. So if it was powering up and you pull the plug, the system will complete the power up process, and then enter the shutdown process.
Getting the system going can be a scary process. You will fear the very thing you are trying to avoid with this circuit; a gentle shutdown of the RPi. Step one is to make sure that the four lines in the code have sufficient boot and shutdown times. The times I'm using are shown below:
- #define SHUTDOWN_DELAY 60 // delay time before shutdown begins
- #define RPI_SHUTDOWN_TIME 3 // time in minutes to allow Raspberry to shutdown before switching off power
- #define PC_BOOT_TIME 5 // time in minutes to allow the PC to boot. Actual boot time includes time to boot the RPi
- #define PC_SHUTDOWN_TIME 3 // time in minutes to allow PCs to shutdown before switching off power
You will also need to make sure that the lines of Automation.yaml code the shut down the RPi and the PCs are commented out. This will, of course, prevent an accidental shutdown of the RPi and PCs. Now, the only danger, and it's serious, is that you will accidently remove power from the RPi if the Arduino were to open the relay. I don't see how to avoid this potentiality but the danger can be minimized.
What I've found effective is to first connect the RPi jumper cable from the 2.1 mm power jack on the board to the already shutdown RPi. Then connect the 5 Volt power sense cable to the appropriate jack on the Power Monitor PCB. Make sure the 5 Volt power is available at the board. This is easy to do since the power will feed through the Arduino's analog input and light the Arduino LED. Finally, connect a 4 Amp power supply to the Power Jack on the Power Monitor PCB. This will first power the Arduino, which in short order will close the relay thus powering the RPi.
Do not disconnect the the 5 volt power sense yet. If you do, the countdown will start and because the automations are inhibited, the RPi will not get a shut down command. Instead, the Arduino will happily wait with the naïve belief that the RPi is shutting down. When the Arduino clocks through the RPI_SHUTDOWN_TIME it will pull the plug on the RPi, even though it hasn't shut down.
Now that the RPi is running, you can go to Home Assistant and remove the comments from the Automation.yaml file, rendering the system fully functional.
In Figure 4 below, the operating Power Monitor System is shown. On the top of the image, the 2.1 mm power connectors are seen. To monitor the AC power, a 5 VDC power supply is plugged into an outlet that is not backed up. When AC power is lost, the 5 VDC signal drops to zero indicating the power loss to the Arduino Nano. On the top right of the image, the UPS is plugged into a 2.1 mm jack. Once this supply is plugged in, the Arduino will be powered. The Arduino will immediately close the relay providing power to the center 2.1 mm jack which connects to the RPi. I am running a RPi 4, which requires more current than a RPi 3, does occasionally experience a low voltage thus triggering a warning. I've been ignoring these without apparent issue.
At his point, I conducted final testing. With everything operational, I pulled the 5 Volt power sense cable to imitate a loss of AC power. I observed the desired shut down process, even waiting the hour for the shutdown delay to expire. Everything worked as designed. Great!
System PerformanceHaving tested everything over and over again, I am confident the system will afford the protection it's designed to provide. But, as of yet, I haven't had a real power loss and so haven't seen the system's reaction.
Comments
Please log in or sign up to comment.