Posts mit dem Label Anfänger werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Anfänger werden angezeigt. Alle Posts anzeigen

Sonntag, 6. August 2023

nextcloud zu Hause - sicher mit nextcloudpi

Wie der Name sagt, wurde nextcloudpi ursprünglich für den Raspberry Pi entwickelt und ist eine Art Komplettlösung. Primär gibt es dafür ein Systemimage, ich habe das auf einem Pi3 ausprobiert und kann sagen: das wird schnell langsam. Vielleicht geht es auf einem Pi4, aber darunter (läuft ab Pi2) kann ich es nicht empfehlen.

Ich habe es auf einem Intel Celeron N5105 System mit 8 GB RAM installiert, da finde ich es ganz brauchbar. Man kann später sehr viel bei nextcloud dazu installieren - ich denke, da kann man jede beliebige Hardware ausreizen.

Mein Ziel ist eine eigene Cloud zu Hause, alle Bewohner können die Daten ihrer Smartphones, vorhandene Bildarchive usw. darauf speichern und von unterwegs will man natürlich mal ein paar Bilder zeigen oder auf Dokumente zugreifen.

Ich möchte die Setup Schritte hier notieren, da es viele Möglichkeiten zum "abbiegen" gibt.

Freitag, 19. August 2022

HowTo - FHEM Umzug von System A nach System B

Scenario: Umzug auf neues System

  • System Alt: altes Linux, alte Hardware ...
  • System Neu: neues Linux, neue/andere Hardware Plattform ...

Zwei verschiedenen Hardware Systeme sind etwas einfacher zu handhaben, es geht aber auch auf der gleichen Hardware (z.B. Raspberry Pi mit SD Card Wechsel oder USB-Bootstick). Ich habe alle Schritte mit einem Raspberry Pi(Raspberry OS Lite) und einer Virtuellen Maschine(debian 11 netinst) getestet. Dieses HowTo ist auch eine Ergänzung zu meinem vorjährigen Artikel.

Mit dem Raspberry Pi Imager kann man eine neue SD Card effektiv vorbereiten und das System grundlegen konfigurieren (Zahnradsymbol am rechten unteren Rand nachdem man das OS ausgewählt hat) 

Es gab von mir schon ein paar ähnliche Artikel, dieser hier soll ganz gezielt Schritt für Schritt zeigen was zu tun ist. Windows 10 hat ssh und scp eingebaut, andere Tools braucht man nicht. Wer nicht mit Windows CMD arbeiten will findet die Codezeilen für Schritt 1 am Ende auch für Linux und Powershell.

Man kann alle Schritte beliebig oft wiederholen / durchspielen und dabei lernen.

Achtung (03.2024): Das FHEM Installermodul wird leider nicht mehr gepflegt, es häufen sich die Meldungen, das mein hier gezeigtes Verfahren der Ermittlung der fehlenden Debianpakete nicht mehr funktioniert. Ich habe derzeit keine Problem Behebung!

Montag, 12. April 2021

Windows To Go

- auch zum mitnehmen 😂 -

Es gab mal eine spezielle Live Version für Windows mit gleicher Bezeichnung, diese Variation wurde aber wieder eingestellt.

mobiles Windows - auf einem Stick

Als Werkzeugkasten - es ist relativ unkompliziert und einfach zu erstellen: Wer sich nicht weiter mit Internas beschäftigen will, nimmt das Tool Rufus, das macht einen guten Job! Es kopiert quasi das Windows ISO Image auf einen USB Stick. Entweder hat man das schon oder es wird vom Tool herunterladen. Die Bedienung ist aus meiner Sicht eindeutig.

Montag, 4. November 2019

MQTT - ich will das testen

... und aufschreiben. Das ist alles ziemlich spannend.
Entstanden ist letztendlich ein kleiner Workshop als Trockentest - Es wird keine extra Hardware benötigt!

Testumgebung

Ein frisches (oder gut gebrauchtes) FHEM und dann
define mqtt2s MQTT2_SERVER 1883 global
attr mqtt2s room MQTT_IO
Ein Linux oder Windows mit mosquitto installiert (install mosquitto-clients oder Windows )
Dort Terminal oder CMD Fenster und folgende Zeile eingeben:
mosquitto_pub -h raspib2 -i COMPUTER -t CPU/raspib/temperature -m 22 
Was passiert? Es entsteht sofort ein Device in FHEM:
defmod MQTT2_COMPUTER MQTT2_DEVICE COMPUTER
attr MQTT2_COMPUTER IODev mqtt2s
attr MQTT2_COMPUTER readingList COMPUTER:CPU/raspib/temperature:.* temperature
attr MQTT2_COMPUTER room MQTT2_DEVICE

setstate MQTT2_COMPUTER 2019-10-21 12:57:00 temperature 22

Empfänger

Weitere Publish Befehle aktualisieren nur das Reading temperature. 

Hinweis 2023: Ich habe ein universelles Script geschrieben um Daten von einem Linux System zu einem MQTT Server zu senden.

Beispiel: Endlosschleife (Abbruch ctrl+c) die alle 30 sec die aktuelle CPU Temperatur schreibt:
while [ true ] ; do mosquitto_pub -h raspib2 -i COMPUTER -t CPU/$(hostname)/temperature -m $(($(</sys/class/thermal/thermal_zone0/temp)/1000)) ; sleep 30 ; done
Der wird sogar geloggt, autocreate hat gleich ein FileLog mit angelegt.
Diese Device bedient jetzt eine wesentliche Funktion: den MQTT Empfänger.

Hinweis: Die autocreate Funktion erzeugt ein Device mit der CID (COMPUTER).
Wird die while Schleife auf einem anderen Computer gestartet, ändert sich die Topic Liste (wegen CPU/$hostname). Dadurch wird die readingList ergänzt aber das Reading bleibt das Gleiche (temperature) d.h. alle Werte von unterschiedlichen Quellen kommen in das gleiche Reading! Weiter unten zeige ich wie man das manuell ändert.

Man wird in der Praxis nicht umhin kommen die automatisch erzeugten MQTT_Geräte manuell zu bearbeiten! (Stand November 2019)

Monitor

Ich kann die Nachrichten auch ganz andere Stelle sehen, z.B. in einem Terminal. Dort einfach als Subscriber für alle Topics registrieren:
mosquitto_sub -h raspib2 -v -t '#'
Damit wird jede Nachricht vom Terminal 1 an den MQTT Server auch in Terminal 2 empfangen. Im mqtt2s sieht man im reading nrclients die Verbindung. Das eigene Device wird dort nicht angezeigt.

Sender

Als nächstes will ich von dem Device etwas publishen (eigentlich ein unnützer Versuch)
attr MQTT2_COMPUTER setList off:noArg cmnd/raspib/POWER off\
on:noArg cmnd/raspib/POWER on
Damit bekomme ich im Device ein on und off "Button" und sehe in meinem Terminal 2 zwischen den Temperaturen die ankommende Nachricht. Die aber jetzt nichts bewirkt.
CPU/raspib/temperature 53
cmnd/raspib/POWER on
cmnd/raspib/POWER off
CPU/raspib/temperature 52

Gerät steuern

Versuch: Simulation und Steuerung eines externen mqtt Gerätes
Ich erzeuge in einer zweiten FHEM Instanz ein Gerät (MQTT2_DEVICE) und einen IO (MQTT2_CLIENT).
Über die readingList will ich die Nachricht POWER (von dem Publish Versuch eben) in das Reading state schreiben:
define mqtt2c MQTT2_CLIENT raspib2:1883
attr mqtt2c room MQTT_IO

define MQTT2_Test MQTT2_DEVICE Test
attr MQTT2_Test IODev mqtt2c
attr MQTT2_Test readingList cmnd/raspib/POWER:.* state
attr MQTT2_Test room MQTT2_DEVICE
Ergebnis: Ich kann jetzt sowohl von FHEM (MQTT2_COMPUTER) als auch von extern das Gerät MQTT2_Test schalten:
mosquitto_pub -h raspib2 -t cmnd/raspib/POWER -m off
Damit das Gerät sich selbst "steuern" kann und mqtt Nachrichten erzeugt erweitere ich es noch um die setList:
attr MQTT2_Test setList off:noArg cmnd/raspib/POWER off\
on:noArg cmnd/raspib/POWER on
Funktion
  • Das ursprünglich automatische Gerät "COMPUTER" kann das Gerät "Test" in der zweiten Instanz steuern.
  • Über eine separate Publish Nachricht kann das Gerät "Test" ebenfalls gesteuert werden 
  • Das Gerät COMPUTER reagiert selbst nicht auf die Nachrichten des Gerätes Test oder von "außen". 
Mit dem attr mqtt2s rePublish 1 oder mit einem zusätzlichen IO (MQTT2_CLIENT) funktioniert dies auch in der ersten FHEM Instanz.
Ich bin nicht sicher ob es einen gutem Grund(Schleifen?) gibt, die eigenen Publish-Nachrichten nicht per default an die eigenen Devices zu verteilen.

Erweiterung des Versuches:
Man kopiert die komplette Definition von "Test" inklusiver der Definition mqtt2c in die erste Instanz.
Ergebnis: Beide FHEM Instanz haben jetzt ein Gerät "Test" welches synchron schaltet.
Zusätzlich können beide Geräte von "außen" und über das Gerät "COMPUTER" gesteuert werden. Durch Manipulation der IOs mit disable 1/0 und beim mqtt2s mit rePublish 1/0 kann man das Verhalten und die Auswirkungen gut testen.

MQTT über Internet

Steve hat hier eine Übersicht über kostenfreie MQTT Broker erstellt.
Bei myqtthub.com gibt es einen "open Plan" der kostenfrei einen MQTT Broker bietet (Oktober 2020).
Bei cloudmqtt.com gab es mal die "cute cat" kostenfrei. 
Nachtrag Juli 2020:  Mein Account funktioniert weiter, obwohl das Angebot nicht mehr existiert:
  • den Zugang "normal", 
  • SSL/TLS, Websocket und 
  • API Zugriff! 
  • 5 User Connections und 10 kbit/s Datentransfer Volumen. 
Achtung: Die CID muss beim Zugriff auf cloudmqtt einmalig sein, eine zweite Verbindung mit gleicher CID beendet die Erste!
So bekommt die Testumgebung (2. Instanz) einen weiteren IO.
define mqtt2Cloud MQTT2_CLIENT xxxxxx.cloudmqtt.com:21234
attr mqtt2Cloud SSL 1
attr mqtt2Cloud room MQTT_IO
attr mqtt2Cloud username uuuuuuu
set mqtt2Cloud password pppppppppppp
Um die Verbindung zum cloudmqtt zu testen habe ich mosquitto_pub oder auch ein Android App MyMQTT ausprobiert. Die Android App kann leider keine SSL Verbindung.
Hinweis: Will man mit mosquitto eine SSL Verbindung machen, muss man die Option --insecure verwenden?! (leider weiß ich nicht warum)
mosquitto_sub -h xxxxxx.cloudmqtt.com -p 21234 -u uuuuuuu -P pppppppppppp -v -t '#' --capath /etc/ssl/certs --insecure
Um eine Reaktion im System zu erhalten, habe ich noch ein MQTT2_Test1 Device in der 2. Instanz erstellt:
define MQTT2_Test1 MQTT2_DEVICE Test1
attr MQTT2_Test1 IODev mqtt2Cloud
attr MQTT2_Test1 readingList mobil/POWER:.* state
attr MQTT2_Test1 room MQTT2_DEVICE
attr MQTT2_Test1 setList off:noArg mobil/POWER off\
on:noArg mobil/POWER on
Das reagiert jetzt auf den Topic mobil/POWER (analog zu dem vorhanden MQTT2_Test) Device und ist "mobil" steuerbar.

