5

I've been extending a weather station / webcam we have here at our model flying field. It has now an Arduino gathering the weather data and starting the Pi in a specific time interval (5 or 10 minutes). In normal cases, the Pi just makes a picture, gather the weather data and uploads the whole package to a web site.

The Pi's power supply is provided by 5v GPIO using a MOSFET on the 5v rail. The Arduino can detect as well if the Pi has shut itself down by using the gpio-poweroff overlay, which allows it for turning the 5v supply off after shutdown.

There is as well a shutdown trigger on another GPIO which allows the Pi to be forced down. A python script is watching this trigger, started from within the rc.local.

And last but not least, there is a set of flags that can be set either by serial console on Arduino or by sending a short message to the Pi's 3G modem to enable things like 'maintenance mode', which basically leaves the Pi on and starts a Wifi access point to which we can login. When the Pi shuts down, it automatically leaves this maintenance mode (all flags are written to tmpfs), and on next start triggerd by the Arduino, everything is back to normal.

All this works like charm. But in case we forget to shutdown the Pi, or if, for whatever reason, we are locked out and cannot turn it down, it gets shutdown after 30 minutes.

Now, what if something crashes on the Pi, or whatever reason, and the gpio-poweroff never triggers? I'd like to have a maximum up-time on Arduino that would basically switch off the Pi, now matter what. This is all very easy to code.

But now, how do I detect that the Pi has been just cut from the power supply, rather than normally shutdown? I could, of course, keep this information in the Arduino and try to communicate it to the Pi, which in turn would mail someone, or any other kind of notification (text message would be nice as well).

However, I think this turns rather complex and leaves many points of failure. I'd rather have a simple way on the Pi to detect that it's power supply has been cut without a correct shutdown. The Pi is running raspbian jessie, and the firmware is kept up to date with rpi-update.

I'd be thankful for any pointer in the right direction.

3
  • This might sound a bit silly but how about a UPS for the RPi? I have one, a UPiS "Basic" from Pimodules - it even has an RTC and can be configured to start-up and shutdown the RPi with a pair of (On-/Off-) Timers which you are currently doing from the Arduino. This means that you have more than enough power to keep the RPi going to signal the Arduino that the plug has been pulled from the Mains and (provided the link to the web-site is maintained), you can tell the World if something is going wrong before the RPi dies. Also see about setting up a "Watchdog"...
    – SlySven
    Commented Feb 5, 2016 at 16:17
  • This is not about power interruption. If the Pi gets switched off without proper shutdown, then it means that the arduino switched the MOSFET off (directly, or indirectly by being reset). The deal is: if that happens, then something must have gone wrong in software, and I have to check it. Normally, the Arduino will request a proper shutdown by setting a pin to HIGH. If the Pi does not shutdown, the arduino will switch the power off after 60s. And this is what I need to be notified of.
    – Raphael
    Commented Feb 5, 2016 at 17:32
  • Ah, my thinking was that stopping the power from failing without the RPi being shutdown. One thought - a "latching" relay that the RPi sets to one state during the shutdown and the Arduino sets the other way when it turns the RPi on...
    – SlySven
    Commented Feb 5, 2016 at 17:36

2 Answers 2

5

If you want the Pi to be able to tell you (via email notification or whatever) that it was not shut down properly the last time it was active, a simple solution is to arrange for a simple script that (a) runs at startup and creates a flag file and (b) runs at shutdown and deletes the flag file. At startup, you check if the flag file exists before you create it, and if you find it, send out your alert.

For example...

A systemd unit and a script could take care of this. Place the following in /etc/systemd/system/powercheck.service:

[Unit]
Description=Detect if system was shut down cleanly
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/powercheck start
ExecStop=/bin/powercheck stop

[Install]
WantedBy=multi-user.target

And /bin/powercheck is a script that looks like this:

#!/bin/sh

FLAG=/etc/poweroff-flag-file

if [ "$1" = "start" ]; then
  if [ -f "$FLAG" ]; then
    echo "Detected impropert shutdown" >&2
    (
    echo 'Detected improper shutdown'
    stat $FLAG | awk '/Modify/ {$1="Power On:"; print}'
    ) | mail -s 'Improper shutdown' [email protected]
  fi

  date >  "$FLAG"
elif [ "$1" = "stop" ]; then
  rm -f $FLAG
fi

This presumes that your Pi is properly configured to send email. An alternative would be to POST data to some sort of alerting web service.

With those in place, just:

systemctl enable powercheck

And you should be all set.

2
  • larsk, you're genius! That's exactly what I was looking for! Obviously, I was too stupid to think of something like this. Dead simple, but very efficient.
    – Raphael
    Commented Feb 5, 2016 at 15:15
  • What about checking for the results of the boot-up fsck - if the return value is... checks the manpage a bit value sum containing '1' or '4' at least then errors were found which is indicative of a failed shutdown...?
    – SlySven
    Commented Feb 5, 2016 at 17:42
1

The following should work nicely on most distros:

last -x reboot | tac | grep 'still running' | wc -l

Expected outputs

result equal 1  # system was shutdown correctly
result greater 1  # system was not shutdown correctly 

In other words, if the result is greater than one, the system was not shut down as expected.

Explanation:

  • First we list all the reboot events
  • We reverse the order using tac - not necessary, but makes this more readable when running the command without wc -l
  • We filter to those reboots that are "still running"
  • We count the lines

More details of this behavior can be found here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.