RPi PowerCheck: tenere d’occhio i blackout di corrente con Bash

| |

Hai un UPS? Molto bene, tieni “al riparo” i dispositivi più delicati che hai in casa, tra cui router, NAS e compagnia bella. Io che ho l’UPS distante però dal Raspberry Pi, voglio sapere – anche tramite suoi controlli – quando viene a mancare la corrente nell’abitazione, eventualità non così rara quando si parla del terzo mondo di Milano nel periodo estivo. Ho scritto qualche riga in Bash e voglio condividerla, magari può tornare utile a chi l’UPS neanche ce l’ha e vuole farsi un’idea di questo evento poco simpatico che potrebbe danneggiare la scheda SD del Raspberry (che spero tu tenga comunque sotto backup, altrimenti dai un’occhiata qui).

Bash: riorganizzazione rapida di immagini e video

rpi_PowerCheck.sh

Se ogni 2 minuti (o 5, o magari 10, scegli un po’ tu, ti spiego come modificare lo script dopo il blocco di codice) decidi di far girare lo script Bash (usando crontab), questo salverà l’ultima data e ora del controllo all’interno di un banale file di testo che tu potrai successivamente consultare. Lo sovrascriverà a ogni controllo, questa è una scelta voluta per evitare di creare file giganteschi a lungo andare. Avrei potuto anche pensare di fare un semplice touch per aggiornare la data e l’ora di ultima modifica ma poco importa, il senso cambia relativamente.

Qui di seguito ti mostro il codice partorito, invitandoti come sempre a proporre eventuali ritocchi per migliorarlo e/o correggere castronerie di cui evidentemente non conosco le conseguenze a lungo termine.

