OpenHAB-Installation und Grundlagen
Konzepte von OpenHAB
Am Anfang ist es nicht ganz einfach das Konzept von OpenHAB nachzuvollziehen. Das folgende Bild zeigt mein Verständnis davon, das ich aus Diskussionen mit Rich Koshak gewonnen habe:
Am Anfang (im Bild rechts) stehen immer die Geräte (Devices), wie ein Homematic Heizkörper-Thermostat, ein Samsung TV oder ein Shelly-Plug. Diese Geräte unterschiedlichster Hersteller werden über Bindigs in die OpenHAB-Welt eingebunden. Bindings sind im Prinzip Software-Schnittstellen, die OpenHAB erweitern. Über das Binding wird die zugehörige Hardware erkannt und als Thing in die Oberfläche übernommen. Jedes Thing besitzt dann eine Reihe von Channels, über die bestimmte Einstellungen abgefragt bzw. geändert werden können.
Mit den Things und Channels selber beschäftigt man sich in OpenHAB aber kaum.
Zentral in OpenHAB sind die Items, das sind meist Links auf Channels (die Points). Es gibt aber auch Items, die andere Items zusammenfassen, gruppieren. Wenn diese Items auf Links zu Channels basieren, dann wird damit ein Equipment beschreiben, ein Ausrüstungsgegenstand. Das Equipment kann auf einem Device beruhen, muss aber nicht. Es können Channels fehlen, oder Channels von anderen Devices mit verlinkt werden. Neben diesen Gruppen-Items vom Typ Equipment gibt es Items vom Typ Location, die im weitesten Sinne Räume beschreiben, wobei dann auch wieder mehrere Räume zu einem Gruppen-Item z.B. einer Etagen-Location zusammengefasst werden können.
Den Zusammenhang zwischen den Items der unterschiedlichen Typen:
- Location
- Equipment
- Point
wird im Model definiert.
Ergeschoss (FirstFloor) und Esszimmer (DiningRoom) sind hier Items vom Type Location. Fenster.Esszimmer.01 und Shelly Plug-S (SHPLG-S) sind dann Items (die Bezeichner sind nicht glücklich, weil teilweise zusammengesetzt mit Location), vom Typ Equipment in der Location Esszimmer.
Die Reihenfolge der Einträge im Model ist, sofern sie sich nicht aus der Struktur ergibt, alphabetisch. Will man hier eine eigene Reihenfolge festlegen, so braucht man Metadata vom Typ Default Widget Order Index. Hier kann man unter Order in Lists eine Zahl angeben. Ich gehe so vor, dass ich für die Etagen 1000er Nummern vergebe: Dachgeschoss:1000, Obergeschoss:2000 usw. Die Räume variieren in der Hunderter-Stelle und die Geräte in der 10er Stelle.
Das Shelly Plug verfügt dann über eine Reihe von Items des Typs Point, die auf den Kanälen des Devices beruhen. Von den 17 Channels des Devices haben aber nur 9 eine Entsprechung als Point des Equipments
Es ist sinnvoll, das Model für OpenHAB sehr sauber und ordentlich zu strukturieren. Das erleichtert die Konfiguration der Pages, über die dann die Funktionalität von OpenHAB realisiert wird. Auf den Pages bindet man dazu vordefinierte oder selbst erstellte Widgets ein.
Etwas verdeutlicht werden die Zusammenhänge auch unter Einstellungen -> Model
Über den Menüpunkt Create Equipment from Thing würde man, bei ausgewählter Location, ein neues Equipment basierend auf einem Thing hinzufügen. Will man nur einen einzelnen Point, z.B. einen der nicht genutzten 8 Channels beim Shelly hinzufügen, so würde man das Equipment Item auswählen und Create Point from Thing anwählen.
Es gibt übrigens auch Things, die nicht auf irgendeinem Device basieren. Dazu gehören z.B. die Online-Tests mittels Ping.
Für ein neues solches Thing geht man unter Things auf das Plus-Icon rechts unten auf der Seite. Im ersten Schritt muss man das Binding auswählen, dass man nutzen möchte, hier also das Network-Binding. Im nächsten Schritt kann man mit Scan das Binding suchen lassen, was es im Netz so an Geräten und Diensten findet, oder man geht direkt auf Add Manually -> Pingable Netzwerkgerät
Mit einen Klick auf Create Thing ist das entsprechende Thing erzeugt und kann ganz normal in das Model eingebunden werden.
Installation
Es bietet sich an, openHAB auf einem extra Rechner zu installieren, dafür eignet sich ein Raspi als Gerät. Ich habe mich dabei an der Beschreibung von https://phenx.de/openhab-3-auf-raspberry-installieren-openhabian/ orientiert. Leider wird dort nicht auf die Entscheidung für 32Bit oder 64Bit System eingegangen. Nach etwas Recherche auf den openHAB Seiten habe ich mich dann für die 32Bit-Version entschieden von Version 3.4.0. In der verlinkten Anleitung wird auf die Vorab-Konfiguration des WLAN über die openhabian.conf hingewiesen. Das hat bei mir nicht funktioniert, da man bei 4.3.0 anscheinend die Datei /boot/openhabian.conf benutzen muss.
Das WLAN konnte ich anschließend auch nicht per openhabian-config konfigurieren, ich habe dann raspi-config erfolgreich dafür genutzt. Damit wird die /etc/wpa_supplicant/wpa_supplicant.conf mit folgendem Inhalt versehen:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=DE
network={
ssid="meinessid"
psk="meinkey"
}
Weitere Möglichkeiten unter https://www.elektronik-kompendium.de/sites/raspberry-pi/1912221.htm
Folgende Bindings habe ich gleich bei der Installation mit installiert:
- AllPlay Binding
- AstroBinding
- AVM FRITZ!Box Binding
- Homematic Binding
- HTTP Binding
- Network Binding
- NTP Binding
- Samsung TV Binding
- Shelly Binding
- TR-064 Binding
Einbinden von Things über Bindings
Nach dem Installieren der benötigten Bindings findet OpenHAB eine Reihe von Geräten, die dann unter Things in der Inbox auftauchen, eventuell muss man auch einige Zeit warten. Dabei ist die Situation je nach Binding unterschiedlich:
Allplay
Im ersten Schritt musste ich das Problem mit der libssl lösen (s.u.) dann tauchten nach einer Wartezeit alle im Netz vorhandenen Geräte auf, die sind ja auch über ihre IP-Adresse erreichbar.
Astro
Es tauchen die Geräte "Lokale Monddaten" und "Lokale Sonnendaten" in der Box auf.
AVM FRITZ!Box
Es taucht erst einmal nur die Fritz!Box als Gerät auf.
TR-064
Gehört zum Umfeld der Fritz!Box
Homematic
In der Inbox taucht anfangs nur die CCU auf. Erst wann man diese eingebunden hat, dann tauchen auch die vielen Geräte auf, die die CCU verwaltet. Zusätzlich taucht auch das Gerät GATEWAY-EXTRAS und das Gerät ZENTRALE auf.
HTTP
kein Gerät
Network
kein Gerät
NTP
Das Gerät "Lokale Zeit" taucht auf.
Samsung TV
Der Fernseher taucht korrekt in der Inbox auf.
Shelly
Hier ist es recht unterschiedlich. Die Geräte, die aus dem Stromnetz versorgt werden, tauchten hier automatisch auf. Es gab aber Probleme mit dem Shelly 1 mit Addon, da dort die drei Sensoren den gleichen Namen haben. Man muss sie daher nacheinander einbinden, um sie getrennt und unterscheidbar benennen zu können. Bei den Batteriegeräten wie Shelly H&T klappte die Einbindung immer nur dann, wenn ich vorher auf den Knopf am Gerät gedrückt habe, ansonsten muss man viel Geduld aufbringen.
Modbus
Das Modbus-Binding benötige ich für den Zugriff auf meinen Huawei Wechselrichter
Sichern der Installation
Wenn man einige Zeit an dem System gearbeitet hat, dann wäre ein Datenverlust schon sehr ärgerlich. Für das Backup gibt es mehrere Möglichkeiten.
- Kopieren der Speicherkarte
- Benutzen der OpenHAB Backup-Funktion
Kopieren der Speicherkarte
Das Kopieren der Speicherkarte ist schnell erledigt, mit Hilfe von DD auf dem Arbeitsplatzrechner. Damit wird die komplette Karte kopiert und im Notfall kann einfach die Kopie anstelle der Originalkarte eingesetzt werden.
Besser ist eine automatisierte Sicherung auf einem NAS
OpenHAB Backup-Funktion
OpenHAB verfügt über eine eingebaute Backup-Funktionalität. Ist man auf dem Raspi angemeldet, so kann man die Funktion aufrufen mittels:
sudo $OPENHAB_RUNTIME/bin/backup
Über die Variable löst der Befehl auf zu
sudo /usr/share/openhab/runtime/bin/backup
Das Backup wird dann mit Datum erzeugt und lokal abgelegt unter z.B.:
/var/lib/openhab/backups/openhab-backup-22_01_09-16_44_58.zip
bzw.
$OPENHAB_BACKUPS/openhab-backup-22_01_09-16_44_58.zip
Für das Zurückspielen gilt dann entsprechend
sudo systemctl stop openhab sudo $OPENHAB_RUNTIME/bin/restore $OPENHAB_BACKUPS/openhab-backup-22_01_09-16_44_58.zip sudo systemctl start openhab
Sollte es sich um ein neu installiertes System handeln und das Backup-Verzeichnis noch nicht vorhanden sein, so legt man es an und kopiert die Sicherung dort hinein.
Anfangs-Probleme
Leider wird der Einstieg in OpenHAB nicht ganz leicht gemacht. Es gibt zwar eine umfangreiche Dokumentation unter https://www.openhab.org/docs/ mir fehlen aber schöne Einstiegs-Beispiele. Viel gelernt habe ich dann über https://community.openhab.org/ aber es bleibt mühsam.
In diesem Abschnitt sammle ich meine ersten Probleme und ihre Lösung.
Problem mit AllPlay Binding
Das Binding wollte bei mir nicht funktionieren. Nach etwas Recherche bin ich auf den Hinweis gestoßen, dass dies mit der OpenSSL Bibliothek zusammen hängt. Das AllPlay Binding kann mit der aktuellen Version nichts anfangen und benötigt eine ältere Version.
wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u12_armhf.deb apt install ./libssl1.0.0_1.0.1t-1+deb8u12_armhf.deb
Lädt und installiert die ältere Version.
Bei dem Openhabian zu OpenHAB 3.4.0 wurde die Installation des Paketes mit einer Fehlermeldung hinsichtlich nicht auflösbarer Abhängigkeiten abgelehnt. Erfolgreich wurde ich dann mit:
dpkg --force-depends -i libssl1.0.0_1.0.1t-1+deb8u12_armhf.deb
Mit
ldconfig -p | grep libssl
habe ich mich dann überzeugt, dass die Bibliothek installiert wurde.
libssl3.so (libc6,hard-float) => /lib/arm-linux-gnueabihf/libssl3.so
libssl.so.1.1 (libc6,hard-float) => /lib/arm-linux-gnueabihf/libssl.so.1.1
libssl.so.1.0.0 (libc6,hard-float) => /lib/arm-linux-gnueabihf/libssl.so.1.0.0
Zum Abschluss habe ich dann den Raspi neu gestartet. Danach erschienen dann auch die AllPlay Things in der Inbox.
User anlegen
Für die normale Benutzung benötigt man User ohne besondere Admin-Rechte. Ich habe in der Oberfläche überall nach einer Möglichkeit gesucht. Erst über den Artikel https://community.openhab.org/t/is-openhab-3-multiuser/111277/21 ist mir klar geworden, dass es in der GUI (noch) keine Option dafür gibt.
Ich habe mich also ganz normal per SSH am Raspi angemeldet. Dann nach Beschreibung unter https://www.openhab.org/docs/administration/console.html
ssh -p 8101 openhab@localhost
Das dann notwendige Passwort ist habopen .
Dort habe ich dann den User benutzer angelegt mittels
add benutzer password user
Löschen von Pages
Beim Testen legt man immer mal wieder Pages an. Wie man diese Seiten wieder löscht, konnte ich nicht sofort finden. Man geht dazu auf Einstellungen -> Pages. Jetz erschein die Liste der vorhandenen Seiten und in der oberen rechten Fensterecke das Wort Select. Klickt man darauf, so erscheint vor jeder Seite ein Auswahlkästchen und wenn man eines der Kästchen angeklickt hat, dann erscheint unten auf der Seite ein Link Remove.
Zeitsteuerung für Rules
Die Rules genannten Programme werden in Abhängigkeit von Trigger-Ereignissen ausgelöst. Ein Trigger kann das Ändern einer Temperatur, das Drücken eines Buttons, aber auch eine Zeitsteuerung sein.
triggers:
- id: "1"
configuration:
cronExpression: 0 0 * ? * *
type: timer.GenericCronTrigger
Die Definition des Cronjobs ist für mich ungewöhnlich, es macht Sinn den Generator unter https://www.freeformatter.com/cron-expression-generator-quartz.html zu nutzen um die Einstellung nachvollziehen zu können.
0 0 * ? * * steht für Every hour 0 * * ? * * für Every minute * * * ? * * für Every second
Verschieben von Things im Model
Ein grafisches Drag&Drop für Things im Seitenbaum des Models ist nicht vorgesehen. Es geht aber trotzdem relativ einfach.
Jedes Thing ist Quasi eine Gruppe von Items. Zu jedem Thing gehört daher auch ein Gruppenitem. Dieses Gruppenitem muss man sich unter Items suchen und anklicken.
Hier findet sich unter Direct Parent Groups die übergeordnete Gruppe, hier Esszimmer. Mit einem Klick auf Edit (rechts oben im Fenster) kann man das bearbeiten.
Hier kann man jetzt über einen Klick auf Parent Group(s) die Position im Model-Baum verändern und eine andere Eltern-Gruppe auswählen.
Da man hier mehrere Eltern-Elemente auswählen kann, muss man darauf achten bei dem vorherigen Element das Häkchen zu entfernen.
Sowie man auf Schließen und dann auf Save klickt (rechts oben im Fenster) ist die Änderung aktiv.
Die Karaf Konsole
In vielen Anleitungen wird immer wieder auf die Karaf-Konsole verwiesen. Es ist aber nicht ganz leicht, dafür eine vernünftige Beschreibung zu finden.
Man muss lokal an dem Linux-System von OpenHAB angemeldet sein. Dann ruft man die zugehörige Shell auf mittels:
ssh openhab@localhost -p 8101
Das Standardpasswort ist habopen. Der Benutzer hier ist wirklich openhab, auch wenn der Systembenutzer eventuell openhabian ist.
Innerhalb der Shell kann man dann mit TAB sich eine Liste der Befehle anzeigen lassen.
Ich brauchte:
links list
bzw.
links orphan list
Auf der Suche nach einem problematischen Link.
Am Ende loggt man sich mit logout wieder aus.
Der Aufruf von
links orphan list
lieferte eine Liste mit über 100 Einträgen in zwei Kategorien:
Item missing: Thing channel missing:
Ich werde also der Empfehlung von Rich Koshak folgen und die verweisten Links mittels
links orphan purge
löschen.
AllPlay Radioempfang steuern mit der Homematic-Fernbedienung
Für die AllPlay-Geräte haben wir uns ursprünglich entschieden, weil sie im täglichen Betrieb auch ohne App bedienbar waren. Nachdem Panasonic diesen Vorteil nun zunichte gemacht hat kam die Idee auf, die vorhandene Homematic-Fernbedienung für diesen Zweck zu nutzen.
Homematic-Fernbedienung
Die Fernbedienung verfügt über 20 Kanäle und die Möglichkeit die zugehörige Funktion auf dem internen Display anzuzeigen. Für die Nutzung muss man bei Homematic unter Geräte ein paar Einstellungen für die Kanäle vornehmen:
Im Screenshot sieht man den Text, den ich für den Kanal eingetragen habe. Außerdem musste ich für jeden Kanal ein Programm anlegen, damit die Belegung auf die Fernbedienung übertragen wird.
Ich habe hier nur eine Bedingung eingetragen, nämlich dass die entsprechende Taste gedrückt wird, aber keine Aktion. Die soll ja innerhalb von OpenHAB erfolgen.
Rule NDR2
Innerhalb von openHAB taucht die Taste dann als Thing auf und ich habe mir eine Rule erstellt.
Das zugehörige Programm ist dann mit der grafischen Entwicklungs-Umgebung schnell erstellt:
Rule Kopplung
Nun noch ein kleines Programm für die Kopplung zweier Geräte auf eine andere Taste gelegt.
Rule Ausschalten
Und ein weiteres Programm zum Ausschalten der Geräte
Hier werden nicht wirklich die Geräte ausgeschaltet, das machen die Apps auch nicht, sondern den Geräten wird nur übermittelt dass sie nichts zu spielen haben. Dann schalten sie sich nach einiger Zeit selber ab.
Arbeiten mit Gruppen
Ein weiteres Ziel war es auf einer Übersichtsseite anzeigen zu können, ob alle Fenster im Haus geschlossen sind.
Mein erster Ansatz bestand darin mir von der Homematic über GATEWAY-EXTRAS die vorhandene Variable Offene_Fenster zu holen. Leider ist es so, dass diese Daten nicht oder nur mühsam aktualisierbar sind. Es dauerte mir immer viel zu lange, bis eine Aktualisierung möglich war. Ich hatte zwar gefunden, dass man mit
events.sendCommand('GATEWAYEXTRAS_ReloadAllFromGateway', 'ON');
die Aktualisierung anstossen kann, aber dann werden anscheinend viele Daten aktualisiert, was dauert, selbst ein
java.lang.Thread.sleep(10000);
vor der Aktualisierung hat da nicht ausgereicht
Nach vielen Versuchen habe ich eine recht flexible Lösung gefunden. Dazu habe ich unter Items über ein neues Item angelegt (Add Item). Dieses Item hat von mir den Namen GruppeFenster bekommen und den Type Group.
Wichtig sind hier die Einstellungen im unteren Bereich:
- Member Base Type: Contact
Von dieser Auswahl ist die nächste Einstellmöglichkeit betroffen:
- Aggregation Function: One OPEN then OPEN else CLOSED
Sowie also ein einziges Fenster offen ist, so zeigt die Gruppe das auch, nur wenn alle Fenster geschlossen sind, dann hat die Gruppe auch diese Eigenschaft.
Nun muss man noch die Fenster dieser Gruppe hinzufügen. Das kann man umständlich von jedem Fenster einzeln aus machen, oder von der neuen Gruppe. Speichert man die eben getroffenen Einstellungen mit Save, so landet man wieder im Item-Fenster und kann dort über einen Click auf Change die Fenster auswählen.
Es erscheint jetzt eine Seite mit der Liste der Direct Group Members
Zum Bearbeiten der Liste klickt man auf die Zeile mit den Members, worauf ein Popup mit der Liste aller Items zur Auswahl erscheint.
Wichtig ist, dass man hier nicht die Fenster auswählt, sondern ihren Zustand. Mit einem Klick auf Schließen und danach noch Apply werden die Einstellungen übernommen.
In meiner Übersichtsseite habe ich dann eine Label-Card erstellt mit folgendem YAML
comp''Kursiver Text''onent: oh-label-card
config:
title: Fenster
item: GruppeFenster
background: '=(items.GruppeFenster.state === "OPEN") ? "red" : "lightgreen"'
icon: oh:window
action: popup
actionModal: page:page_32a98b1708
label: '=(items.GruppeFenster.state === "CLOSED") ? "Alle zu" : "offen"'
Dieser Code hat drei Funktionen. Es wird also je nach Zustand ein unterschiedlicher Text angezeigt und die Hintergrundfarbe ist vom Zustand abhängig. Zusätzlich wird durch einen Klick auf diese Card eine weitere Page als Popup geöffnet, auf dieser Seite sind dann alle Fensterzustände einzeln zu erkennen.
Meine Widgets
Schon lange möchte ich eigene Widgets erstellen, einfach um schönere Darstellungen und Darstellungen mit weniger Aufwand zu erreichen.
Unter https://community.openhab.org/c/marketplace/ui-widgets/75 findet sich eine Zusammenstellung von Widgets, die kann man benutzen und als Anregung verwenden. Es gibt zwar unter https://next.openhab.org/docs/tutorial/custom_widgets.html ein Tutorial, das lässt aber viele Fragen offen. Wichtig im Zusammenhang mit eigenen Widgets ist mir die Wiederholstruktur, die es ebenfalls gibt und die unter https://next.openhab.org/docs/ui/components/oh-repeater.html "dokumentiert" ist.
ud_batterie_status
Hier nun das erste Widget, das ich selbst erstellt habe. Es zeigt den Batteriestatus aller Geräte an, die in einer Batterie-Gruppe zusammengefasst sind.
uid: ud_batterie_status
tags: []
props:
parameters:
- context: item
description: Group Das Item das alles Batterie-Level aggregiert
label: Batterie Zustands Item
name: batLevel
required: true
type: TEXT
filterCriteria:
- value: Group
name: type
parameterGroups: []
timestamp: Jan 1, 2022, 2:58:39 PM
component: oh-list-card
config:
title: '="Eine Batterie Leer: " + ((items[props.batLevel].state === "OFF") ? "Nein" : "Ja")'
slots:
default:
- component: oh-repeater
config:
fragment: true
for: item
sourceType: itemsInGroup
groupItem: =props.batLevel
fetchMetadata: widgetOrder,semantics
slots:
default:
- component: oh-list-item
config:
icon: '=(loop.item.state === "OFF") ? "oh:battery-90" : "oh:battery-10"'
title: = loop.item.metadata.semantics.config.isPointOf
item: =loop.item.name
badge: '=(loop.item.state === "OFF") ? "Ok" : "Wechseln"'
badgeColor: '=(loop.item.state === "OFF") ? "green" : "red"'
footer: =items[loop.item.metadata.semantics.config.isPointOf+"_BatteryState"].state
action: group
actionGroupPopupItem: =loop.item.metadata.semantics.config.isPointOf
Mit den letzten Zeilen wird aus dem list-item quasi ein Button, über den ein Popup mit den Eigenschaften des zugehörigen Gerätes aufgerufen wird.
Mit dem folgenden YAML-Code ist das Widget dann in eine Spalte einer Page eingebunden.
component: widget:ud_batterie_status
config:
batLevel: GruppeBatterieZustand
Der folgende Screenshot vermittelt einen Eindruck davon, wie das Widget auf der Seite aussieht.
Und dann das Popup, wenn man eines der Battrie-Items angeklickt hat:
Benutzt wird hier das Standard-Geräte Widget von OpenHAB.
Sicher kann man hier noch eine ganze Menge optimieren. Was mich am meisten ärgert ist die Tatsache, dass ich nicht ganz einfach an die anderen Datenfelder (Points) heran komme. Bei einigen Geräten wird auch die Batteriespannung gemeldet, diese Information würde ich auch gern mit anzeigen lassen.
Ein weiterer noch nicht ganz klarer Punkt für mich ist die Frage der Reihenfolge. Momentan scheinen die Geräte in der Reihenfolge zu stehen, in der ich sie in die Gruppe aufgenommen habe. Falls das stabil stimmt wäre das eine Möglichkeit. Schöner wäre eine direkte Möglichkeit der Sortierung. Inzwischen habe ich eine Möglichkeit für die Sortierung gefunden. Man muss bei den Batterie-Items jeweils Metadata vom Typ Default Widget Order Index hinzufügen. Dort gibt man eine "Zahl" an, die aber nach Textkriterien sortiert wird, also 10 < 2. Ich habe daher Tausender-Zahlen benutzt:
- Tausender-Stelle: Etage
- Hunderter-Stelle: Raum
- Zehner-Stelle: Equipment
- Einer-Stelle: Item
Im nächsten Schritt wollte ich erreichen, dass ich vom Batterie-Item aus auch das Gerät und den Raum bestimmen kann. Die Diskussion in der Community hat mir deutlich gemacht, dass es nicht trivial ist, aber möglich.
Eine interessante Möglichkeit habe ich in diesem Zusammenhang kennen gelernt. Es ist möglich Daten von einem Widget zum nächsten zu übergeben
ud_shellyplug
An dem folgenden Widget habe ich längere Zeit gebastelt und bin wohl auch über ein paar Fehler in OpenHAB gestolpert. Über die Diskussion in der OpenHAB Community habe ich viel dazu gelernt.
Ziel war es ein Widget zu bauen, das die wichtigsten Werte und Funktionen meiner Shelly-Plugs nutzbar macht und möglichst einfach nutzbar ist.
Man kann hier eine Überschrift angeben und muss ein Shelly-Plug auswählen, mehr nicht. Das Element hat dann folgendes Aussehen.
Hier sieht man schon eine Merkwürdigkeit. Die LEDs beim Plug sind dann an, Wenn xxxLEDaus OFF ist. Viel Aufwand hatte ich daher damit, das entsprechende Toggle-Element auf Grün zu setzen, wenn das zugehörige Element OFF ist und Rot bei ON.
(Grün bedeutet immer in Betrieb, Rot ausgeschaltet. Die WiFi-LED ist also aus und die Betriebs-LED an, zumindest wenn der Strom-Schalter in Betrieb ist.)
Die üblichen Zeilen wie
color: '=(items[props.item + "_Betrieb"].state == "ON") ? "green" : "red"'
funktionieren nämlich nicht. Der inaktive Zustand wird immer in Grau dargestellt. Insofern kann man sich die Fallunterscheidung auch schenken.
Folgender Workaround funktioniert aber
color: green style: --f7-toggle-inactive-color: "#e64a19"
Der komische Hex-Wert für Rot ist von OpenHAB abgeschaut, ebenfalls der für Grün (s.u.).
uid: ud_shellyplug_grid
tags: []
props:
parameters:
- description: Überschrift (wenn leer, dann wird der Name des Schalters benutzt)
label: Überschrift
name: ueberschrift
required: false
type: TEXT
- context: item
description: Der Schalter (Shelly Plug)
label: Item
name: item
required: true
type: TEXT
parameterGroups: []
timestamp: Dec 8, 2021, 6:19:50 PM
component: oh-list-card
config:
title: '="Zustand von " + ((props.ueberschrift) ? props.ueberschrift : props.item)'
slots:
default:
- component: oh-toggle-item
config:
title: = "In Betrieb:"
item: = props.item + "_Betrieb"
color: green
style:
--f7-toggle-inactive-color: "#e64a19"
badgeColor: red
- component: oh-toggle-item
config:
title: ="BetriebsLED aus:"
item: = props.item + "_BetriebsLEDaus"
style:
--f7-toggle-active-color: "#e64a19"
--f7-toggle-inactive-color: "#4cd964"
- component: oh-toggle-item
config:
title: ="Wi-Fi LED aus:"
item: = props.item + "_StatusLEDaus"
style:
--f7-toggle-active-color: "#e64a19"
--f7-toggle-inactive-color: "#4cd964"
- component: oh-list-item
config:
title: "Gerätetemperatur:"
badge: =items[props.item + "_Geratetemperatur"].state
- component: oh-list-item
config:
title: "Gesamtverbrauch:"
badge: =items[props.item + "_Gesamtverbrauch"].state
- component: oh-list-item
config:
title: "Läuft seit:"
badge: =dayjs().subtract(Number.parseInt(items[props.item + "_Laufzeit"].state), 's' ).format('D.MM.YY HH:mm')
- component: oh-list-item
config:
title: "Leistung:"
badge: =items[props.item + "_Leistung"].state
- component: oh-list-item
config:
title: "Signalstärke:"
badge: =items[props.item + "_Signalstarke"].state
badgeColor: '=(Number.parseInt(items[props.item + "_Signalstarke"].state) < 1 ) ? "red" : ((Number.parseInt(items[props.item + "_Signalstarke"].state) > 2) ? "green" : "yellow")'
Jetzt sieht das Listing recht einfach und übersichtlich aus, aber an der richtigen Syntax für die Nutzung der Elemente habe ich dann doch eine Weile gesessen.
Für mich gibt es hier noch zwei Probleme, an denen ich arbeiten muss:
- Auf Android-Geräten hat das Toggle-Element eine kleinen Fehler. Der weiß Kreis (der Schalter) nimmt im Zustand ON die Farbe des Hintergrund (also Rot oder Grün) an. Das ist aber auch bei den Standard-Widget der Fall.
- Ich suche eine Möglichkeit durch alle Eigenschaftsfelder zu iterieren, damit könnte man die vielen Wiederholungen vermeiden und das Widget würde universeller.
Für das zweite Problem gibt es eine einfache Lösung. Ein Equipment wird immer durch ein Item repräsentiert, welches eine Gruppe darstellt. Damit kann man einfach über die Gruppe iterieren:
- component: oh-repeater
config:
fragment: true
for: item
sourceType: itemsInGroup
groupItem: =props.batLevel
fetchMetadata: widgetOrder
Problem mit Tags
Aus der Diskussion im Forum hat sich dieses Code-Fragment entwickelt. Es war überraschend, dass hier hinter itemTags nur ein Komma steht und andere Kombinationen nicht funktionierten.
- component: oh-repeater
config:
for: witem
sourceType: itemsWithTags
itemTags: ,
fetchMetadata: semantics,stateDescription,widgetOrder
fragment: true
Inzwischen habe ich gefunden, dass das Komma wie ein Und wirkt und nicht wie ein Oder. Wenn man mehrere Tags aufführt, dann werden nur Elemente gewählt, die alle Tags besitzen. Der Wert darf aber anscheinen auch nicht einfach leer bleiben, daher das Komma. Ein Und mit zwei leeren Eingaben.
Shelly H&T
Der Shelly H&T ist ein relativ preiswerter kleiner Sensor, der Temperatur und Feuchtigkeit per WLAN zur Verfügung stellt. Er meldet sich aber nur dann, wenn eine Änderung seiner Werte erfolgt, von daher ist es sinnvoll auch die Zeit der letzten Aktualisierung mit zu betrachten:
Klickt man auf diese Karte, so erscheint das folgende Diagramm:
OpenHAB hat hier die Prozentangabe noch einmal durch 100 geteilt, na gut.
Dazu gehört dann der folgende YAML-Code:
uid: ud_shellyht_card
tags: []
props:
parameters:
- description: Überschrift (wenn leer, dann wird der Name des Gerätes benutzt)
label: Überschrift
name: ueberschrift
required: false
type: TEXT
- context: item
description: Das Gerät (Shelly)
label: Item
name: item
required: true
type: TEXT
filterCriteria:
- name: type
value: Group
parameterGroups: []
timestamp: Jan 5, 2022, 12:20:15 PM
component: oh-label-cell
config:
header: "=(props.ueberschrift) ? props.ueberschrift : props.item"
label: = "Temperatur " + items[props.item + "_Temperatur"].state
trendItem: = props.item +"_Temperatur"
action: analyzer
actionAnalyzerItems: =[props.item +"_Luftfeuchtigkeit", props.item +"_Temperatur"]
icon: oh:temperature
footer: = 'Letzte Aktualisierung ' + items[props.item + "_LetzteAktualisierung"].displayState
subtitle: = "Luftfeuchtigkeit " + items[props.item + "_Luftfeuchtigkeit"].state
expandable: false
style:
background: '=(items[props.item + "_Luftfeuchtigkeit"].state.split(" ")[0] > 60) ? "red" : "lightblue"'
Ein paar Erläuterungen zu dem Code:
- In den ersten 15 Zeilen werden hauptsächlich die Konfigurationseinstellungen festgelegt. Es muss ein Item ausgewählt werden und es kann eine Überschrift festgelegt werden.
- Mit den Zeilen 16 bis 18 will ich eigentlich erreichen, dass nur Gruppen (also vor allem Equipment) ausgewählt werden können. Leider funktioniert das nicht.
- In Zeile 23 wird festgelegt, dass als Header die eingegebene Überschrift, oder falls keine angegeben wurde, der Gerätename genutzt wird.
- In Zeile 24 wird die Temperatur-Ausgabe erzeugt, als Hauptinformation. (Mir ist nicht klar, warum ich da nicht "Temperatur:" schreiben kann, der Doppelpunkt wird moniert)
- Zeile 25 erzeugt die blaue Temperatur-Kurve im Hintergrund
- Zeile 26 und 27 konfigurieren den Effekt beim Anklicken der Card. Hinter actionAnalyserItems wird eine Array erwartet, daher die eckigen Klammern. Dafür sind auch mehrere Elemente möglich
- Die nächsten Zeilen sind recht üblich, auch hier darf ich meinen Text nicht mit einem Doppelpunkt versehen.
- Mit den Zeile 32 und 33 will ich erreichen, dass bei einer Luftfeuchtigkeit von mehr als 60 % der Hintergrund rot wird. Um die Zahlen vergleichen zu können muss von der Luftfeuchtigkeit die Einheit (%) entfernt werden, daher die Split-Funktion.
Homematic Heizungs-Thermostat
Von Thorsten habe ich die Ausgangsversion dieses Widgets bekommen, er hat sich dabei anregen lassen von dem Diskussionsstrang unter https://community.openhab.org/t/oh3-item-widget-switch-with-multiple-buttons/112671. Ich habe dann nur das Interface an meine Vorstellungen angepasst, so dass relativ wenige Angaben notwendig sind, wenn man es auf einer Page einbinden möchte. Zwingend ist nur die Auswahl des Gerätes selber.
Und hier das Listing zu dem Widget:
uid: Thermostat-Control
tags: []
props:
parameters:
- description: Titelzeile
label: Titel (wenn leer, dann Gerätename)
name: titel
required: false
type: TEXT
- context: item
description: Der Thermostat
label: Item
name: item
required: true
type: TEXT
timestamp: Jan 10, 2022, 5:35:40 PM
component: f7-card
config:
outline: false
noBorder: false
padding: true
noShadow: false
style:
--f7-card-margin-horizontal: 5px
--f7-card-content-padding-vertical: 0px
--f7-card-content-padding-horizontal: 16px
--f7-card-border-radius: 15px
--f7-card-box-shadow: 0px 5px 10px rgba(0,0,0,0.15)
--f7-card-header-font-size: 14px
--f7-card-header-font-weight: 600
slots:
content:
- component: oh-label-card
config:
noShadow: true
trendItem: =props.item+"_ActualTemperature"
action: analyzer
actionAnalyzerItems: =[props.item+"_ActualTemperature",props.item+"_SetTemperature", props.item+"_ValveState"]
item: =props.item+"_ActualTemperature"
title: "=(props.titel) ? props.titel : props.item"
icon: f7:thermometer
actionAnalyzerCoordSystem: time
vertical: false
footer: = "Ventil " + (items[props.item+"_ValveState"].state) + " / Batterie " + (items[props.item+"_BatteryState"].state)
- component: oh-stepper-card
config:
noShadow: true
color-theme: gray
item: =props.item+"_SetTemperature"
large: false
autorepeat: true
fill: false
noBorder: true
raised: true
small: true
round: true
min: 5
max: 30
step: 0.5
- component: f7-row
config:
class:
- padding-bottom
- padding-right
slots:
default:
- component: f7-col
slots:
default:
- component: oh-button
config:
title: Auto
action: toggle
actionItem: =(props.item+"_AutoMode")
actionCommand: ON
textColor: '=(items[props.item+"_ControlMode"].state === "AUTO-MODE") ? white : red'
fill: '=(items[props.item+"_ControlMode"].state === "AUTO-MODE") ? true : false'
text: Auto
- component: f7-col
slots:
default:
- component: oh-button
config:
title: Manu
action: toggle
actionItem: =(props.item+"_ManuMode")
actionCommand: =(items[props.item+"_SetTemperature"].state)
textColor: '=(items[props.item+"_ControlMode"].state === "MANU-MODE") ? white : red'
fill: '=(items[props.item+"_ControlMode"].state === "MANU-MODE") ? true : false'
text: Manu
- component: f7-col
slots:
default:
- component: oh-button
config:
title: Boost
action: toggle
actionItem: =(props.item+"_BoostMode")
actionCommand: ON
textColor: '=(items[props.item+"_ControlMode"].state === "BOOST-MODE") ? white : red'
fill: '=(items[props.item+"_ControlMode"].state === "BOOST-MODE") ? true : false'
text: Boost
Temperaturmessung mit Shelly 1 und Addon
Bisher fehlte mir immer eine Möglichkeit, die Temperaturen des Heizungskreislaufes zu verfolgen. Erst jetzt habe ich wahrgenommen, dass es dafür bei Shelly die notwendigen Teile gibt. Am übersichtlichsten sind die entsprechenden Teile bei https://shellyparts.de zu finden. Hier gibt es auch in 3D gedruckte Gehäuse dafür zu kaufen.
Der Shelly 1 ist eigentlich ein Relais, er lässt sich aber mit dem Addon um Sensoren erweitern, bei mir sind das Temperaturfühler DS18B20.
Die Temperaturfühler arbeiten von -55 °C bis +125 °C, die Kabelbelegung ist
1-> rot: VCC 3-> schwarz: GND 2-> gelb: Data
Das Addon wird auf das Relais aufgesteckt und dann kann man an den Kabeln Sensoren anschließen. Da die Sensoren alle parallel geschaltet werden, sind Klemmen dabei um bis zu drei Sensoren anschließen zu können.
Dazu muss man vorher die längliche Abdeckung entfernen.
Es bietet sich aber an, die Stromversorgung vorher anzuschließen, da das Addon einrastet und nur mühsam wieder zu lösen ist.
Unter der kleineren Abdeckung befindet sich eine Steckbrücke, mit der man die Stromversorgung des Relais auf 12 V Gleichstrom umstellen kann. Da ich mit dem Shelly nicht schalten, sondern nur messen will, habe ich hier die Umstellung vorgenommen und von einer alten Fritz!Box das 12V Netzteil angeschlossen.
Es ist relativ schwierig die Steckbrücke aus dem Gehäuse zu bekommen, da die Öffnung so eng ist, dass man mit einer Pinzette kaum greifen kann. Ich habe mir eine Büroklammer zurechtgebogen und die Brücke damit herausbekommen.
Bei der Firma Shellyparts gibt es auch ein Gehäuse für den gesamten Aufbau.
Mit dem Gehäuse kommen auch drei neue Klemmen, mit drei Anschlüssen, da die vierer Klemmen, die zum Addon gehören, zu lang für das Gehäuse sind. Man muss also im Zweifelsfall in einen der Anschlüsse jeweils zwei Kabel klemmen. Das Gehäuse sieht auch keine Zugentlastung vor, ich habe mir mit zwei Kabelbindern geholfen, die das Herausziehen der Kabel erschweren.
Kosten ca. 50€ (Stand Dezember 2022):
- Shelly1 12,98 €
- Addon 10,98€
- 3 DS18B20 8,94 €
- Gehäuse 8,98 €
- Netzteil 9,32 € (von Amazon)
Einbindung ins eigene WLAN
Die Einbindung ins WLAN ist bei Shelly-Geräten nicht immer unproblematisch, das betrifft aber vor allem die batteriebetriebenen Geräte. Hier ist das einfacher, mit einem Tablet oder Handy auf den Acces-Point des Shelly verbinden und dann im Browser die IP-Adresse 192.168.33.1 aufrufen.
In dem Screenshot sieht man schon den Zustand mit zwei angeschlossenen Sensoren.
Im ersten Schritt bindet man das Gerät über Internet & Security -> WIFI MODE - CLIENT ins lokale WLAN ein.
Nach diesem Schritt kann man das Gerät dann mit einer IP-Adresse im eigenen WLAN erreichen. Welche das ist, das kann man in der Regel im Router nachschauen.
Wenn das geklappt hat, dann kann man den WIFI MODE - ACCESS POINT deaktivieren.
Was man nach der Einbindung auf alle Fälle machen sollte, ist ein Update Settings -> FIRMWARE UPDATE auf die neueste Version.
Einbindung in OpenHAB
In OpenHAB war die Einbindung recht einfach, das Shelly-Binding war bei mir ja schon längere Zeit vorhanden. Man geht dann auf Things -> + -> Shelly-Bindung und bekommt eine Reihe der unterstützten Geräte zur Auswahl.
Das Scannen hat bei mir nichts ergeben, aber das gesuchte Gerät ist ja auch an der ersten Stelle zu finden.
Hier muss man eigentlich nur die IP-Adresse des Gerätes angeben und eventuell das Label anpassen, danach ist das Gerät innerhalb von OpenHAB verfügbar.
Auch die installierten Sensoren stehen dann automatisch zur Auswahl zur Verfügung.
Aber hier gibt es ein blödes Problem. Die Temperatur-Sensoren heißen alle gleich und sind damit nur mühsam zu individualisieren. Es gibt dafür folgende Möglichkeiten:
- Man schließt die Sensoren nacheinander an und übernimmt sie dann auch entsprechend nacheinander in das Modell. Dabei gibt man dann jeweils dem neu hinzugekommenen Sensor einen Namen, der von der Vorgabe abweicht. Eine Nummerierung langt hier, also Temperatur1, Temperatur2, Temperatur3, später lassen sich die Sensoren umbenennen, nur solange sie alle den gleiche Namen haben haut das nicht hin.
- Nach dem Einbinden des Shelly-Gerätes (gleich einen individuellen Namen vergeben) importiert man die Sensoren nicht gleich ins Modell, sondern geht über Things -> Shelle 1... -> Channels -> jeweiliger Sensor -> Add Linkt to item hierbei kann man dann jeweils individuell einen Namen vergeben. Wenn man dann über Create Points from Thing die Sensoren im Modell zum Shelly 1 hinzufügt und dann den im vorherigen Schritt gewählten Namen angibt, dann bekommt man die Warnung, dass der Name schon existiert. Aber genau so soll es sein.
Label-Card
Hier mein erster Versuch für eine Label-Card. Am wichtigsten ist mir hierbei das Diagramm mit dem Temperatur-Verlauf:
component: oh-label-card
config:
title: Heizkreislauf-Temperaturen
label: = "Rücklauf-Temperatur " + items.Shelly1Addon_Temperatur1.state
subtitle: = "Temperatur " + items.Shelly1Addon_Temperatur2.state
item: Shelly1Addon_Temperatur1
footer: = "Vorlauf-Temperatur " + items.Shelly1Addon_Temperatur2.state
trendItem: Shelly1Addon_Temperatur2
action: analyzer
actionAnalyzerItems:
- Shelly1Addon_Temperatur1
- Shelly1Addon_Temperatur2
Am liebsten würde ich im Diagramm noch die Differenz der Temperaturen darstellen, aber ich habe bisher noch nicht die entsprechenden Möglichkeiten für berechnete Werte heraus gefunden.
Anzeige der Temperatur-Differenz
Die Anzeige nur von Vorlauf- und Rücklauf- Temperatur allein fand ich nicht so hilfreich. Ich will auch die Temperatur-Differenz mit im Diagramm haben.
Dazu habe ich ein Item angelegt: Einstellungen -> Items -> + -> Add item : HeizkreisTemperaturDiff
Um das Item mit Inhalten zu versorgen dient eine Rule:
die immer dann, wenn sich einer der beiden Messwerte ändert, das folgende Script aufruft:
oder in Textform:
var Vorlauf, Ruecklauf, Differenz;
Vorlauf = itemRegistry.getItem('Shelly1Addon_Temperatur2').getState();
Ruecklauf = itemRegistry.getItem('Shelly1Addon_Temperatur1').getState();
Differenz = Vorlauf - Ruecklauf;
Differenz = Differenz * 10;
Differenz = Math.round(Differenz);
Differenz = Differenz / 10;
events.sendCommand('HeizkreisTemperaturDiff', Differenz);
Und dann muss natürlich noch die Label-Card angepasst werden
component: oh-label-card
config:
title: ="Vorlauf-Temperatur " + items.Shelly1Addon_Temperatur2.state
label: = "Temperatur-Differenz " + items.HeizkreisTemperaturDiff.state
subtitle: = "Temperatur " + items.Shelly1Addon_Temperatur2.state
item: Shelly1Addon_Temperatur1
footer: = "Rücklauf-Temperatur " + items.Shelly1Addon_Temperatur1.state
trendItem: Shelly1Addon_Temperatur2
action: analyzer
actionAnalyzerItems: =["Shelly1Addon_Temperatur1", "Shelly1Addon_Temperatur2", "HeizkreisTemperaturDiff"]
Einbindung von Shelly Duo
Ich habe mir vor ein paar Tagen die Shelly Duo RGBW Smart Home LED Glühbirne Dimmbar E27 gekauft. Diese LED-Lampe wird vom aktuellen Shelly-Binding unterstützt, aber die Unterstützung ist teilweise seltsam. Nach der Einbindung habe ich einen Channel für den Betrieb, also den Power Switch vermisst. Durch einen Hinweis im OpenHAB-Forum bin ich darauf gekommen, dass man dazu die Lampe auf den Color-Betrieb einstellen muss. Nach etwas Wartezeit tauchte dieser Channel beim Thing auch auf und ich konnte ihn in mein Model einbinden. Auch nach dem Zurückstellen auf Weiß blieb der Channel erhalten und nutzbar.
Hilfreiche Links
- https://phenx.de/openhab-3-auf-raspberry-installieren-openhabian/
- https://www.laub-home.de/wiki/Raspberry_Pi_mit_openHAB_als_Smart_Home_Schaltzentrale
- https://shelly-api-docs.shelly.cloud/gen1/ API-Doku für Shelly Generation 1
- https://shelly-api-docs.shelly.cloud/gen2/ API-Doku für Shelly Generation 2