Dienstag, 19. März 2019

Precence und OpenWrt - der 3. Versuch

Am Wochenende habe ich meinen OpenWrt Router WRT1900ACS mit neuer Firmware versorgt und dabei fiel dann relativ schnell auf, da war doch noch was...
Die beiden Varianten um festzustellen, ob bestimmte Geräte im Wlan angemeldet sind, die ich im Juni bzw. August 2018 schon mal getestet habe, haben einen ganz entscheidenden Nachteil: Sie überleben das Firmware Update nicht!
Ich hatte die Variante aus August zwar als Provisorium ohne Probleme laufen, aber so richtig zufrieden war ich damit sowieso nicht.
Der ssh Zugang zum OpenWrt Router überlebt das Firmware Update!
Deswegen eine neue Version. Ich beschreibe der Vollständigkeit halber an dieser Stelle auch noch einmal in Kurzfassung die Einrichtung des passwortlosen ssh Zuganges von fhem zum OpenWrt Router. Die Langfassung gab es ja schon in 2017.

Vorbemerkung

Das Tool ssh-copy-id kann nicht mit den speziellen Pfaden von dropbear (ssh OpenWrt) umgehen, deshalb kommt mein "Einzeiler" aus dem Artikel zum Einsatz.
Ich weiß, dass man prinzipiell die ssh Keys auch vom aktiven User auf den User fhem kopieren kann. Bei sicherheitsrelevanten Themen bin ich lieber für "ordentliches" und vielleicht etwas aufwendigeres Vorgehen.

ssh Zugang mit Public Key einrichten

Bitte diesen Artikel zur Einrichtung verwenden und dort in der Codebox den Abschnitt Ziel openwrt verwenden!

FHEM

Die Einrichtung in FHEM besteht aus einem Script und einem Presence Device.

Script

Meine Script liegen jetzt alle auch auf GitHub, wer das aktuelle Script einfach laden will kann das wie hier gezeigt tun, fhem braucht selbst nur Lese Rechte. Im Script muss normal nichts konfiguriert werden.
Dieser Befehl in der FHEM Kommandozeile lädt das Script ohne Umwege ins FHEM Verzeichnis:
"wget -O GetMacPresence.sh https://raw.githubusercontent.com/heinz-otto/scripts/master/Bash/GetMacPresence.sh"
Ich habe keinen anderen Benutzer in OpenWrt angelegt, sollte man aber vielleicht tun.
Das Script liefert lediglich, wie vom Modul gefordert, 0 oder 1 zurück, MAC Adresse und Routername werden als Parameter übergeben.
MAC=$1
host=$2
user="root"
ssh $user@$host '
    if (
      for m in $(
                 for w in $(iwinfo |grep -oE "wlan\d-\d|wlan\d")
                 do
                   iwinfo $w assoclist | grep -o -E "([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}"
                 done
                )
      do
        [ "$m" = '"$MAC"' ] && exit 0
      done
      exit 1
    )
  then
    echo 1
  else
    echo 0
  fi
'

Presence Device

Das Beispiel zeigt die einfachste Verwendung, neben der zu suchenden MAC Adresse wird noch der Name des OpenWrt Routers angegeben.
define WL_Dev1 PRESENCE shellscript "bash GetMacPresence.sh 11:22:33:AA:BB:CC wrt1900"

Erfahrung

Ein Problem tritt relativ schnell zu Tage: Man kann offenbar dieses Script nicht mehrfach starten, dann führt irgendeine Komponente zum Abbruch.

Dienstag, 5. März 2019

Eine weitere FHEM Instanz auf gleicher Hardware

Ein kleines HowTo für eine zweite FHEM Instanz.

1. Variante: Codeshare

Es gibt bei dieser Variante keine separaten Pfade - alles läuft in einem Pfad!
Lediglich eine neue fhem.cfg wird verwendet. Ein Update wirkt sich auf alle Instanzen aus!
Nur 3 Zeilen für die FHEM Kommandozeile - Achtung! Einzeln ausführen! FHEM startet über die Raw Definition mehrere Prozesse, da wäre die neue cfg noch nicht da wenn der sed Befehl losläuft:
  • Die erste Zeile holt eine Standard fhem.cfg vom SVN und speichert sie als fhem2.cfg. Die Original fhem.cfg wird nicht überschrieben!
  • Die zweite Zeile modifiziert diese fhem2.cfg:
    • Port 8093 statt 8083
    • ändert Namen für Logfile und Statefile sowie eventTypes, damit läuft diese Instanz zunächst unabhängig.
    • initialUsbCheck wird deaktiviert 
  • Die dritte Zeile startet diese neue Instanz, sie ist unter http://<hostname>:8093 erreichbar.