Nach kurzer Zeit ist mir etwas aufgefallen:
Erweitert man die readingList um den topic vom Gerät MQTT2_Test:
attr MQTT2_Test1 readingList mobil/POWER:.* state\
cmnd/raspib/POWER:.* Teststate
wird das Reading Teststate analog zum Reading state von Gerät MQTT2_Test aktualisiert.
  • Mehr noch: Ich kann den topic cmnd/raspib/POWER über den cloudmqtt Server publishen und das Gerät Test in der 2. Instanz schalten. Das attr IODev muss dazu nicht verändert werden: MQTT2_Test hat IODev mqttc und 
  • MQTT2_Test1 hat IODev mqttCloud! 
  • Das IODev hat ausgehend Bedeutung, eingehend verarbeiten die MQTT2_DEVICEs nur den Topic!

Brücke schlagen

Ich will den Versuch erweitern und Werte zwischen FHEM Instanzen übertragen, die gar nicht aus dem mqtt Umfeld kommen.
Dazu erzeuge ich in meiner zweiten Instanz ein paar "manuelle Temperaturfühler":
define fuehler1 dummy
attr fuehler1 readingList temperature humidity
attr fuehler1 room Fühler
attr fuehler1 setList temperature:25,25.5,26,26.5,27,27.5,28 humidity:50,55,60,65,70,75,80
attr fuehler1 userReadings state {my $temp=ReadingsVal($name,"temperature",99);;my $hum=ReadingsVal($name,"humidity",99);;sprintf "T: $temp H: $hum"}
Zur Übertragung nehme ich ein notify (die Idee ist von hier). Das notify macht folgendes:
  • es reagiert auf Events der Geräte fuehler1 oder fuehler2 usw. sowie deren Readings temperature und humidity
  • es verwendet set magic
  • es befreit den Readingnamen im Event vom ":" (wobei ich nicht sicher bin ob das wirklich sein muss). Die Idee stammt von hier.
define n_publish3 notify fuehler.:(temperature:|humidity:).* set mqtt2c publish -r home/states/$NAME/{((split(":","$EVTPART0"))[0])} $EVTPART1
attr n_publish3 room Fühler
In der ersten Instanz ensteht jetzt durch autocreate eine Art Sammeldevice MQTT2_mqtt2c.
Aus diesem erzeugt man sich die passenden Devices. Wichtig hier ist die Anpassung der Topic "Kette"
define fuehler1 MQTT2_DEVICE mqtt2c
attr fuehler1 readingList home/states/fuehler1/temperature:.* temperature\
home/states/fuehler1/humidity:.* humidity
attr fuehler1 room Fühler
attr fuehler1 userReadings state {my $temp=ReadingsVal($name,"temperature",99);;my $hum=ReadingsVal($name,"humidity",99);;sprintf "T: $temp H: $hum"}

Modifikation

Die attr readingList wird schnell unübersichtlich und schwierig zu warten. Mit nur zwei Modifikationen stellt man die Übertragung auf das JSON Format um.

  • Die Definition der mqtt Geräte wird einheitlicher und einfacher.
  • Man kann auch leicht mehrere Readings in einer Nachricht übertragen.

Erste Instanz
Die readingList reagiert so auf alle Nachrichten die mit dem Topic home/states/ beginnen und wo im Topic der eigene Gerätename vorkommt.
attr fuehler. readingList home/states/.* { if ($TOPIC=~m/$NAME/) { json2nameValue($EVENT) } }
Zweite Instanz
Das notify erzeugt ab sofort Nachrichten im JSON Format.
defmod n_publish3 notify fuehler.:(temperature:|humidity:).* set mqtt2c publish -r home/states/$NAME { "{((split(":","$EVTPART0"))[0])}": $EVTPART1 }

Alle Readings auslesen

Ich habe mal noch zwei Codezeilen gebaut, die entweder alle Readings eines Gerätes oder bestimmte Readings (Array) als JSON String ausgeben. Dieser Code ist zum Test in der Kommandozeile gedacht!
# Für Kommandozeile - alle Readings
{my $d="fuehler1";;my $hash = $defs{$d};;my $readings = $hash->{READINGS};;my $message="{ ";;foreach my $a ( keys %{$readings} ) {my $val=ReadingsVal($d,$a,"error");;$message .= toJSON($a)." : ".toJSON($val)." ," };;chop($message);;$message.="}"}

# Für Kommandozeile - nur zwei Readings
{my $d="fuehler1";;my @readings = ("temperature","humidity");;my $message="{ ";;foreach my $a ( @readings) {my $val=ReadingsVal($d,$a,"error");;$message .= toJSON($a)." : ".toJSON($val)." ," };;chop($message);;$message.="}"}
Will man im obigen set ... publish eine JSON formatierte Nachricht mit allen Readings des triggernden Gerätes absetzen, sieht das wie folgt aus (Dieser Code ist für die DEF!):
{(my $d="$NAME";;my $hash = $defs{$d};;my $readings = $hash->{READINGS};;my $message="{ ";;foreach my $a ( keys %{$readings} ) {$message .= toJSON($a)." : ".toJSON(ReadingsVal($d,$a,"error"))." ," };;chop($message);;$message.="}")}
Ich habe bewusst auf Formatierung verzichtet, in der DEF kann man den Code "lesbarer" formatieren.
AchtungDie FHEM Kommandozeile und set magic haben gegenüber dem normalen Perl Code immer ein paar Besonderheiten. -> ;; {(...)} "$NAME"

Tipp:

Nimmt man als MQTT Server einen Server in der Cloud, kann man damit die FHEM Instanzen ziemlich simpel übers Internet koppeln, ohne irgendeine Portfreigabe!

Allgemeine Brücke

Das Modul MQTT_GENERIC_BRIDGE scheint für die Kopplung der MQTT- und Nicht-MQTT Welt designed zu sein - eigentlich wollte ich dies als nächstes testen. Die Installation ist deutlich aufwendiger, deswegen sehe ich erstmal davon ab.

Ganz verrückt

Man kann aber auch mit einem kleinen  Shell Script mqtt Nachrichten auf System Ebene verarbeiten.

Notizen und Infos

Die mosquitto Windows Version installiert Server und Clients in einem Setup, man kann den Service aber "aushaken". Unter Linux installiert das Paket mosquitto den Server und mosquitto-clients nur die Client Tools.

Achtung: Alle MQTT Server laufen per default auf Port 1883! (Auch Mosquitto Server und MQTT2_SERVER) Es kann nur einen geben!

Gibt man bei mosquitto_pub keine CID an (Option -i) dann wird dies per default so gesetzt: "Defaults to mosquitto_pub_ appended with the process id." MQTT2_DEVICE ignoriert diese CID und legt dafür kein neues Device an!

Topic: Nach ersten Versuchen habe ich irgendwie gelesen, man soll bei den Topics keine führenden Slash's nehmen. Dadurch entsteht eine leere Ebene (bad practise).
Man kann jeden beliebigen Topic monitoren, das # gibt alle weiteren Level zurück. Das # allein liefert alle Topics, damit die Shell das nicht als Kommentar interpretiert muss man '#' schreiben!

Von steves-internet-guide habe ich mir auch ein paar Anregungen geholt.

Mittwoch, 25. September 2019

Windows Datensicherung mit Bordmitteln auf USB Stick

Achtung!
Ich möchte davor warnen, capture-image in einem normalen Windows zu starten!
Bei den Versuchen eine andere Systemplatte einfach mit Hilfe meines Notebooks in ein Wim File zu sichern, habe ich leider die Erfahrung gemacht, dass entweder der Vorgang in vielen Stunden ohne Fortschritt oder nach einem Abbruch die zu sichernde Partition zerstört ist!
Der Befehl "dism /capture-image ..." darf meiner Meinung nach nur unter Windows PE verwendet werden!

Grundlegende Idee

  • Seit der Version 1709 von Windows 10 kann man mit der Datenträgerverwaltung auch auf einem USB Stick mehr als eine Partition erzeugen.
  • Der Dateiversionverlauf sichert einfach, automatisch und benutzerfreundlich die Dateien auf ein externes Laufwerk.
  • Mit dism kann man ein Image des gesamten Systemlaufwerkes auf dem USB Stick (oder auf einem Netzlaufwerk) erzeugen, welches auch noch flexibel handhabbar ist.
  • Mit Windows PE oder dem Windows Setup kann man jederzeit ein Notfall System starten.

Dienstag, 9. Juli 2019

Neues Linux System - Nacharbeit

Generell ist es relativ einfach eine bestehende FHEM Installation auf ein neues Betriebssystem/System zu setzen:
  1. Backup FHEM
  2. Kopie der aktuellen Backupdatei -> Server | USB Stick | per scp lokal
  3. sudo halt
  4. neue SD Card mit aktuellem Image (ich behalte immer die alte SD erstmal in Reserve)
  5. setupBasic, setupFhem, testen
  6. Backupdatei verfügbar machen -> Server | USB Stick mounten | per scp - lokal -> nach /home/pi
  7. stop fhem
  8. restore des Backups
  9. start fhem

Sicherung / Backup

Bei mir ist beim obigen Plan mindestens die Anbindung an Dateiserver und die ssh Verbindung auf der Strecke geblieben. Schritt 1 und 8 muss man dafür noch etwas ausbauen.

Sicherung ssh Umgebung

Die notwendigen Dateien befinden sich in diesen Verzeichnissen:
  • /etc/ssh für den ssh Host / Server
  • /opt/fhem/.ssh für den User fhem
  • /home/pi/.ssh für den User pi. 
Ich werde zwei zusätzliche Dateien in den Backup Ordner von FHEM erstellen. Dies könnte man auch von FHEM von Zeit zu Zeit machen lassen. Neben der Datei für eine Historie mit Zeitstempel erzeuge ich noch eine ohne Zeitstempel. Damit muss man bei der Wiederherstellung nicht lang suchen.
Man kann dieses als Script auch unter FHEM ausführen, da aber Systemdateien gesichert werden, muss tar als sudo ausgeführt werden. Damit das funktioniert, muss die zuständige Datei um /bin/tar ergänzt werden.
datei=/opt/fhem/backup/ssh$(date +%Y%m%d_%H%M%S).tar.gz
sudo tar -czf $datei /etc/ssh /opt/fhem/.ssh /home/pi/.ssh
sudo cp $datei /opt/fhem/backup/ssh.tar.gz
Falls der User fhem gar kein ssh verwendet kommt ein Fehler, dann muss man die Befehle abwandeln. Da die Dateien nicht voluminös sind, kann man auf zip verzichten. Damit kann das tar Archiv leichter mit der Option -rf ergänzt werden.
sudo tar -cf $datei /etc/ssh /home/pi/.ssh
cp $datei /opt/fhem/backup/ssh.tar
Der folgende Zweizeiler wirft zwar Fehler, sichert aber die ssh Dateien für alle existierenden User.
datei=ssh$(date +%Y%m%d_%H%M%S).tar
sudo tar rf $datei /etc/ssh $(awk -F: '$3>998{print $6"/.ssh"}' /etc/passwd)
Will man einfach in FHEM die ssh Key für user fhem sichern kann man das auch dort machen: 
"datei=./backup/sshFhem$(date +%Y%m%d_%H%M%S).tar;; tar -cf $datei ./.ssh"
Und auch später wiederherstellen:
"datei=./backup/sshFhem*.tar;; tar -xf $datei ./.ssh"

