Weg zu High-Availability der Home-Automation

Weg zu High-Availability der Home-Automation

Am 15. Januar 2024 habe ich einen neuen Raspi 4 B inklusive dem empfohlenen offiziellen Netzteil erhalten und damit begonnen, die bisher von einem Linux-PC gesteuerten Automationen zu Hause auf diesen Raspi zu migrieren.
Spätestens nachdem ich in einem Forum gelesen habe, dass ein Benutzer während den Ferien erlebt hat, dass ein Netzteil seines Raspis ausgefallen ist und in der Folge seine Steuerungen zu Hause (Jalousien, Gartenbewässerung, etc.) komplett ausgefallen sind, beschloss ich, einen Weg zur Hochverfügbarkeit der Home-Automation zu beschreiten.
Hier wird dieser Weg beschrieben.

Hardware
Am 21. Februar 2021 erhielt ich die neue Hardware:
- Raspberry Pi 4 8G Model B
- Official Raspberry Pi 4 Power Adapter USB-C Schwarz
- SanDisk Max Endurance 32GB
Erstmals wollte ich einen Raspi mit 8GB RAM ausprobieren und sicherheitshalber bestellte ich das schwarze Netzteil (im Unterschied zum weissen Modell, welches im Januar 2024 gekauft wurde); vielleicht erkaufe ich mir damit eine gewisse Sicherheit, obwohl ich nicht weiss, ob das schwarze und weisse Netzteil bzgl. Hardware wirklich unterschiedlich sind.
Als SD-Karte entschied ich mich für eine 'SanDisk Max Endurance' in der Hoffnung, dass diese lange haltbar ist.

Installation des Raspberry Pi 4 B
Der neue Raspi wurde gleich eingerichtet wie derjenige vom Januar 2024.
Positioniert wurde der neue Raspi diesmal nicht im Untergeschoss, sondern im Obergeschoss, um eine örtliche Redundanz zu etablieren.

Zwei Rechner zu einem Hochverfügbarkeits-System verbinden
Die zwei Raspis haben die Namen raspi und raspi2. Anstatt nur via 'ping' zu schauen, ob beide Rechner aktiv sind, wird regelmässig je ein File auf den anderen Rechner kopiert. Falls dieser Vorgang nicht erfolgreich ist, setzt sich der entspechende Rechner automatisch als MASTER.
Als crontab wird auf beiden Rechnern folgendes eingetragen:

*/2 * * * * /home/USER/smarthome/HA/ha.sh >> /home/USER/smarthome/HA/ha.log 2>>/home/USER/smarthome/HA/ha.errlog

Das File 'ha.sh' sieht wie folgt aus:
Zur besseren Darstellung wurde vor dem Einfügen folgender Befehl benutzt:
cat ha.sh | > ha.text