#!/bin/bash
# Electricity Power Check Script
# GSolone, 2022 - https://gioxx.org
#================================================================================
# Credits:
# https://raspberrypi-guide.github.io/programming/run-script-on-boot
# https://unix.stackexchange.com/a/616085
# https://www.cyberciti.biz/faq/unix-linux-bash-script-check-if-variable-is-empty/
# https://www.cyberciti.biz/tips/howto-linux-unix-write-to-syslog.html
# https://askubuntu.com/a/77739
#================================================================================
powercheck=/home/pi/PWR_lastcheck.txt
notificationaddress=admin@contoso.com
BASHDATE=`date +"%b %d, %Y"`
BASHTIME=`date +"%T"`
TICK="[\e[32m ✔ \e[0m]"
ERROR="[\e[31m ✖ \e[0m]"
COL_NC="\e[0m" # No Color
COL_LIGHT_GREEN="\e[1;32m"
COL_LIGHT_RED="\e[1;31m"
VERSION="0.3 (20220629-02)"
case "$1" in
help)
scriptname=$(basename "$0")
echo
echo -e " ██████████
████ ████
██ ▒▒▒▒▒▒ ██
██ ▒▒▒▒▒▒▒▒▒▒ ██
██ ▒▒▒▒▒▒▒▒▒▒ ██
██▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒██
██▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒██
██▒▒▒▒ ▒▒▒▒██
██▒▒ ████████ ▒▒▒▒██
██ ██████░░░░██████ ▒▒██
██ ██░░░░██░░░░██░░░░██ ██
████░░░░██░░░░██░░░░░░██ ██
██░░░░░░░░░░░░░░░░░░██ ██
██░░░░████████░░░░░░████
██░░░░░░░░░░░░░░████ ${COL_LIGHT_GREEN}Electricity Power Check Script ${VERSION}${COL_NC}
████████████████████ ${COL_LIGHT_RED}GSolone, 2022, https://gioxx.org${COL_NC}
████▓▓██░░░░██▓▓██░░░░██ (Toad Ascii Art made by textart.sh)
██░░██▓▓██░░░░██▓▓▓▓██░░░░██
██░░██▓▓██░░░░░░██▓▓▓▓██░░░░██
██░░██▓▓██████████▓▓▓▓▓▓██░░░░██
██░░██▓▓██ ██▓▓▓▓██░░░░██
██████ ██ ██████████
██ ██ ██
██▓▓▓▓▓▓████▓▓▓▓██████
██▓▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓██
████████████████████████"
echo
echo -e "${COL_LIGHT_GREEN}Electricity Power Check: Is there power in the house?${COL_NC}"
echo -e "This script save (via crontab) the latest date and time when power is available in the house."
echo -e "Checking RPi uptime, you can obtain an email notification and verify how many minutes (hours/days/etc) the power was not available (when uptime is not greater than XX mins)."
echo
echo -e "\033[1mHow to use\033[0m"
echo -e " Modify $scriptname and change 'powercheck' (absoute path where you want to save PWR_lastcheck.txt file) and 'notificationaddress' (email address to notify when Raspberry Pi reboots) vars. Save and exit."
echo -e " chmod +x $scriptname"
echo
echo -e "\033[1mSchedule $scriptname\033[0m"
echo -e " Manual Execution (not recommended): ${COL_LIGHT_GREEN}./$scriptname${COL_NC} (to execute and save last check file, $powercheck)"
echo -e " Automatic Execution (recommended): use crontab, ${COL_LIGHT_GREEN}0 */5 * * * /ABSOLUTE/PATH/WHERE/FIND/$scriptname${COL_NC}"
echo
;;
clean)
rm $powercheck
echo -e " ${TICK} \e[32m Log deleted \e[0m"
;;
*)
echo Power available on ${BASHDATE} at ${BASHTIME}. > $powercheck
upSeconds="$(cat /proc/uptime | grep -o '^[0-9]\+')"
upMins=$((${upSeconds} / 60))
if [ "${upMins}" -gt "5" ]
then
echo -e " ${TICK} \e[32m Up for ${upMins} minutes. \e[0m"
else
echo -e " ${ERROR} \e[31m Up 5 minutes or less, send notification ... \e[0m"
while [ "$(hostname -I)" = "" ]; do
echo -e " ${ERROR} \e[31m No network, wait 1s. \e[0m"
sleep 1
done
echo -e " ${TICK} \e[32m I have network, send notification now! \e[0m"
lastcheck=$(<"$powercheck")
if [ -z "$notificationaddress" ]
then
echo -e "Email address not specified, log to /var/log/messages"
logger "RPi Startup on ${BASHDATE} at ${BASHTIME}. Latest electricity power check on $lastcheck. Uptime: ${upMins}."
else
echo -e "RPi Startup on ${BASHDATE} at ${BASHTIME}\nLatest electricity power check on $lastcheck.\nUptime: ${upMins}." | mail -s "RPi3-Startup alert" $notificationaddress
fi
fi
echo -e " ${TICK} \e[32m Last check on ${BASHDATE} at ${BASHTIME} \e[0m"
exit 0
;;
esac

Cosa c’è da sapere

Lo script, sia se lanciato manualmente che eseguito via crontab, andrà a controllare da quanto tempo è attivo il tuo sistema. Se questo è stato da poco riavviato (tipico comportamento relativo a un riavvio voluto o a una mancanza di corrente), allora notificherà l’accaduto. Mi riferisco in particolare al controllo eseguito dalle righe 75-77 dello script, queste per la precisione:

upSeconds="$(cat /proc/uptime | grep -o '^[0-9]\+')"
upMins=$((${upSeconds} / 60))
if [ "${upMins}" -gt "5" ]