Sicherung Dateiserver Umgebung

datei=/opt/fhem/backup/fsconf$(date +%Y%m%d_%H%M%S).tar.gz
sudo tar -czf $datei /etc/fstab /usr/.*credentials /etc/davfs2/secrets
cp $datei /opt/fhem/backup/fsconf.tar.gz
Hat man Scripte o.ä. zusätzlich in anderen Pfaden, kann man die natürlich einfach in dem tar Befehl ergänzen und gleich mit sichern oder eine weitere Datei nach gleichem Schema erzeugen.

Finale Sicherung des alten Systems

Damit man den finalen Status im FHEM System behält, muss man FHEM beenden und dann ein backup durchführen!
systemctl stop fhem
datei=/opt/fhem/backup/FHEM-$(date +%Y%m%d_%H%M%S).tar.gz
tar -czf $datei -C /opt/fhem --exclude ./backup ./
Wenn das Backup zu Ende ist, startet man beispielsweise das Script /opt/fhem/backupFhem.sh und kopiert alle aktuellen Dateien damit auf den Sicherungsserver.
Am Ende des Artikels habe ich noch den Hinweis auf Alternativen zum Server.

Wiederherstellung

Nachdem das neue System grundlegend installiert und getestet ist (Ergänzung Schritt 5. optional: setupDavfs) wird die Sicherung zurückgespielt.
Die Verbindung zu meinem Windows Server geht relativ simpel. Ohne Angabe des Usernamens wird der momentane User (root) verwendet. Ohne Angabe des Passwortes wird es abgefragt:
sudo su
mount -t cifs //ServerName/Freigabe /mnt
mount -t cifs -o username=UserName //ServerName/Freigabe /mnt
mount -t cifs -o username=UserName,password=Passwort //ServerName/Freigabe /mnt
Ist das Laufwerk verbunden, kann auch ohne lokale Kopie sofort mit der Wiederherstellung begonnen werden.
datei=/mnt/fhem/$(hostname)/backup/FHEM-$(date +%Y%m%d_%H%M%S).tar.gz
tar -xzf $datei -C /opt/fhem
Querverweis: Falls die Module im alten System nicht gut dokumentiert waren, hilft eventuell dieser Beitrag.

Wiederherstellung ssh

Bei meinen Systemen wurde immer nur der ecsda Key verwendet. Ich möchte nicht die neue ssh Server Gesamtkonfiguration zerstören (da ändert sich immer mal was, ich habe nicht untersucht was genau) sondern nur das wiederherstellen was gebraucht wird. Unter der Annahme: es gibt nur eine aktuelle Datei im Verzeichnis, wird damit der ecdsa Key in /etc/ssh wieder hergestellt:
datei=/mnt/fhem/$(hostname)/backup/ssh.tar.gz
tar -xzf $datei -C / --wildcards etc/ssh/ssh_host_ecdsa_*
Um die User .ssh Verzeichnisse wieder herzustellen, sollte dieser Befehl gut sein
tar -xzf $datei -C / home/pi/.ssh/ opt/fhem/.ssh/
Damit steht die ssh Umgebung wieder.

Wiederherstellung Verbindungen zum Dateiserver

Die für die Verbindung verantwortlichen Scripte sollten im /opt/fhem Verzeichnis liegen und sind damit schon Teile der Wiederherstellung. Die Datei /etc/fstab und die jeweiligen Credential Dateien liegen aber unter Umständen "verstreut" im System und sind jetzt entweder nicht vorhanden oder neu gemacht.
Zunächst die credential Datei(en) in /usr/
datei=/mnt/fhem/$(hostname)/backup/fsconf.tar.gz
tar -xzf $datei -C / --wildcards usr/.*credentials
Die davfs2/secrets will ich nur ergänzen, davfs muss schon installiert sein!
tar -xzf $datei etc/davfs2/secrets -O|grep magentacloud >> /etc/davfs2/secrets
Ich möchte gern die fstab nicht überbügeln sondern die neue Datei einfach um meine Einträge ergänzen. Existieren z.B. mehrere Mountpoints in /media/ - kann das in einer Zeile erledigt werden:
tar -xzf $datei etc/fstab -O|grep /media/ >> /etc/fstab
Jetzt müssen noch die Mountpoint erzeugt werden:
mkdir $(tar -xzf $datei etc/fstab -O|grep -o '/media/[a-Z,0-9]*'|tr '\n' ' ')

Jetzt kann man das Sicherungslaufwerk wieder trennen.
umount /mnt
Die Verbindung zu davfs2 erfordert auch noch die Gruppenmitgliedschaft in der Gruppe davfs2
usermod -aG davfs2 fhem
Die Gruppenmitgliedschaft greift erst nach erneutem Login! Also mindestens FHEM neu starten!

Alternativen zum Sicherungsserver

USB Stick
Man könnte einen USB Stick verwenden, der Raspberry Pi 3 verkraftet das Stecken im laufenden Betrieb. Bei allen anderen Typen und "zur Vorsicht" ist aber vom Stecken eines USB Sticks im laufenden Betrieb abzuraten. Zuerst schauen welches Device der Stick geworden ist und dann einfach temporär mounten:
lsblk
mount /dev/sda1 /mnt

SCP - lokale Kopie
Mit scp ist es recht simpel sich eine Kopie der Dateien lokal zum holen und diese später zurück zu spielen. Geht auch unter Windows 10 ab 1809 einfach so!
scp pi@hostname:dateiname .
scp dateiname pi@hostname:
Die Restore Befehle muss man natürlich etwas abwandeln, entweder die Variable $datei wird einfach auf die lokale Datei Homedir von pi gesetzt, oder im tar Befehl die Datei direkt angeben.

Installation nodejs, pm2 und pip

Die Installation von nodejs hatte ich ja hier schon erläutert.
Zusätzlich brauche ich "global" noch den Nodejs Prozessmanager pm2.
sudo su
curl -sL https://deb.nodesource.com/setup_10.x | bash -
apt-get install nodejs
npm install pm2 -g
Trotz der Sicherung des gesamten Ordners installiere ich Landroid neu. Wie so oft gibt es mittlerweile neue Versionen.

Python Pakete werden mit Hilfe von pip installiert. Beispiel: die fhem API
apt-get install python-pip
pip install fhem


ToDo
Andere Applikationen unterhalb von /opt sichern

codebox

Mittwoch, 30. Januar 2019

VHD - was geht, was nicht?

VHD erzeugen und verwenden

VHDs sind Container Dateien, die ein Festplattenimage enthalten. Ich setze sie der neben Virtualisierung gerne ein, um alte Datenpartitionen zu erhalten oder separate Festplatten zu simulieren. Um sie schnell mal zu erzeugen und auch für "normale" Benutzer bereitzustellen, gibt es verschiedenen Möglichkeiten.

In jedem aktuellen Windows System vorhanden:
Explorer: Man kann VHD Dateien mounten/dismounten - einfach per Doppelklick oder rechter Maustaste. Das funktioniert auch mit normalen Benutzerrechten.
Alle anderen Möglichkeiten brauchen Adminrechte.
diskpart/Datenträgerverwaltung: Mit beiden Tools kann man VHD Dateien erzeugen und mounten/dismounten.
Die Powershell kennt zwei Sets an Cmdlets.
(Dismount, Get, Mount)-DiskImage
Diese Cmdlets sind wahrscheinlich in jeder Windows Version vorhanden. Sie funktionieren mit VHD und ISO Dateien. Für die Verwendung von VHD Dateien braucht man Administrator Rechte.
*-VHD, *-VHDSet, *-VHDSnapshot
Ein neues, umfangreiches Set an Cmdlets welches erst mit der Hyper-V Rolle installiert wird. Mit denen kann man VHDs auch erstellen und umfangreich manipulieren. Doku.

Automatische Bereitstellung.

Zur Laufzeit kann man VHD Dateien leicht interaktiv einbinden und auswerfen, aber kann man VHD Dateien als HDD Ersatz auch beim Systemstart bereitstellen?
Das geht per Taskplaner und diskpart Script.

Praktisches Beispiel

Schritt für Schritt entsteht so eine dynamische VHD Datei mit 10 GB und einer Partition.
Achtung: Die Powershellversion funktioniert nur auf einem Hyper-V "aktiviertem" System:
$VDisk = "D:\VHD\TestPS.vhdx"
New-VHD -Path $VDisk -Dynamic -SizeBytes 10GB
$Disk = Mount-VHD -Path $VDisk -Passthru|Get-Disk
$Disk|Initialize-Disk 
$Disk|New-Partition -UseMaximumSize -AssignDriveLetter|Format-Volume -NewFileSystemLabel "Meine VHD"
Dismount-VHD -Path $VDisk
Schritt für Schritt in diskpart
create vdisk file=D:\VHD\TestDP.vhdx type=expandable maximum=10240
select vdisk file=D:\VHD\TestDP.vhdx 
attach vdisk
create partition primary
format FS=NTFS LABEL="MEINE VHD" QUICK
assign
detach vdisk
Alle diskpart Befehle kann man in eine Textdatei packen, und diese dann als Parameter übergeben.
diskpart /s Scriptdatei
Für die automatische Bereitstellung braucht man nun bloß noch ein paar Befehle. Für Powershell ist das Script ein Einzeiler
Mount-VHD -Path "D:\VHD\TestPS.vhdx"
# Oder so
Mount-DiskImage "D:\VHD\TestPS.vhdx"
Um es mit diskpart automatisch zu erledigen, braucht man wieder ein kurzes Script. Dieses startet man dann wie oben.
select vdisk file="D:\VHD\TestDP.vhdx"
attach vdisk
exit

Das Vorgehen bis hierher hat eventuell ein Problem: Die Zuweisung eines Laufwerkbuchstabens. Das passiert im Zweifelsfall einfach nicht. Wenn dem System die VHD nicht bekannt ist, wird sie eventuell ohne Laufwerksbuchstaben bereitgestellt. Bei dem Diskpart Script kann man das einbauen, der Mount-VHD Befehl kennt nur die Option -NoDriveLetter, bei Mount-DiskImage hat man gar keine Option.

Im Taskplaner (Aufgabenplanung) kann man eine Task für den Systemstart einrichten, damit steht die VHD nach dem Start für alle Benutzer zur Verfügung. So geht es:
Registerkarte Allgemein
Wichtig: Benutzer SYSTEM verwenden und den "Mit höchsten Privilegien" Haken setzen.
Registerkarte Trigger
"beim Start" auswählen.
Registerkarte Aktion
Hier in zwei getrennten Boxen den Programmnamen und die Argumente eintragen:
powershell
# entweder als Befehlsblock
-Command Mount-DiskImage "D:\VHD\TestPS.vhdx"
# alternativ als Scriptfile
-ExecutionPolicy Bypass -File "C:\Tools\Scripts\mountvhd.ps1"