#!/bin/bash # ha.sh 23Feb2024/uk # # High-Availability # cd /home/USER/smarthome/HA # # Es kam am 23. Feb. 2024 vor, dass das File /etc/resolv.conf "leer" war: # grep -q 192.168.0.1 /etc/resolv.conf if test $? -ne 0 ; then echo "`uname -n`: /etc/resolv.conf ist 'leer' - Neustart! `date +%d.%m.%Y_%H:%M`" >> neustart.log sudo shutdown -r 0 fi # source PRIMARY.MASTER #echo "PRIMARY_MASTER=$PRIMARY_MASTER" # source MASTER.file if test "$MASTER" = "no" ; then sleep 2 fi # othermachine="none" thismachine=`uname -n` statusothermachine="ok" # if test "$thismachine" = "raspi" ; then othermachine="raspi2" fi if test "$thismachine" = "raspi2" ; then othermachine="raspi" fi if test "$othermachine" = "none" ; then # write/append to standard error echo "Machine=$thismachine - weder raspi noch raspi2 --> exit! `date +%d.%m.%Y_%H:%M`" >&2 exit 1 fi # hellofile=hello_from_$thismachine touch $hellofile # otherhellofile=hello_from_$othermachine # foblack="<font size=5 color=black><b>" fowhite="<font size=5 color=white><b>" fontend="</font>" # statusthismachine="ok" # scp -p $hellofile $othermachine:smarthome/HA/ >/dev/null if test $? -ne 0 ; then echo "$thismachine meldet: $othermachine nicht erreichbar! `date +%d.%m.%Y_%H:%M`" statusothermachine="notok" else ## echo "$thismachine meldet: $othermachine erreichbar!" : fi rm -f result.txt find -name $otherhellofile -mmin +4 > result.txt if test ! -s result.txt ; then ## echo "$otherhellofile ist jünger als 4 Min." othermcol="green" othermfont=$fowhite : else echo "$otherhellofile ist älter als 4 Min. - `date +%d.%m.%Y_%H:%M`" statusothermachine="notok" othermcol="red" othermfont=$foblack fi # if test "$thismachine" = "$PRIMARY_MASTER" ; then echo "MASTER='yes'" > MASTER.file_new echo "SLAVE=$othermachine" >> MASTER.file_new thismcol="green" thismfont=$fowhite else if test "$statusothermachine" = "notok" ; then echo "MASTER='yes'" > MASTER.file echo "SLAVE=$othermachine" >> MASTER.file_new echo "$thismachine wird Master - `date +%d.%m.%Y_%H:%M`" thismcol="green" thismfont=$fowhite othermcol="red" othermfont=$foblack else echo "MASTER='no'" > MASTER.file_new echo "SLAVE=$thismachine" >> MASTER.file_new thismcol="green" thismfont=$fowhite othermcol="green" othermfont=$fowhite fi fi # mv MASTER.file_new MASTER.file # source MASTER.file if test "$MASTER" = "yes" ; then thismachinemaster="YES" othermachinemaster="no" else thismachinemaster="no" othermachinemaster="YES" fi echo "<p>" > ha_new.html echo "<font size=2 color=black><b>High-Availabilty-Status</b><br></font>" >> ha_new.html echo "<font size=2 color=black><b>`date +%d.%m.%Y_%H:%M`</b></font>" >> ha_new.html echo "<p>" >> ha_new.html ##echo "`date +%d.%m.%Y_%H:%M`<br>" >> ha_new.html ##echo "$thismachine MASTER=$MASTER <br>" >> ha_new.html ##echo "$othermachine $statusothermachine <br>" >> ha_new.html ##echo "$othermachine MASTER=no <br>" >> ha_new.html echo "<p>" >> ha_new.html echo "<table border=1 cellpadding=3 cellspacing=9>" >> ha_new.html echo "<tr>" >> ha_new.html echo "<td>$foblack Machine</td><td align=center bgcolor=$thismcol>$thismfont $thismachine</td><td align=center bgcolor=$othermcol>$othermfont $othermachine</td>" >> ha_new.html echo "</tr>" >> ha_new.html echo "<tr>" >> ha_new.html echo "<td>$foblack Master</td><td align=center>$foblack $thismachinemaster</td><td align=center>$foblack $othermachinemaster</td>" >> ha_new.html echo "</tr>" >> ha_new.html echo "<tr>" >> ha_new.html echo "<td>$foblack Erreichbar</td><td align=center bgcolor=$thismcol>$thismfont $statusthismachine</td><td align=center bgcolor=$othermcol>$othermfont $statusothermachine</td>" >> ha_new.html echo "</tr>" >> ha_new.html echo "</table>" >> ha_new.html echo "<p>" >> ha_new.html ##fi # mv ha_new.html ha.html #
Das HTML-File-Fragment 'ha_new.html' dient dazu, auf einer Webseite den Status der beiden Rechner darzustellen. Ist z.B. der Rechner 'raspi' nicht erreichbar/down, dann sieht dieses HTML-Fragment wie folgt aus:

Das File PRIMARY.MASTER hat folgenden Inhalt: PRIMARY_MASTER='raspi' und ist auf beiden Rechnern identisch. Es dient dazu, zu definieren, welcher der beiden Rechner der Master ist, falls beide Rechner online sind.
Das File MASTER.file wird durch das oben beschriebene Script ha.sh alle zwei Minuten neu erstellt und sieht auf dem Master so aus:


MASTER='yes'
SLAVE=raspi2
und auf dem Slave so:

MASTER='no'
SLAVE=raspi

Software auf den beiden Rechnern, die zum Hochverfügbarkeits-System gehören

Die Software auf beiden Rechnern sollte generell identisch gehalten werden. Auf beiden Rechnern wird ja alle zwei Minuten getestet, ob der andere ebenfalls funktioniert und erreichbar ist. Dieser Status ist jeweils im File (siehe oben) /home/USER/smarthome/HA/MASTER.file gespeichert (MASTER='yes' oder MASTER='no'). In allen Scripts auf beiden Rechnern lesen wir nun gleich zu Beginn diesen Status wie folgt aus:


source /home/USER/smarthome/HA/MASTER.file if test "$MASTER" = "no" ; then echo "Not MASTER - exit! `date +%d.%m.%Y_%H:%M`" exit fi
und können jeweils das via cron aufgerufene Script gleich beenden.

Dies wurde genauso implementiert für die Steuerung der Storen bzw. Rollläden und ebenso für die automatisierte Gartenbewässerung inklusive der Sicherheitsüberwachung der Bewässerung, welche das Wasserventil schliesst, sollte es zu einer Zeit, wo keine Bewässerung vorgesehen ist, noch geöffnet sein.

Wichtig ist allerdings. dass die beiden redundanten Rechner stets auf dem aktuellen Stand der Daten sind. Wo immer in einem Script daher (auf dem MASTER) neue Daten generiert werden, wird sichergestellt, dass diese auf den SLAVE kopiert werden:


scp -p -o ConnectTimeout=5 Daten.file $SLAVE:smarthome/Verzeichnis_auf_slave/
Damit ist sichergestellt, dass beide Maschinen zu jeder Zeit bezüglich der Daten auf dem gleichen Stand sind und im Falle eine 'Failovers', also des nahtlosen und automatischen Umschaltens auf das redundante System, die Arbeiten problemlos und quasi kontinuierlich mit aktuellen Daten weitergeführt werden können.

 

...wird fortgesetzt...

 


Last Update: 04Apr2024 - Created: 21Feb2024 / uk