dove quel -gt "5" equivale ai minuti entro i quali considerare un sistema “da poco riavviato“. È logico che un’interrogazione di questo tipo potrebbe generare un falso positivo dovuto a un riavvio generato dall’utente e non dal blackout elettrico, ma tecnicamente dovresti esserne consapevole dato che – salvo Raspberry non gestiti da te direttamente – dovresti poter essere solo tu a riavviare il tuo RPi. Va da sé che questo intervallo di tempo deve in qualche maniera corrispondere all’esecuzione dello script, altrimenti il tutto perde di senso.
Se deciderai quindi di eseguire lo script a intervalli regolari inferiori ai 5 minuti non dovrai ritoccare alcunché. Se invece sceglierai di eseguirlo – per esempio – ogni 10 minuti, allora dovrai anche modificare quel -gt "5" in -gt "10". A voler essere precisini, sarebbe opportuno modificare anche il testo della riga 81 poiché riporta anch’essa il 5 (nel senso di 5 minuti):

echo -e " ${ERROR} \e[31m Up 5 minutes or less, send notification ... \e[0m"

Quindi al posto di 5 minutes or less, andrebbe indicato XX minutes or less dove XX dovrebbe corrispondere ai minuti da te stabiliti per il controllo.

Lo script inizialmente era diverso, l’ho volutamente modificato per tenere d’occhio l’uptime del sistema e per questo ringrazio questo thread del forum ufficiale di Raspberry Pi che mi ha fatto accendere la lampadina.

Ciò premesso, queste sono le uniche due variabili che dovresti andare a ritoccare:

  • powercheck: indica il percorso assoluto dove conservare il file di cui ti parlavo, quello in cui verrà salvata l’ultima combinazione data / ora relativa al controllo effettuato. Io ho scelto di salvare il file nella cartella del profilo di pi, tu cambia tranquillamente il percorso e il nome del file se lo reputi opportuno.
  • notificationaddress: se sul tuo Raspberry hai configurato correttamente le informazioni che permettono l’invio di email da sistema (cosa che nulla ha a che fare con questo script), allora qui puoi indicare l’indirizzo di posta elettronica da raggiungere nel caso in cui venga rilevata una mancanza di corrente. Se lasci vuota la variabile, lo script salverà le informazioni all’interno di /var/log/messages (e tu potrai consultarle da riga di comando).
    Non ti preoccupare per la questione connettività: se il Raspberry per qualsiasi motivo non dovesse ancora essere riuscito a ottenere un IP di rete LAN, lo script attenderà che lo abbia prima di provare a inviare l’email.

Cosa puoi programmare

L’esecuzione dello script, cos’altro vorresti mai programmare? Il consiglio è quello di usare crontab ovviamente. Non c’è nulla nello script che richieda diritti di root, ti basterà quindi lanciare un crontab -e e inserire questa riga in fondo (o ovunque tu voglia, a patto di non rompere le scatole a eventuali altre operazioni programmate):

*/5 * * * * /home/pi/rpi_PowerCheck.sh

Modifica quel 5 nella stessa maniera in cui hai eventualmente modificato il valore di cui ti ho parlato prima (-gt "5") e assicurati che lo script si trovi in quella posizione, altrimenti modifica il percorso per richiamarlo. Salva ed esci per applicare la modifica e attendere così che i controlli inizino a essere effettuati salvando data e ora nel file di testo dichiarato nella variabile powercheck.

Io ho terminato di riportare quanto credo sia necessario raccontarti per metterti in condizione di replicare il medesimo scenario con il tuo Raspberry Pi. In caso di dubbi inerenti questo articolo che stai leggendo già lo sai, l’area commenti è a tua totale disposizione. Sarà mia cura in futuro aggiornare lo script nel caso in cui io mi inventi dell’altro o decida di modificare qualcosa nel processo.

#StaySafe


Immagine di copertina Vishnu Mohanan on Unsplash

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

L'articolo potrebbe non essere aggiornato

Questo post è stato scritto più di 5 mesi fa, potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a lasciare un commento per chiedere ulteriori informazioni! :-)

Condividi l'articolo con i tuoi contatti:
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Commenti
Oldest
Newest Most Voted
Inline Feedbacks
View all comments