diskpart
/s "C:\Tools\Scripts\mountvhd.txt"
Mit "Ausführen" sollte man die Aufgabe nach dem Erstellen direkt testen!

Um den Laufwerksbuchstaben der gemounteten VHD Datei zu ermitteln, muss man eine Kette von Cmdlets bemühen (Doku):
(Get-DiskImage -ImagePath $VDisk |Get-Disk|Get-Partition|Get-Volume).DriveLetter

Sonntag, 25. Februar 2018

Windows Server Freigabe auf dem Raspberry verbinden

Ich will hier kurz zeigen wie der Zugriff auf eine Windows (Samba) Freigabe unter Raspbian eingerichtet wird. Im Raspbian Image (Lite vom November 2018) sind alle Voraussetzungen vorhanden, man muss nichts weiter installieren. In anderen Systemen kann es sein, dass man das debian Paket cifs-utils nachinstallieren muss.  Openmediavault hat z.B. bei aktiviertem Samba nicht automatisch cifs-utils installiert.
Für den praktischen Gebrauch muss man lediglich 3 Dinge konfigurieren, für einen schnellen Test  kann man es mit einem Zweizeiler machen (siehe weiter unten):

Pfad

Unter Linux braucht man einen Ort wo man ein Laufwerk "hin" mounten kann, dabei wird
\\Servername\Sharename auf den lokalen Pfad /DirName/DirName gemappt.
Man erzeugt einen Pfad, am Besten mit einer "Wurzel", einem Verzeichnis unter dem alle Netzlaufwerke eingehängt werden:
mp='/mnt/Sicherung'
sudo mkdir -p ${mp}
Die Option -p erzeugt alle notwendigen Ordner falls sie noch nicht existieren.

Benutzerkonto

Da ein Windows Server nicht ohne weiteres einen Zugriff ohne Login ermöglicht und wir username und password nicht immer eintippen wollen, werden die Informationen entsprechend abgelegt.
Dabei gibt es drei Möglichkeiten. Ja nach Vorliebe verwendet man einen Editor (nano) oder direkte Shellbefehle
1. persönliche Datei (notwendiger Inhalt siehe nächster Codeblock):
fcred='.smbcredentials'
nano $fcred
chmod 600 $fcred
Die Datei ist damit nur vom Eigentümer lesbar!

2. allgemeine Datei:
Wenn keine Domain verwendet wird, kann der Eintrag domain entfallen oder freibleiben.
fcred='.smbcredentials'
export datei="/usr/${fcred}" 
sudo bash -c "cat >${datei}" <<'EOF'
username=UserName
password=Userpassword
domain=
EOF
Man braucht pro Konto eine credentials Datei. Diese Datei muss von allen Usern lesbar sein, die mounten wollen. Die gerade angelegte Datei ist aber auch von "Jedem" lesbar, will man das eingrenzen, kann man das so machen:
sudo -s <<EOI
  addgroup cifs
  usermod -aG cifs fhem
  usermod -aG cifs pi
  chown root:cifs ${datei}
  chmod 640 ${datei}
EOI
Hinweis: Die Änderung der Gruppenmitgliedschaft wirkt erst nach Neuanmeldung!

3. anstatt extra Datei (credentials=Datei) schreibt man die Kontodaten direkt in die fstab Zeile, dort ohne Zeilentrennung!
username=ano,password=nym

fstab

Nun fehlt noch der mount Eintrag in der fstab. In meinem Beispiel wird nicht automatisch gemountet, alle User dürfen mounten und das Laufwerk ist beschreibbar.
sudo bash -c "echo //ServerName/daten ${mp} cifs noauto,users,credentials=/usr/.smbcredentials 0 0 >> /etc/fstab"

Verwendung

Jetzt können wir das Laufwerk einbinden, den erfolgreichen mount anzeigen und den Inhalt anzeigen. Das funktioniert ohne sudo, der Benutzer braucht Leserechte auf die credentials Datei.
mount ${mp}
df
ls -l ${mp}
umount ${mp}

Hinweis

Das Windows Laufwerk wird auf diese Art nicht automatisch beim Start angebunden. Das Netzwerk ist zu diesem Zeitpunkt noch nicht verfügbar und der automount über die fstab würde nicht funktionieren. Ist für mich kein Nachteil, weil es jederzeit in einem Script per mount Befehl angebunden werden kann.

Nachtrag

Man kann auch jederzeit  mit einem simplen "Zweizeiler" ein Windows Laufwerk als sudo mounten, password= kann man weglassen, dann wird es abgefragt.

sudo mkdir -p /mnt/daten
sudo mount -t cifs -o username=UserName,password=Passwort //ServerName/Freigabe /mnt/daten
# Bei smb1 Servern und ab debian stretch
sudo mount -t cifs -o username='UserName',password='Passwort',vers=1.0 //ServerName/Freigabe /mnt/daten

Bei Problemen kann man sich die verwendeten Dateisysteme bzw. die Unterstützung des Kernels  anzeigen lassen.
cat /proc/filesystems
ls /lib/modules/$(uname -r)/kernel/fs

Zum nachlesen: Ubuntu Wiki

SMB Protokoll

smb Version 1 wird mittlerweile als extrem unsicher eingestuft. Deswegen wird es aus modernen Systemen "entfernt".
Allerdings ist es in vielen Geräten nach wie Standard und eine Unterstützung von smb 2 oder 3 nicht implementiert (Fritzbox NAS, Sonos ...)
Windows hat ab Version 1709 das Protokoll entfernt, man muss es bei Bedarf mit "Windows Apps und Features" nachinstallieren (Neustart erforderlich)
debian stretch hat es offenbar als default aus der Aushandlung herausgenommen, mann muss es mit der cifs Option "vers=1.0" beim mount Befehl explizit hinzufügen, wenn der Server nur smb1 unterstützt.

Donnerstag, 8. Februar 2018

In FHEM externe Programme aufrufen

Es gibt viele Möglichkeiten ein externes Programm aufzurufen. Ich habe Einiges ausprobiert und hier sind meine Erkenntnisse. Es kann sein, dass sich Dinge ändern oder ich etwas nicht richtig verstanden habe. Meine Ausführungen sind mit Sicherheit nicht vollständig!
Dieser Beitrag endet mit konkreten Beispielen, die kann man exakt so übernehmen. Dabei sind die Anführungszeichen in den Codefenstern richtig und wichtig!
Empfehlung: Komplizierte und lange Codezeilen immer in ein Script oder in eine Perl Sub schreiben! Mit Sonderzeichen, doppelten und einfachen Anführungszeichen kommt man schnell in sehr unübersichtliche, beinahe unlösbare Situationen. Immer die mögliche Blockade von FHEM im Hinterkopf haben!

Aufruf

Es gibt drei FHEM Kommandotypen, sie unterscheiden sich in der Verwendung der "Klammer"
  • FHEM Befehl - keine Klammer
  • "Shell Befehl" - doppelte Anführungszeichen (blockiert FHEM nicht)
  • {Perl Befehl} - geschweifte Klammer (kann FHEM blockieren)
Für externe Programmaufrufe eignen sich die beiden letzeren.
Perl kennt in sich wieder drei Funktionsaufrufe für externe (nicht Perl) Programme.
  • system() - liefert in FHEM immer "-1" zurück, Ausgaben landen im Logfile
  • qx() - liefert die Ausgabe zurück, bei Aufruf in der FHEM Oberfläche landet diese im Browserfenster
  • exec() - in FHEM nicht sinnvoll! Beendet FHEM und das aufgerufene Programm wird ausgeführt.

Kurze Fingerübung

Der Code ist für die FHEM Kommandozeile!
"echo test"
Liefert nichts im Browserfenster, schreibt test ins Logfile.
Innerhalb von Perlcode kann man das auch so verwenden:
{fhem("\"echo test\"")}
Perl system() liefert -1 im Browserfenster und schreibt test ins Logfile.
{system("echo test")}
Variante von system() mit anderer Schreibweise: {system("programm","Arg1","Arg2")} und man bekommt das gleiche Ergebnis.
{system("echo","test")}
Perl qx() liefert test im Browserfenster und schreibt nichts ins Logfile.
{qx(echo test)}
Tipp: Diese Version verwende ich gern, um in der FHEM Oberfläche mal schnell etwas im System abzufragen. Man muss dazu nicht immer ins Terminal wechseln.

Achtung: Die Pipeline (> |) der Standardausgabe funktioniert nur bei {system("echo system > test.txt")} und {qx(echo qx > test.txt)}, bei "echo kommando > test.txt" versagt sie aber!

Zwischenspiel

Wie bekomme ich Text in eine Datei? Am Besten mit der Perlfunktion FileWrite
{FileWrite("test.txt","Inhalt")}
Das Ergebnis anschauen:
{qx(cat test.txt)}

Beispiel mit Wertübergabe von FHEM

Dieses mehrzeilige Beispiel ist für die Raw Definition!
Mit dem Code Block erzeugt man:
  • ein Shellprogramm (echo $(($1*$2))) welches beide Übergabewerte multipliziert.
  • ein Dummy mit dem Reading Wert,
  • ein notify welches den Wert und state an das Shell Programm übergibt und die Rückgabe wieder den Wert schreibt.
{FileWrite("ext_Script.sh","echo \$((\$1*\$2))")}

define ext_dummy dummy
attr ext_dummy readingList Wert
attr ext_dummy room extern
attr ext_dummy setList 0 1 2 3 4 5 6 7 8 9
setreading ext_dummy Wert 1

define ext_notify notify ext_dummy:[0-9] {\
 my $a = ReadingsVal($NAME,"Wert","2");;\
 my $b = qx(bash ext_Script.sh $EVENT $a);;\
 fhem("set $NAME Wert $b")\
}
attr ext_notify room extern
Diese Beispiel ist sicher etwas konstruiert, es zeigt aber verschiedenen Ebenen (FHEM, Perl, Shell) und auch die Übergabe von Werten über Variablen. Dabei gibt es einiges zu beachten:
Sonderzeichen in Textketten werden innerhalb einfacher und doppelter Anführungszeichen je nach Ebene unterschiedlich behandelt! Bei doppelten Anführungszeichen gilt:
  • Text der mit $ oder @ beginnt wird als Perl Variable/Array aufgelöst/ersetzt. Man kann/muss die Auflösung mit dem vorangestellten \ verhindern/schützen: "\$a , name\@domain.de". 
  • Ist das Anführungszeichen selbst nur Text: \".
  • Den \ muss man selbst schützen: \\.
  • Mit \ werden auch Steuerzeichen eingeleitet. z.B. \n ist ein Zeilenumbruch.
Immer dran denken: Den Befehlstrenner ; müssen wir in der FHEM Eingabezeile auch verdoppeln/schützen!

Beispiele zur Verwendung von Variablen