"wget -qO fhem2.cfg https://svn.fhem.de/fhem/trunk/fhem/fhem.cfg"
"sed -i -e 's/\/fhem/\/fhem2/;;s/\/eventTypes/\/eventTypes2/;;s/8083/8093/;;$aattr initialUsbCheck disable 1' fhem2.cfg"
"perl /opt/fhem/fhem.pl /opt/fhem/fhem2.cfg"

Achtung: Obwohl die Konfiguration separat ist, verwendet sie den gleichen Pfad wie die erste Instanz. Update, gleiche Namen innerhalb von Definitionen (Logdateien usw.) wirken sich auf beide Instanzen aus!

Ein shutdown der zweiten Instanz beendet diese, ein shutdown der ersten Instanz beendet beide Instanzen!

Mit einem notify in der ersten Instanz, kann man die zweite Instanz automatisch nach dem Start der ersten Instanz starten:
define n_StartFhem2 notify global:INITIALIZED "perl /opt/fhem/fhem.pl /opt/fhem/fhem2.cfg"

Damit läuft auch ein restart ohne Probleme: beide Instanzen werden nacheinander neu gestartet.
Beide Instanzen verwenden unterschiedliche Prozessorthreads/CPUs.

2. Variante: Rettungsweste

Wenn FHEM nicht mehr startet muss man Fehler suchen. Dazu ist es eigentlich nicht schlecht, mal eben "schnell" zu prüfen: Läuft es generell "ohne alles", was sagt das Log?
Der Ausgangszustand ist hier: FHEM läuft nicht! Wir bewegen uns im Terminal!

Erstmal prüfen, ob FHEM wirklich nicht läuft.
ps -aux|grep fhem
Prinzipiell passiert mit diesen Zeilen, das Gleiche wie in Variante 1, außer:
  • Nur der Name für den Statefile wird geändert, damit der Inhalt des originalen Statefile erhalten bleibt. 
  • Der Logfilename bleibt erhalten, man startet zwar ein  FHEM mit leerer cfg, hat aber den originalen Logfile im Zugriff.
n=3
cd /opt/fhem
sudo wget -qO fhem$n.cfg https://svn.fhem.de/fhem/trunk/fhem/fhem.cfg
sudo sed -i "s/\/fhem.save/\/fhem$n.save/;\$aattr initialUsbCheck disable 1" fhem$n.cfg
# oder auch das Port ändern
# sudo sed -i -e "s/8083/8093/" fhem$n.cfg
sudo chown fhem: fhem$n.cfg 
sudo perl fhem.pl fhem$n.cfg

Damit sieht/kann man:
  • ob FHEM startet (keine Problem mit dem Betriebssystem),
  • wie gewohnt das Logfile lesen. 
  • restore machen
  • diese Instanz ganz normal mit shutdown beenden

3. Variante: Völlig separat

In dieser Variante wird folgendes eingerichtet:
  • neues Port, 
  • der existierende /opt/fhem Pfad wird ohne die aktuellen Daten in einen neuen Pfad /opt/fhemN kopiert, 
  • neuer zweiter FHEM Service, 
  • neue leere fhem.cfg wird verwendet.
Ein installiertes FHEM  mit Systemd ist Voraussetzung!

Das Script / die Befehle alle im sudo Kontext (sudo su) ausführen!
#!/bin/bash
# Nummer und Port vergeben
n=4
fPort=8103

# aktiven Pfad kopieren, aktuelle Daten ausschließen
rsync -av --exclude={'log/*','restoreDir/*','cache','backup'} /opt/fhem/ /opt/fhem$n/

# fhem Service kopieren, anpassen und anlegen
cp /etc/systemd/system/fhem.service /etc/systemd/system/fhem$n.service
sed -i -e "s/\/fhem/\/fhem$n/" /etc/systemd/system/fhem$n.service
systemctl daemon-reload
systemctl enable fhem$n

# Leere cfg holen und anpassen
wget -qO /opt/fhem$n/fhem.cfg https://svn.fhem.de/fhem/trunk/fhem/fhem.cfg
sed -i -e "s/8083/$fPort/;\$aattr initialUsbCheck disable 1" /opt/fhem$n/fhem.cfg

#Besitzer setzen
chown -R fhem: /opt/fhem$n/

# Service starten
systemctl start fhem$n

Achtung, das kopiert und modifiziert die Version von fhem.cfg und fhem.service vom Entwicklungsstand heute! Wenn sich in Zukunft etwas ändert, muss dieser Code angepasst werden!

Will man alles wieder entfernen:
Bitte Vorsicht!
# zur Sicherheit nochmal n setzen
n=4

# Entferne den Dienst
systemctl stop fhem$n
systemctl disable fhem$n
systemctl daemon-reload
systemctl reset-failed
echo 'Mit y oder Y bestätigen'
rm -i /etc/systemd/system/fhem$n.service

#Entferne den Pfad
echo 'Mit y oder Y bestätigen'
rm -I -R /opt/fhem$n