Zwei Perlzeilen und zwei Ebenen. Die Ausgabe ist gleich, die Variablen unterschiedlich.
  1. $a ist eine Perl Variable und der Inhalt wird von Perl zur Shell übergeben.
  2. $a ist eine Shell Variable und wird erst in der Shell erzeugt. Es wird nichts übergeben.
{my $a = "test";;qx "echo $a"}
{qx 'a=test;;echo $a'}
Der Syntax von qx ist sehr variabel, alle Zeilen bewirken das Gleiche: den letzten Fehlercode der Shell ausgeben
{qx "echo \$?"}
{qx 'echo $?'}
{qx /echo \$?/}
{qx (echo \$?)}
{`echo \$?`}
Mit einer Ausnahme könnte auch eine Perl Variablen übergeben werden (anstatt \$? $a).
Achtung: Die Verwendung von qx("") führt zu einer Fehlermeldung, da ist offenbar ein String Terminator zu viel.

Damit es nicht zu leicht wird, kann man die String Terminatoren natürlich auch schachteln. Für die Auflösung von Perl Variablen ist dabei die äußere Klammer bestimmend!
Das erste Beispiel gibt Hallo Welt aus, das zweite nur Hallo. Die Variable $a wird im zweiten Fall nicht aufgelöst, sondern als Shell Variable interpretiert.
{my $a = "Welt";;qx "echo 'Hallo $a'"}
{my $a = "Welt";;qx 'a=FHEM;;echo "Hallo $a"'}
Ausnahmen? Verwirrung?
Im folgenden Beispiel muss der Name der Variable im Shellscript auch geschützt werden.
Im Zweifelsfall hilft nur probieren!
{system('echo "wget --quiet - \"http://192.168.178.65/esp8266?max=Aussentemperatur+\$1+C\"" > ext_Script2.sh')}

Empfehlung: Befehle kapseln

Die Verwendung von Trennzeichen im String und die bisher genannten Interpretationen von Variablen Namen in den Umgebungen führt mich zu den unbedingten Empfehlung Befehle zu kapseln! Entweder in Stringvariablen in Perl oder in Scriptdateien für andere Sprachen. Es spart jede Menge Zeit und Nerven!

Verkettung / concatenation

Perl kennt noch die String Verkettung mit Punkten.
Im ersten Fall ist die Ausgabe identisch zur Version oben, im zweiten Fall wird der Inhalt der Variablen noch in Anführungszeichen ausgegeben:
{my $a = "test";;qx "echo ".$a}
{my $a = "test";;qx "echo ".'"'.$a.'"'}
Welche Methode man verwendet ist häufig Geschmacksache, manchmal aber auch vom Inhalt der Strings und dem gewünschten Ergebnis abhängig und damit das Mittel der Wahl.

Achtung blockierend

Die Ausführung von externen Programmen mit Perl Aufrufen wird FHEM für die Laufzeit dieses Programmes unterbrechen/anhalten. Das kann unvorhersehbare Folgen haben.
Der kurzer Perl Test erzeugt für 5 sec "Warten" und dann eine Ausschrift.
{sleep 5;; return "Das war eine Pause"}
{qx "echo Das war;;sleep 5;;echo eine Pause"}
Der zweite Test führt auf Shell Ebene ein sleep aus, beide echo Befehle werden aber erst am Ende über qx an den Browser zurück gegeben.
Für einen weiteren Test erzeugen wir uns wieder ein Shell Script.
{FileWrite("ext_Pause.sh","sleep \$1\necho \$1 sec Pause")}
Dies erwartet eine Zahl und macht dann eine entsprechende Pause. Mit einem qx() Aufruf können wir das Script testen.
{qx "echo Das war;;bash ext_Pause.sh 4"}
Nach meinen Informationen, lässt sich das Verhalten mit qx() nicht ändern. Die Befehle werden immer seriell ausgeführt, Perl wartet auf die Rückgabe!
Der system() Aufruf hat andere Möglichkeiten. Bei ihm kann man mit dem & Zeichen am Ende (für die Shell typisch) die Ausführung im Hintergrund starten. Die Ausgabe im Script landet damit nach der Pause im Logfile von FHEM.
{system ("bash ext_Pause.sh 5 &")}

Aufräumen

Um die hier beim Testen erzeugten Geräte und Dateien wieder zu entfernen, kann man die beiden Zeilen einzeln in der Kommandozeile oder zusammen in der Raw Definition ausführen.
delete ext_.*
{system ("rm ext_*.sh >/dev/null")}

Ganz zum Schluss

Mal noch als "Merker" der Tipp aus dem Forum. Den baue ich bei Gelegenheit mal noch aus.
Code Block

Donnerstag, 1. Februar 2018

Setup FHEM

Es gibt einen aktuellen Artikel. Detail werden aber weitestgehend hier erklärt.

FHEM installieren ist eigentlich ziemlich einfach. Bevor meiner folgenden Anleitung gefolgt wird, sollte man sich unbedingt hier über den aktuellen Stand informieren. Mit minimalem Aufwand kann man das Setup von hier durchführen.
Alle meine Setup Schritte erfordern erhöhte Rechte. Also bitte alles in einer "sudo su" Session ausführen!
Und so setze ich diese Aufgabe praktisch in einem Script um:
# von debian.fhem.de installieren - siehe aktuelle Anleitung dort https://debian.fhem.de/
wget -qO - http://debian.fhem.de/archive.key | apt-key add -
echo "deb http://debian.fhem.de/nightly/ /" >> /etc/apt/sources.list
apt-get update
apt-get install fhem

Den zusätzlichen Eintrag in der sources.list entfernt das Setup Programm von FHEM. Alle benötigten und sinnvollen debian Pakete werden automatisch mit installiert. Ist ein systemd System vorhanden wird auch der Dienst für FHEM entsprechend installiert.

Damit ist man grundlegend fertig! Aber ein paar Dinge fehlen noch!

Das aus meiner Sicht wichtigste aktuelle Feintuning des frischen FHEM ist die Deaktivierung der USB Stick Erkennung. Dieser kleine direkte Patch auf diese Art ist nur unmittelbar nach der Installation zulässig! Später muss man diese Attribute bitte über die FHEM Oberfläche setzen.
# Den USB Check besser abschalten
/opt/fhem/fhem.pl 7072 "attr initialUsbCheck disable 1"
/opt/fhem/fhem.pl 7072 "save"

Weitere Attribute die man irgendwie braucht, kann man einfach über die Raw definition setzen. Die findet man in jeder Detail Ansicht von Definitionen ganz unten in der Mitte als Link.
attr global backup_before_update 1
attr global commandref modular
attr global title FHEM-Name
attr global sendStatistics onUpdate
attr global latitude 51.xxxxxxxxxxxxx
attr global longitude 12.xxxxxxxxxxxxx
attr global language de
attr WEB JavaScripts codemirror/fhem_codemirror.js
attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true }
attr WEB plotfork 1
attr WEB longpoll websocket

Fast fertig - allowed

ToDo

Speziell - Mplayer Ersatz

Ich arbeite viel mit Ansagen unter anderem mit Text2Speech.
Nachtrag: Mittlerweile ist der Aufruf für play direkt mit Parametern im MplayerCall eingebaut. Das Script ist also überflüssig.
Aktuell verwende ich dieses Script um mplayer zu ersetzen. In der Quelle gibt es auch noch eine Variante mit setzen des AUDIODEV.
#!/bin/sh
# die Kommentarezeichen vor echo  fuer den Test entfernen
# echo Parameteranzahl $# > /tmp/mplay.txt

# falls volume nicht vorhanden = 1
volume=1
# Alsa Device, Volume und Dateinamen ermitteln
while [ $# -gt 0 ]
do
# echo $1 >> /tmp/mplay.txt
 if [ $1 = -ao ]
 then
  shift
#   echo $1 >> /tmp/mplay.txt
  device=$(echo $1|cut -d= -f2)
#   echo $device >> /tmp/mplay.txt
 elif [ $1 = -volume ]
 then
  shift
#  echo $1 >> /tmp/mplay.txt
   if [ $1 -lt 100 ]
   then
    volume=0.$(($1))
   fi
 elif [ -e $1 ]
 then
  file=$1
 fi
 shift
done
#echo $volume $file >> /tmp/mplay.txt
play -q -v $volume $file
exit 0

Dieses Script muss für FHEM ausführbar sein. Wenn man es im aktuellen Homdedir liegen hat (User pi) dann kann man es wie folgt als User fhem an Ort und Stelle kopieren. Automatisch mit den richtigen Rechten und Besitz.
sudo -u fhem cp mplayer.sh /opt/fhem/
chmod +x /opt/fhem/mplayer.sh
Zur Vorbereitung sind zwei Pakete erforderlich.
sudo apt-get install libdigest-sha-perl mp3wrap
In Text2Speech kann man einfach den Aufruf durch dieses Script ersetzen. Minimal kann man Text2Speech so definieren:
define MyTTS Text2Speech default
attr MyTTS TTS_MplayerCall /opt/fhem/mplayer.sh

Weitere Software Pakete installieren

Viele der Module in FHEM erfordern zusätzliche Software auf System Ebene.
Aus meiner Liste sind bisher folgende debian Pakete noch nicht installiert
sudo apt-get install avrdude libcrypt-cbc-perl libcrypt-ecb-perl libcrypt-rijndael-perl libdigest-md5-perl libimage-info-perl liblwp-useragent-determined-perl libmime-base64-perl libnet-telnet-perl libnet-upnp-perl libsoap-lite-perl libxml-parser-lite-perl libxml-parser-perl sendemail
Diese Pakete müssen mit cpan installiert werden, es gibt kein debian Paket.
sudo cpan install Crypt::Rijndael_PP

Das folgende Script ermittelt ob die Pakete schon installiert sind und gibt eine Liste der noch nicht installierten Pakete aus. Der Aufruf erfolgt mit Übergabe der zu ermittelnden Pakete.
bash software.sh paket1 paket2 paket3
Script software.sh
# Eine von beiden Zeilen auskommentieren
#echo -n "cpan install " >notinstalled.sh
echo -n "apt-get install " >notinstalled.sh
while [ $# -gt 0 ]
do
# eine von beiden Zeilen auskommentieren
#perl -M$1 -e '' 2>/dev/null
dpkg -s $1 &> /dev/null

if [ $? -eq 0 ]; then
    echo $1" is installed!"
else
    echo $1" is not installed!"
    echo -n $1" " >>notinstalled.sh
fi
shift
done

Man kann auch nur die Perl Module ermitteln, die im System installiert sind.
Aus diesem Beitrag mal abgeleitet könnte man alle Module ausgeben, die in einem System vollständig installiert sind:
dpkg -l |grep ^ii| awk '{ print $2 }'
Oder nur die Perl Module
dpkg -l |grep -i '\-perl'| awk '{ print $2 }'

Diese List könnte man von Zeilenumbrüchen befreien:
|tr -d "\r"|tr "\n" " "

...und in ein ähnliches Script wie oben einspeisen. Damit hätte man alle Pakete die nicht installiert sind. Das geht auch gleich remote von der "Quell Maschine". (Alle Pakete außer die mit "raspberry" in der Zeile)
bash software.sh $(ssh pi@remotehost "dpkg -l " |grep ^ii|grep -vi raspberry | awk '{ print $2 }' |tr -d "\r"|tr "\n" " ")
Das abgewandelte software.sh Script mit Loggingfunktion
LOG=DiffInstall.log
{
date
while [ $# -gt 0 ]
do
   if dpkg -s $1 &> /dev/null
     then
        echo $1" is installed!"
     else
        apt-get -y install $1
   fi
   shift
done
} >> $LOG 2>&1

Dienstag, 23. Januar 2018

NAS automatisch mit PC starten

Die Geräte sollte ja nur laufen wenn Sie wirklich gebraucht werden. Vom Windows PC aus ein Gerät per WOL starten geht ohne fremde Hilfsmittel.

Hauptscript

Die eigentliche Aufgabe erledigt das Script StarteNAS.ps1
Dies sendet ein magic Packet zur NAS, geht dann in eine Prüfschleife und wartet darauf, dass die IP Adresse der NAS erreichbar ist. Bei Erfolg oder Misserfolg wird der passende Balloon-Tip ausgegeben.
Die Zahl $x muss man seiner realen Umgebung anpassen, bei mir ist die NAS nach ca. 10 Schleifen Durchläufen gestartet, nach 15 Durchläufen ist irgendetwas schief gelaufen.

Hilfsmittel aus der Sammlung

Die Function Send-WOL habe ich im Scriptcenter der Technet gefunden. Ich habe diese im Script SendWOLPacket.ps1 noch mit der Variante kombiniert, einen oder mehrere PC aus einem vorhandenen Array zu starten.
Für etwas Benutzerinformation verwende ich noch das Script BalloonTipp.ps1 welches nur die Function Show-BalloonTip liefert. Wie der Name sagt, kann man damit Nachrichten im BalloonTipp Area von Windows erzeugen.
Beides sind nur allgemein verwendbare Scripts aus der Sammlung.

Installation

Alle 3 Scripts kopiert man in einen passenden Pfad, z.B. c:\Tools\Scripts
Es gibt viele Möglichkeiten ein Script bei der Anmeldung einen Benutzers zu starten, die allereinfachste ist immer noch der Autostartordner, auch wenn MS den immer weiter versteckt hat. So findet man ihn schnell:
Windows+r (Ausführen) und dort ins Fenster shell:startup eintragen und enter drücken. Schon wird der persönliche Autostartordner geöffnet.
Hier erzeugt man jetzt eine Verknüpfung mit folgendem Ziel:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass &'C:\Tools\Scripts\StarteNAS.ps1'

Tipp: Der Parameter ExecutionPolicy ignoriert die gleichnamige Einstellung im System.
Wer gerne den Link mit einem Script erzeugen möchte -> ShortCutFileErzeugen.ps1

NAS nach der Arbeit herunterfahren

Meine NAS kann eine oder mehrere IP Adressen überwachen und sich automatisch herunterfahren wenn diese IP Adressen im Netz nicht mehr aktiv sind. (Openmediavault Plugin autoshutdown)

Anmerkung: Ich habe festgestellt, dass wenn man die Scripte über Gist komplett als Zip Datei herunterlädt, sind die Inhalte beschädigt. Warum das so ist, weiß ich nicht. Also am Besten über die Raw Ansicht den Inhalt kopieren.

Mittwoch, 3. Januar 2018

WebDAV auf dem Raspberry

Wer einen Telekom Anschluss besitzt oder besaß hat dort einen "Cloud" Speicher von 25 GB - dauerhaft. Dieser beherrscht im Gegensatz zu Google Drive WebDAV.
Auch andere Provider (z.B. 1und1) bieten ihren Kunden Online Speicher mit WebDAV Zugriff.
WebDAV ist eine standardisierte Schnittstelle für die Einbindung als Laufwerk ins Betriebssystem, Linux, Windows - eigentlich können das alle.

Ich will hier kurz zeigen wie der WebDAV Zugriff unter Raspbian eingerichtet wird. Was uns an Vorrausetzungen fehlt, ist das Debian Paket davfs2
sudo apt-get update
sudo apt-get install davfs2
Bei mir brachte die interactive Installation die Frage nach dem Zugriff für alle User, diese bitte mit yes beantworten. Ansonsten kann man die Berechtigung später mit diesem Befehl korrigieren.
sudo dpkg-reconfigure davfs2 # interaktiv
sudo chmod u+s /usr/sbin/mount.davfs # direkt
Unter Linux braucht man einen Ort wo man ein Laufwerk "hin" mounten kann, wir erzeugen also einen Pfad mit entsprechenden Berechtigungen:
sudo mkdir /media/magenta
sudo chmod 777 /media/magenta
Da wir das Login zu Magenta Cloud nicht immer eintippen wollen, werden die Informationen entsprechend abgelegt. Der erste Befehl öffnet den Editor und am Ende der Datei wird die zweite Zeile eingefügt. Der Username ist die 12 stellige Zugangsnummer, das Passwort ist ein extra vergebenes WebDAV Passwort und nicht das Passwort vom Kundencenter.
sudo nano /etc/davfs2/secrets
https://webdav.magentacloud.de user passwort
Nun fehlt noch der mount Eintrag in der fstab, es wird nicht automatisch gemountet, alle User dürfen mounten und es ist beschreibbar:
sudo nano /etc/fstab
https://webdav.magentacloud.de /media/magenta davfs noauto,users,rw 0 0
Jetzt können wir das Laufwerk einbinden und den Inhalt anzeigen. Damit das ohne sudo funktioniert muss der User in der Gruppe davfs2 sein. Die Reihenfolge funktioniert so nicht direkt, der User Pi muss sich neu anmelden.
sudo usermod -aG davfs2 pi
mount /media/magenta
ls -l /media/magenta
umount /media/magenta

Hinweise

Bei wheezy gibt es eine Fehlermeldung, obwohl diese Datei erstmal keine Verwendung findet:
/sbin/mount.davfs: file /home/pi/.davfs2/secrets has wrong permissions
Abhilfe schafft der Befehl:
chmod 0600 .davfs2/secrets
Das WebDAV Laufwerk wird auf diese Art nicht automatisch beim Start angebunden. Das Netzwerk ist zu diesem Zeitpunkt noch nicht verfügbar und der automount über die fstab würde nicht funktionieren. Ist für mich kein Nachteil, weil es jederzeit in einem Script per mount Befehl angebunden werden kann.

Manche Webdav Server unterstützen kein file locking (Fehlermeldung:the server does not support locks). Will man die resultierende Fehlermeldung nicht sehen, hilft ein Eintrag in der Datei davfs2.conf.
sudo sh -c 'echo "use_locks 0" >> /etc/davfs2/davfs2.conf'

 Mehr Sicherheit

Wir haben oben das Konto für den Zugriff auf WebDAV global abgelegt, man kann es auch restriktiver für einen bestimmten Benutzer machen. Anstatt der Ablage des Kontos in der Datei/etc/davfs2/secrets, kann die Information auch sicher vor dem Zugriff andere im User Home Verzeichnis hinterlegt werden (Quelle):
touch /home/$(whoami)/.davfs2/secrets
chmod 0600 /home/$(whoami)/.davfs2/secrets
echo "https://cloud.example.com/webDAV/URL <username> <password>" > /home/$(whoami)/.davfs2/secrets

Zum Nachlesen

Wiki fstab
Wiki rsync
Wiki cp
Wiki inotify
lsynd und Beispiel

Freitag, 1. September 2017

Homematic Türschließer

Von Homematic gibt es den HM-Sec-Key als automatischen Schließer für jedes normale Türschloß. Die Einrichtung und die mitgelieferte Beschreibung ist nicht so einfach, deshalb hier ein kleines HowTo. Da man sich ganz schnell vertan hat, fange ich mal am Ende der "ersten" Runde an:

Werksreset

Für den Schlossantrieb

  1. Man baut das Gerät vom Schloß ab
  2. Man drückt den kleinen Taster mit einer Spitze für 2 sec, die Anzeige die jetzt erscheint hängt vom vorherigen Zustand ab -> X bei angelernter Master FB oder rotierender Strich in Richtung der Schließrichtung.
  3. Jetzt dreht man das Handrad in Richtung "Schließen", solange bis die Anzeige wechselt. Bei mir war es kurz die 1 und dann sofort der rotierende Strich.
  4. Jetzt dreht man das Handrad in gleicher Richtung weiter, solange bis die Anzeige kurz ausgeht und ein Piep ertönt.
  5. Jetzt sollte das Gerät im Auslieferungszustand sein.

Für die Fernbedienung

  1. Man drückt den kleinen Taster hinten mit einer Spitze für ca. 5 sec bis es langsam blinkt, 
  2. dann lässt man kurz los und drückt wieder ca. 5 sec bis es schnell blinkt,
  3. jetzt loslassen, es hört es kurz auf mit blinken und es erfolgt ein rot grün gelb blinken als Quittung für den Neustart.

Erste Fernbedienung anlernen


Man sollte unbedingt die erste (Master) Fernbedienung an den Antrieb anlernen bevor man eines von beiden Geräten an die Zentrale (FHEM) anlernt! Die Grundeinrichtung muss abgeschlossen sein. Die Masterfernbedienung hat eine besondere Funktion (Sicherheitsabfrage quittieren)
  1. Im Display steht M. Zuerst drückt man die obere Taste (entriegeln) für 2 sec bis die Anzeige nach 1 wechselt.
  2. Innerhalb von 20 sec drückt man kurz den kleinen Taster an der Rückseite der FB mit einer Spitze. Die LED muss jetzt ruhig grün blinken!
  3. Jetzt drückt man an der FB die obere Taste (Schloß zu). Die LED an der FB muss jetzt schnell orange blinken, ein Zeichen der Datenübertragung. Am Antrieb erscheint während des gelben Blinkens nach kurzer Zeit ein Piep und ein M als Quittung. Als Abschluss leuchtet die LED an der FB grün.

Gerät in FHEM anlernen

Türschlossantrieb

  1. Mit set <vccu> hmPairForSec 60 die Zentrale in den Anlernmodus versetzen
  2. Am Antrieb die obere Taste (Schloss auf) 2 sec drücken, die Anzeige wechselt nach X
  3. Mit der Master FB durch drücken einer der beiden Tasten (Schloss auf oder zu) den Vorgang quittieren (Sicherheitsabfrage)
  4. Ein erneuter Anlernversuch wird durch Anzeige von "c" im Display verweigert.

Fernbedienung

  1. Mit set <vccu> hmPairForSec 60 die Zentrale in den Anlernmodus versetzen
  2. An der FB mit einer Spitze die Taste an der Rückseite kurz drücken. Die LED an der FB muss jetzt schnell orange blinken, ein Zeichen der Datenübertragung. Als Abschluss leuchtet die LED an der FB grün.
  3. In der Regel sind jetzt noch nicht alle Daten übertragen, der Anlernvorgang aber angefangen (Gerät ist angelegt aber die Daten sind nicht komplett). Einfach den Vorgang 2. wiederholen. Es wird eine neue Datenübertragung erfolgen.
  4. Ein erneutes Drücken der Taste an der Rückseite wird mit "rot" quittiert und der Anlernversuch damit verweigert.
Den Anlernvorgang an FHEM zum Schluss am Besten mit hmInfo configCheck überprüfen!

Sicherheit - eigenen AES Schlüssel verwenden

Um es klar zu sagen: AES muss nicht eingerichtet werden, AES machen beide Komponenten von Hause aus. Allerdings ist der Systemschlüssel, der in allen Homematic Komponenten gespeichert ist bekannt. Eine Erhöhung der Sicherheit erreicht man also nur mit einem eigenen Schlüssel.
Grundlage ist die Beschreibung im Wiki. Ich will hier die Schritte zusammenfassen

Hier wird noch gearbeitet

Dienstag, 1. August 2017

Raspberry ausschalten mit FHEM

Man kann den Raspberry einfach so vom Strom ziehen - aber schön ist das nicht!
Wenn man schon FHEM drauf hat, kann man sich auch einen Ausschaltknopf auf der Oberfläche machen.

Achtung: Der Raspberry kann kein WOL oder ähnliches. Aus ist Aus. Baut man das mit dem "halt"
wirklich auf die Weboberfläche muss man sich auch über einen Neustart Gedanken machen!

Als erstes muss der User fhem (der User unter dem FHEM läuft) ein reboot oder halt des Systems auch dürfen. Im raspbian kann man dafür einfach eine Textdatei im Pfad /etc/sudoers.d/ ablegen, man braucht die eigentliche sudoers Datei nicht mit visudo zu editieren (ist mittlerweile in vielen anderen Systemen Standard).
Hinweis:
Der Benutzer Pi bekommt über genau diesen Weg seine sudo Rechte, einfach mal anschauen:
sudo cat /etc/sudoers.d/010_pi-nopasswd

Rechte für User fhem setzen

Wie immer mache ich das gern mit einem Script (welches mit sudo ausgeführt werden muss):
#!/bin/bash
# ergänze eine Datei zum sudoers Script Verzeichnis /etc/sudoers.d/
File="011_fhem-nopasswd"
echo "fhem ALL=(ALL) NOPASSWD: /sbin/reboot, /sbin/shutdown, /sbin/halt" >/etc/sudoers.d/$File
chmod 0440 /etc/sudoers.d/$File
Man kann den Erfolg sofort testen, aber vorher save nicht vergessen, falls man gerade in FHEM etwas geändert hat!
Wenn man in der FHEM Befehlszeile "sudo /sbin/reboot" eingibt, sollte der Raspberry jetzt neu starten. Ein umfangreiches Manual zum Syntax in der Datei findet man hier.

Bedienelemente in FHEM

Damit man einen Knopf in der Oberfläche von FHEM bekommt, kann man es analog zu diesem Beitrag machen. Dazu braucht man allerdings erstmal einen FHEM Befehl:
define s1 cmdalias reboot AS "sudo /sbin/reboot"
Das kann man wieder sofort testen, in dem man reboot in der Kommandozeile von FHEM eingibt - man muss nur aufpassen, dass dem Raspberry nicht schwindelig wird.
define Systembefehle weblink cmdList Restart:Restart-Fhem:shutdown+restart Restart:Restart-System:reboot Update:Update-Check:update+check Update:Update-Now:update Shutdown:Shutdown-System:halt
Der aufmerksame Leser hat gemerkt: hier fehlt noch etwas! Der alias für halt:
define s2 cmdalias halt AS "sudo /sbin/halt"
Optisch sieht das Ganze so aus:
Mit diesem Befehl kann man den Ausschalter auch links ins Menü packen:
attr WEB menuEntries System-Halt,/fhem?cmd=halt

Ein Script zum Einrichten

Für den ganz Eiligen habe ich hier noch alles in einem Script. Damit man das nicht erst noch ausführbar machen muss, kann man es einfach mit sudo bash <scriptname> starten
#!/bin/bash
# System Befehle für FHEM
File="011_fhem-nopasswd"
echo "fhem ALL=(ALL) NOPASSWD: /sbin/reboot, /sbin/shutdown, /sbin/halt" >/etc/sudoers.d/$File
chmod 0440 /etc/sudoers.d/$File
perl /opt/fhem/fhem.pl 7072 '
define s1 cmdalias reboot AS "sudo /sbin/reboot"
define s2 cmdalias halt AS "sudo /sbin/halt"
define Systembefehle weblink cmdList Restart:Restart-Fhem:shutdown+restart Restart:Restart-System:reboot Update:Update-Check:update+check Update:Update-Now:update Shutdown:Shutdown-System:halt
attr WEB menuEntries System-Befehle,/fhem?detail=Systembefehle
save
'

Kleiner Makel

Beim Restart von FHEM (und damit auch beim Restart System) ist danach der csrf Token vom Link nicht mehr gültig. Der Kontakt von FHEM kehrt also nicht allein zurück. Mit der zurück taste im Browser geht es wieder ins Menü.

Inhalt der sudoers Datei

Die durch Komma getrennten Werte in der Datei haben folgende Bedeutung und benötigen immer den vollen Pfad!

/usr/sbin -> für alles im Verzeichnis
/usr/sbin/service * -> für alle Parameter
/usr/sbin/service apache2 * -> für alle weiteren Parameter
/usr/sbin/service apache2 reload -> genau nur hierfür

Der Aufruf in FHEM muss dann genau dem Schema entsprechen:
"sudo /usr/sbin/service apache2 reload"

Freitag, 14. Juli 2017

Elektrodrachen und so

Fertige IoT Module mit dem ESP Modul gibt es mittlerweile Einige. Von SonOff eine ganze Palette, dazu gibt es auch schon Anleitungen im FHEM Wiki.
Eine Alternative mit nicht so breiter Palette liefert Electrodragon. Ich habe mir zwei Module (SPDT und VDC Version ist die Bezeichnung von Electrodragon) von denen bestellt und möchte die Einbindung in FHEM hier kurz vorstellen.
All diesen Modulen gemeinsam ist, dass sie quasi ohne Lötarbeit für FHEM einsatzbereit gemacht werden können, der Interface Stecker zur Programmierung ist schon vorhanden. Die Module enthalten den ESP 12E Baustein mit 4 MB Flash.
Im Gegensatz zu SonOff liefert Electrodragon keine fertige Software und keine App mit. Diese Module sind für den "normalen Anwender" also nicht brauchbar.

Achtung: 

  1. Niemals die Module programmieren oder im offenen Zustand betreiben wenn sie mit dem Stromnetz verbunden sind!
  2. Die Stromversorgung während der Programmierung erfolgt besser durch eine separate 5 V oder 3,3 Volt Spannungsquelle. Sonst ist der Erfolg beim Flashen nicht gewährleistet. Beim Betrieb mit 3,3 Volt funktionieren die Relais nicht sauber! 
  3. Es sind keine Güte- und Prüfsiegel vorhanden! 

Electrodragon liefert derzeit 3 fertige Relais Module, zwei mit SPST Relais (einfacher Schließer) und eines mit SPDT Relais (Umschalter). Leider ist die Beschreibung im Shop relativ dürftig, es sind aber die Schaltpläne verfügbar. Alle Module verfügen über einen bestückten 12 poligen Steckverbinder zum Anschluss der Programmierumgebung und eventuell weitere Komponenten. Sie verfügen weiterhin um einen vorbereiteten Lötanschluss für einen DHT22. Das SPST Modul mit Niederspannungsversorgung hat zusätzlich einen vorbereiteten Lötanschluss für D0-D3 VCC GND.

Verwendungsmöglichkeiten aus meiner Sicht


SPDT Variante
Separates Netzteil zur Speisung 65-250 Volt AC, der Speiseeingang ist nicht mit den Relaiskontakten verbunden! Die Umschaltkontakte der beiden Relais sind separat herausgeführt. Die Kontakte sind damit potentialfrei.

SPST Variante mit Stromversorgung 85-250 Volt AC
Die Schließerkontakte der beiden Relais sind einseitig bereits mit der Speisespannung verbunden. Dieses Modul ist zum Einsatz von Schaltaufgaben mit minimalem Verkabelungsaufwand im Haushalt gedacht. Die Netzspannung kann auf zwei Verbraucher geschaltet werden, sowohl Versorgung als auch Verbraucher haben separate zweipolige Klemmen.

SPST Variante (VDC Version) mit Niederspannung Gleichstromversorgung 5-24 Volt DC
Im Auslieferungszustand sind die Schließerkontakte der beiden Relais einseitig bereits mit der Speisespannung verbunden. Der Pluspol der Speisespannung kann auf zwei Verbraucher geschaltet werden. 
Das Board bietet aber die Möglichkeit den Pluspol der Speisespannung und Schaltspannung zu trennen. Außerdem bietet es die Möglichkeit das Modul separat mit 5 Volt zu versorgen. Dabei ist die Schaltspannung der beiden Relais wählbar (AC oder DC). 
Die Eingangsspannung kann auf zwei Verbraucher geschaltet werden, sowohl Versorgung als auch Verbraucher haben separate zweipolige Klemmen. Man hat damit auch ein Modul mit Niederspannungsversorgung und zwei potentialfreien Schließerkontakten. 
Die Konfiguration der einzelnen Varianten erfolgt mit Jumpern bzw. Lötbrücken.

Praktisches Einsatzbeispiel

Mein Freund Steffen hat mit einem SPST Modul einen Zwischenstecker realisiert. Für kleines Geld gibt es z.B. bei conrad ein universelles Gehäuse (TRU COMPONENTS TC-SG 1022 SW203) und einen Dichtring (TRU COMPONENTS TC-SG 1015 SW203).

Programmierung

Electrodragon hat eine Art Demo Software vorinstalliert, mit der man einen MQTT Server anbinden kann. Ich will das Modul mit ESPEasy flashen und an FHEM anbinden.
Notwendige Hardware: 
Eine serielle Schnittstelle mit 3,3 Volt Logikpegel! (z.B. FTDI USB Adapter)
Eine 5 Volt oder 3,3 Volt Stromversorgung die etwa 300 mA liefern kann. 

Achtung!
Der typische FTDI Adapter kann nur 50 mA liefern und eignet sich nicht zur Stromversorgung! 
Man könnte das Modul über den 5 Volt Anschluss direkt vom USB versorgen, allerdings hat mein FTDI Adapter dafür kein Pin. Mit dem CP2102 Adapter geht das.

Ich verwende ein Breadboard, eine 5 / 3,3 Volt Stromversorgung fürs Breadboard und einen USB/seriell Adapter (mit CP2102 oder FTDI Chip aber unbedingt (3,3 Volt !) sowie ein paar Steckbrücken.
  • Spannungsversorgung aus!
  • Alle Masseanschlüsse werden verbunden, Spannungsanschlüsse am USB/Seriell Wandler werden nicht mit der separaten Versorgung verbunden
  • Stromversorgung an das Modul, Aufpassen! Entweder -> 5 V an 5 V ODER 3,3, V an 3,3 V
  • RX von der seriellen Schnittstelle an TX vom Modul
  • TX  von der seriellen Schnittstelle an RX vom Modul
  • USB Stecker an USB seriell Adapter
  • Spannungsversorgung ein.
Wird die allgemeine Spannungsversorgung mit verbundenem TX RX aber spannungslosem USB/seriell Wandler hergestellt, kann es sein, dass der ESP nicht richtig startet oder sogar "Factory Reset" durchführt.

Zum flashen muss beim Einschalten der Spannungsversorgung, der BTN2 (BTN) Knopf gedrückt  werden. Als Quittung leuchtet die Status LED dauerhaft. Die Bezeichnung der Knöpfe im Plan und Aufdruck ist nicht ganz konsistent.
Man muss beim Aufbau dafür sorgen, dass man leicht mit einer Hand die Stromversorgung stecken kann (Breadboard und Steckbrücke).
Im Detail ist der Flashvorgang hier beschrieben 

Auf dem SPST/VDC Board ist der zweite Knopf (RST) wirklich der Reset Knopf.
Auf dem SPST (Netzteilversion) /SPDT Board ist der zweite Knopf (BTN1) mit GPIO-02 verbunden. Hier muss der Reset also durch kurze Spannungsunterbrechung erfolgen.

Die Einbindung in FHEM zeige ich in diesem Artikel

Montag, 10. Juli 2017

Einbindung von ESPEasy Schaltern in FHEM

Die aktuellen Informationen findet man in der Doku  und im Forum.
Hier habe ich schon mal die Einbindung beschrieben.
ESPEasy kennt kein Relais Gerät als Output. Es kennt nur einen Switch Input. Ein GPIO Pin wird in dem Moment, wo man einen logischen Zustand setzt, einfach auf Ausgang gesetzt. Beispiel
in der ESPEasy Weboberfläche gpio,12,1
in FHEM set <ESPEasy Device Name> gpio 12 on
Genau genommen bräuchte man in ESPEasy für FHEM nichts definieren, allerdings würde das ESPEasy Modul dann auch kein Gerät erzeugen. Da man von seinem Schalter ja auch Lebenszeichen erhalten will, konfigurieren wir die Übertragung der Feldstärke (rssi) und als Status Rückmeldung einen Switch Input. Der eigentliche Schaltvorgang wird über eine eventMap erzeugt.
Durch die Wahl des Namen auf den Deviceseiten erzeugt man in FHEM ein oder mehrere Geräte. Der Name muss also nicht Unikat sein und soll es für diesen Fall auch nicht! Bei gleichen Namen erzeugt FHEM einfach ein weiteres Reading. Der Name im Feld Value bestimmt den Namen des Reading.

ESPEasy konfigurieren

Nach der WLAN Konfiguration mit dem Smartphone (mit ESP_0 verbinden) kommt man mit http://newdevice auf die Weboberfläche. Ich habe diesmal mit der Version 2.0.0 dev10 gearbeitet.
Die einzelnen Konfigurationsschritte (Seiten) immer mit Submit abschicken und das Häkchen bei Enabled nicht vergessen!

Config
Den Namen setzen: EDSPST1
Der neue Name ist im Browser sofort sichtbar, wirkt als Hostname aber erst nach dem nächsten Neustart.

Controllers
Hier ist ein Wert per default vorkonfiguriert, den ändern wir mit Edit.
Hinweis: Das Feld für Controller User und Password wird nur ausgefüllt wenn in FHEM bei der espBridge das Attribute authentication auf 1 gesetzt ist und die Werte für user und pass übergeben wurden!

Hardware
Keine Änderung.

Devices
Hier konfiguriert man zunächst zwei Geräte für die Relais, welche mit GPIO-12 und GPIO-13 verdrahtet sind.


Zusätzlich konfiguriert man noch den RSSI Wert, damit hat man eine Information über den WiFi Empfang des Moduls und dieser Wert sorgt für permanente Status Updates. Dieses Gerät erzeugt man zweimal, nur der Name wird unterschiedlich SW1 bzw. SW2.

Zum Schluss sieht die Konfiguration so aus

Pro vergebenen Device Namen (Name Spalte) wird von der espBridge ein Gerät erzeugt. Der Value Name (Value Spalte) erzeugt je ein Reading.
In FHEM sind durch diese Konfiguration zwei Geräte mit je zwei Readings entstanden.

FHEM konfigurieren

Durch die Übertragung der rssi Werte hat die espBridge in FHEM zwei Geräte erzeugt mit dem Namen ESPEasy_EDSPST1_SW1 und ESPEasy_EDSPST1_SW2. Diese muss man jetzt noch so konfigurieren, das die Schalter auch bedient werden können. Das wichtigste ist eine eventMap:
attr ESPEasy_EDSPST1_SW1 eventMap /gpio 12 on:on/gpio 12 off:off/
attr ESPEasy_EDSPST1_SW2 eventMap /gpio 13 on:on/gpio 13 off:off/
Damit entstehen on und off Kommandos für den set Befehl und für webCmd. Jetzt kann man die Schaltfunktion prüfen.

Damit der Status richtig angezeigt wird, braucht man noch ein angepasstes stateFormat

attr ESPEasy_EDSPST1_SW1 stateFormat {ReadingsVal($name,"presence","") eq "absent" ? "absent" : ReadingsVal($name,"Switch","")}

Das sieht jetzt schon mal gut aus, ist aber noch nicht perfekt.

Nur mal zur Vollständigkeit die bis hierher komplette Definition, also das automatisch Erzeugte und Ergänzungen/Änderungen:
defmod ESPEasy_ED230V_SW1 ESPEasy 192.168.178.107 80 espBridge ED230V_SW1
attr ESPEasy_ED230V_SW1 IODev espBridge
attr ESPEasy_ED230V_SW1 Interval 300
attr ESPEasy_ED230V_SW1 eventMap /gpio 12 on:on/gpio 12 off:off/
attr ESPEasy_ED230V_SW1 group ESPEasy Device
attr ESPEasy_ED230V_SW1 presenceCheck 1
attr ESPEasy_ED230V_SW1 readingSwitchText 1
attr ESPEasy_ED230V_SW1 room ESPEasy
attr ESPEasy_ED230V_SW1 setState 3
attr ESPEasy_ED230V_SW1 stateFormat {ReadingsVal($name,"presence","") eq "absent" ? "absent" : ReadingsVal($name,"Switch","")}


Mit attr <> setState 0 kann man die interne Erzeugung des state Readings ausschalten. Nun kann man mit verschiedenen Methoden z.B. einem userReadings sein eigenes state erzeugen.
state {ReadingsVal($name,"Switch","") }

Noch die Idee aus dem Forum für on-for-timer muss ich noch probieren

attr <deinEsp> eventMap /longpulse 5 on:on-for-timer/longpulse 5 off:off-for-timer/gpio 5 on:on/gpio 12 off:off/status gpio 15:check/

Hier wird noch gearbeitet ...

Mittwoch, 18. Januar 2017

Ein Remote Taster in FHEM mit Rückmeldung

HowTo

Einfacher Taster

Zielstellung

Ein Dummy mit klickbarem Symbol für die Weboberfläche als "Taster" für verschiedenen Aktionen.

Als erste Komponente stattet man einen dummy mit dem Attribute devStateIcon aus:
define testdummy dummy
attr testdummy devStateIcon _start:on:stop _stop:off:start
attr testdummy event-on-change-reading state
set testdummy _stop

Als Zweites braucht man ein notify welches nur auf die Events start und stop vom testdummy reagiert:
define nty_test notify testdummy:(start|stop) set $NAME _$EVENT

Diese Konstruktion wirkt wie ein toggle Schalter, das Symbol beim dummy ist klickbar und bei jedem Klick schaltet es sichtbar on und off.

Die Rückmeldung des Schalters ist damit vorhanden nur er tut nicht wirklich etwas. Zur Demonstration lassen wir "noch etwas tun":
defmod nty_test notify testdummy:(start|stop) sleep 2;;set $NAME _$EVENT

Jetzt erfolgt die Reaktion auf den Klick mit kurzer Pause, stattdessen kann man natürlich auch etwas sinnvolles tun.

Remote Taster mit Rückmeldung

Zielstellung

Ein "Taster" in der Weboberfläche, der auf einem Remote System z.B. einen Dienst startet oder beendet. Mein Taster soll erst reagieren, wenn der Befehl vom Remote System ausgeführt wurde.

Die System sind mit ssh "gekoppelt", wie das geht steht in meinem vorherigen Beitrag.

Achtung! Seit  März 2017 funktioniert die hier beschriebene Steuerung von FHEM über die Webschnittstelle nicht mehr so einfach. Bitte meinen Beitrag im März beachten.

Demo Script

Auf dem Remote System wird ein Script im Home Verzeichnis des verwendeten Remote Benutzers erzeugt/abgelegt und mit chmod +x test.sh ausführbar gemacht:
#!/bin/sh
# Parameter Übergabe
host=$1
name=$2
event=$3
# Kontrollausgabe zum Test aktivieren
# echo $host $name $event
# Zur Demo ein Sleep
sleep 3
# Abfrage und Verzweigung
case "$event" in
    start)
 # hier kann etwas spezifisches bei Start passieren
    ;;

    stop)
 # hier kann etwas spezifisches bei Stop passieren
    ;;
    *)
       exit 1
    ;;

esac
# Web Kommando an FHEM absetzen
h=$host':8083'; c='set '$name' '$status; curl --data "fwcsrf=$(curl -s -D - http://$h/fhem?XHR=1 | awk '/X-FHEM-csrfToken/{print $2}')" http://$h/fhem?cmd=$(echo $c|sed 's/ /%20/g')

exit 0

Zum Test kann man dieses Script mit ./test.sh <FHEM hostname> testdummy start aufrufen. Dabei muss sich der Status unseres Dummy ändern.

Funktioniert dieser Test, wird das notify geändert, die hostnamen müssen angepasst werden:
defmod nty_test notify testdummy:(start|stop) "ssh pi@<remote hostname> ./test.sh <FHEM hostname>  $NAME $EVENT"

An der Reaktion des Dummy hat sich nicht viel geändert, da ich im Script sleep 3 gesetzt habe dauert es jetzt 1 Sekunde länger. Dafür passiert aber etwas auf einem anderen System!

Praktische Verwendung

Das Demo Script kann so als Grundgerüst verwendet werden. Im einfachsten Fall fügt man an den entsprechende Stellen einfach nur Befehle ein. Komplizierter wird es, wenn man z.B. vor Rückkehr (absetzen des Befehls an FHEM) wirklich überprüfen will/muss ob die gewünschet Aktion auch gelaufen ist.
Das notify kann für mehrere dummy verwendet werden.

Dienst steuern

Um einen Dienst zu starten und zu stoppen muss das Script und der dummy etwas angepasst werden. Zum Testen habe ich meinen Dienst aus diesem Beitrag genommen. Der Name muss entsprechend angepasst werden. Man könnte den Dienstnamen auch im notify übergeben.
Der Steuerbefehl (event) wird nochmal überprüft und übergeben. Nach kurzer Wartezeit wird der Status abgefragt und dieser direkt an FHEM übergeben. Der Status ist also direkt im dummy sichtbar
#!/bin/sh
# Parameter Übergabe
host=$1
name=$2
event=$3
service=<Dienst Name>
# Abfrage und Verzweigung
case "$event" in
    start|stop)
   # Sicherstellen das nur zulässige Events verwendet werden
   sudo systemctl $event $service 
   sleep 2
          status=$(systemctl is-active $service)
   # Web Kommando an FHEM absetzen (neu mit csrfToken)
   h=$host':8083'; c='set '$name' '$status; curl --data "fwcsrf=$(curl -s -D - http://$h/fhem?XHR=1 | awk '/X-FHEM-csrfToken/{print $2}')" http://$h/fhem?cmd=$(echo $c|sed 's/ /%20/g')

    ;;

    *)
      exit 1
    ;;

esac

exit 0

Wenn der Dienst läuft wird er als active erkannt, wenn er gestoppt ist liefert er unknown zurück. Das Mapping des devStateIcon wird einfach angepasst.

attr testdummy devStateIcon active:on:stop unknown:off:start