Rollo mit Shelly 2.5 und OpenWeatherMap Binding in OH3 wetterabhängig steuern

Geflasht oder ungeflasht ...

Moderator: seppy

Antworten
MrWilson
Beiträge: 2
Registriert: 1. Jul 2021 15:01

Rollo mit Shelly 2.5 und OpenWeatherMap Binding in OH3 wetterabhängig steuern

Beitrag von MrWilson »

Hallo liebe Community,

seit kurzem bin ich auch Besitzer meiner ersten Shelly (2.5) und wenn ich mein Vorhaben realisieren kann, dann kommen sehrbald noch ein paar weitere hinzu.

Aktueller Status: Ich habe die Shelly 2.5 als Rollosteuerung eingebaut und in der App aufgenommen. Dort habe ich eine Routine erstellt, die das Rollo täglich um 10 Uhr komplett öffnen und um 19 Uhr komplett schließen soll. Das funktioniert soweit tadellos.

Ziel: Was will ich mehr? Nunja, die Hausseite wird an wärmeren Tagen doch relativ warum und wenn das Rollo tagsüber "oben" ist, dann kommt doch viel Wärme ins Haus trotz Dreifachverglasung. Ich würde daher gerne einstellen können, dass das Rollo nur dann wie oben beschrieben geöffnet wird, wenn die erwartete Temparatur für den Tag nicht über 25°C steigen soll. Daher habe ich mir OpenHAB angesehen und in der neusten Version (OH3) via Docker aufgesetzt. Das Shelly Binding war ebenfalls schnell installiert und das Gerät erkannt. Da ich keine Wetterstation besitze und mir auch keine anschaffen möchte, habe ich auch das OpenWeatherMap Binding installiert und meinen API Key dort hinterlegt. Wetter kann also eingelesen werden. Wo hakt es nun?

Ich habe mir diverse Videos und Tutorials durchgelesen, wie man OpenWeatherMap mit Shelly in OH verknüpft. Ein Großteil allerdings noch für OH2 via MQTT, was ich nicht möchte und mit OH3 auch nicht mehr brauche (?). Jetzt habe ich versucht mir selbst eine Regel zu basteln, die das Rollo morgens öffnet und abends schließt. Aber nur dann, wenn das Wetter (Außentemparatur) an dem Tag nicht über 25°C erwartet wird. Aber ich scheitere schon direkt am Anfang. Es gibt so unglaublich viele Möglichkeiten das in OH3 zu realisieren, dass ich einfach überfordert bin. Muss ich zB auch die Sensoren anpassen, wenn ich ein Rollo hochfahren will (und es dann schon ganz oben wäre... würde der Motor dann "überdrehen")? Ich habe einfach Angst etwas am Rollo kaputt zu machen, wenn ich es via Trial-and-Error ausprobiere. Und da dachte ich mir "Mensch, das ist so simpel, das hat doch bestimmt schon jemand anderes mal genau so gemacht!?".

Dennoch habe ich nun einmal angefangen rumzuprobieren und folgendes Skript erstellt:

Code: Alles auswählen

if (itemRegistry.getItem('Shelly25RollerSHSW25_Status').getState() == '0') {
  if (itemRegistry.getItem('Wetterinformationen_Aussentemperatur').getState() >= '25') {
    events.sendCommand('Shelly25RollerSHSW25_Steuerung0offen100geschlossen', '100');
  }
}
Leider passiert, wenn ich das Skript testweise ausführe, rein gar nichts. Auch kein Errorlog o.ä. in der Weboberfläche. Und ich habe den Wetterwert auf 10 geändert, damit es auch triggern würde bei aktuell 19 Grad ;)

Ich würde mal vermuten, dass ich den Wetterwert erst noch konvertieren muss, da er vermutlich in °C ankommt, das Skript aber eine einfache Zahl erwartet?

Dann habe ich folgende Rule erstellt:

Code: Alles auswählen

triggers:
  - id: "4"
    configuration:
      cronExpression: 0 0 10-19 * * ? *
    type: timer.GenericCronTrigger
conditions:
  - id: "1"
    configuration:
      itemName: Wetterinformationen_ForecastHours09_Temperature
      operator: ">="
      state: "25"
    type: core.ItemStateCondition
actions:
  - id: "2"
    configuration:
      itemName: RolloBadOG_Steuerung0offen100geschlossen
      command: DOWN
    type: core.ItemCommandAction
  - id: "3"
    configuration:
      itemName: RolloBadOG_Steuerung0offen100geschlossen
      state: "100"
    type: core.ItemStateUpdateAction
Aber auch wenn die Temparatur bei Weitem nicht auf 25 Grad steigen soll, dann fährt es trotzdem immer runter. Bin einfach zu blond.

Hat das evtl. jemand von euch schon mal so umgesetzt, oder hat ein paar Tipps, wie ich vorgehen sollte bzw. was ich falsch gemacht habe?

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Rollo mit Shelly 2.5 und OpenWeatherMap Binding in OH3 wetterabhängig steuern

Beitrag von udo1toni »

Herzlich willkommen :)

Grundsätzlich sollte das schon funktionieren.

Dein erstes Codebeispiel sieht nach JavaScript aus, hast Du das auch als Sprache ausgewählt? Gewöhnlich erstellst Du in OH3 eine Rule über die UI, dort musst Du dann auswählen, dass der Code JavaScript ist.

Der zweite Teil zeigt ja die Konfiguration einer solchen UI Rule als Code. Hier dürfte der limitierende Faktor das verwendete Item im "But only If" bereich sein (im Code heißt das schnöde "conditions").
Das Item ist an openWeatherMap gekoppelt, und openWeatherMap unterstützt UoM (kurz für Units of Measurement). Es gehört also eine Einheit zu der Zahl. Es kann gut sein, dass Du die Einheit einfach nur mit angeben musst, damit die Rule korrekt läuft (das habe ich aber noch nicht ausprobiert), es kann auch sein, dass Du die Einheit in einer ganz bestimmten Form schreiben musst.
Also statt 25 ein fach 25 °C schreiben und mal schauen, was passiert.

Oder Du schreibst die Rule in der DSL von openHAB :), dann allerdings wäre eine rules-Datei die bessere Wahl gegenüber der UI Rule.
Ich habe gerade keinen Zugriff auf mein System, kann Dir aber gerne heute Abend mal meine Rule dazu hier hochladen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

MrWilson
Beiträge: 2
Registriert: 1. Jul 2021 15:01

Re: Rollo mit Shelly 2.5 und OpenWeatherMap Binding in OH3 wetterabhängig steuern

Beitrag von MrWilson »

Danke, das wäre super. Das Vergleichen mit "25 °C" probiere ich mal so aus:

Code: Alles auswählen

  if (itemRegistry.getItem('Wetterinformationen_Aussentemperatur').getState() >= '25 °C') {
Da bin ich mir aber unsicher, ob der >= Operator damit klar kommt. Geschickter wäre es sicherlich, wenn ich die Wetterinformationen_Aussentemperatur von "XY.Z °C" nach "XY" konvertieren könnte?

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Rollo mit Shelly 2.5 und OpenWeatherMap Binding in OH3 wetterabhängig steuern

Beitrag von udo1toni »

Ah. Da habe ich mich vielleicht etwas unklar ausgedrückt. Das mit dem Vergleich und einfach °C dahinter schreiben war auf die UI Rule bezogen (die zusammengeklickt war)
In den DSL Rules gibt man die Einheit mit der Pipe an:

Code: Alles auswählen

if(Wetterinformationen_Aussentemperatur.state > 25 | °C)
Der Witz dabei ist, ich könnte auch

Code: Alles auswählen

if(Wetterinformationen_Aussentemperatur.state > 77 | °F)
oder

Code: Alles auswählen

if(Wetterinformationen_Aussentemperatur.state > 298.15 | K)
schreiben, alle drei Varianten funktionieren und lösen bei Temperaturen oberhalb 25 °C aus. Vielleicht wird die Temperatur von openweathermap sogar in °F geliefert. openHAB gibt sie aber in °C aus, weil das metrische System ausgewählt ist. Das ist der große Benefit von UoM. UoM sollte auch in JavaScript uneingeschränkt verfügbar sein.

Meine Rules zu der Beschattung sehen so aus:

Code: Alles auswählen

rule "update Schatten"
 when
    Time cron "0 55 6 * * ?" // täglich um 06:55 Uhr
 then
    maxTemp = 0
    gOWM.members.filter[ i | // alle Items von OWM in einer Gruppe
        i.name.contains("Temperature") && i.name.contains("Fc") && (i.state instanceof Number)]. // alle mit Temp.. und Fc im Namen mit gültigem Wert
        forEach [ j | // für jedes dieser Items
            if((j.state as Number).floatValue > maxTemp) // Falls über maxTemp
                maxTemp = (j.state as Number).floatValue // übernimm den Wert nach maxTemp
            logInfo("schatten", "{} ist {}, Maximum ist {}",j.name,j.state,maxTemp)
        ]
    if (maxTemp > 23) // Falls maxTemp über 23
        Schatten.postUpdate(ON) // aktiviere Beschattung
    else // ansonsten
        Schatten.postUpdate(OFF) // deaktiviere Beschattung
end

rule "Beschattung" // Mai - September
 when
    Time cron "0 31 8 * 5-9 ?"
 then
    if(Schatten.state==ON) {
        GS_C1?.members.forEach(Shutter|Shutter.sendCommand(75))					// Laura
        GS_C2?.members.forEach(Shutter|Shutter.sendCommand(60))					// Matty
        GS_Bath?.members.forEach(Shutter|Shutter.sendCommand(75))				// Bad
        RollGruppe4_Ch1.sendCommand(100)										// Eltern
        Virtuelle_Scene2.sendCommand(0)											// Wohnzimmer
        Schatten_aktiv.postUpdate(ON)
    }
end

rule "Beschattung aus"
 when 
    Item Elevation changed 
 then
    logDebug("Beschattung","Elevation Trigger {}",Elevation.state)
    if(Schatten_aktiv.state != ON) return;

    logDebug("Beschattung","Shadow {}",Schatten_aktiv.state)
    if (!((previousState as Number).floatValue >11.0 && (Elevation.state as Number).floatValue <= 11.0)) return;

    logDebug("Beschattung","Elevation old {} new {}",previousState,Elevation.state)
    Schatten_aktiv.postUpdate(OFF)
    if (now.plusHours(8).getMinuteOfDay > 12*60) return;

    Virtuelle_Scene2.sendCommand(1)
    GS_Bath?.members.forEach(Shutter|Shutter.sendCommand(0))
    Schatten_aktiv.postUpdate(OFF)
    if (now.getHourOfDay < 20){
        GS_C1?.members.forEach(Shutter|Shutter.sendCommand(0))
        GS_C2?.members.forEach(Shutter|Shutter.sendCommand(0))
        RollGruppe4_Ch1.sendCommand(0)
    }
end
Die beteiligten Items bezüglich Temperatur:

Code: Alles auswählen

Number:Temperature     WetterDa_Fc06Temperature     "Temperatur + 6h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours06#temperature"}
Number:Temperature     WetterDa_Fc09Temperature     "Temperatur + 9h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours09#temperature"}
Number:Temperature     WetterDa_Fc12Temperature     "Temperatur +12h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours12#temperature"}
Number:Temperature     WetterDa_Fc15Temperature     "Temperatur +15h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours15#temperature"}
Number:Temperature     WetterDa_Fc18Temperature     "Temperatur +18h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours18#temperature"}
Number:Temperature     WetterDa_Fc21Temperature     "Temperatur +21h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours21#temperature"}
Number:Temperature     WetterDa_Fc24Temperature     "Temperatur +24h"                       (gOWM)  {channel="openweathermap:weather-and-forecast:api:da:forecastHours24#temperature"}
Switch      Schatten            "Beschattung aktivieren [%s]" (All) 
Switch      Schatten_aktiv      "Beschattung aktiv [%s]" (All)
Ich hole also um 6:55 Uhr täglich die Forecast Werte der nächsten 24 Stunden für die Temperatur. Ich bestimme den höchsten Wert, ansclhießend prüfe ich auf den Schwellwert und speichere das Ergebnis im Item Schatten.
Anschließend lasse ich meine Rollläden um 8:31 Uhr (in den Monaten Mai bis September) nur dann in Beschattungsposition fahren, wenn das Item Schatten auf ON steht. Wird ide Beschattungsposition angefahren, merkt sich das System, dass dies der Fall ist (über das Item Schatten_aktiv).
Die letzte Rule kümmert sich darum, die Läden wieder hochzufahren, wenn die Sonne unter 11° Elevation sinkt (natürlich nur, wenn Schatten_aktiv auf gesetzt ist).

Meine Rule ist natürlich nur eine sehr minimalistische Beschattungsautomatik, genügt unseren Ansprüchen aber vollkommen. Unser Haus steht mitten im "Dorf", das heißt, es gibt drumherum viele Reflexionsflächen, die für "zu viel" Licht sorgen.
Ich schneide die Einheit im Beispiel ab:

Code: Alles auswählen

maxTemp = (j.state as Number).floatValue
Der Status von j wird nach Number gecastet. Damit steht die Methode .floatValue zur Verfügung, die den Wert nach Float konvertiert.
Das Casting funktioniert aber nur, wenn auch ein gültiger Zahlenwert vorliegt, deshalb ist es eesenziell, vorher zu prüfen, ob j.state auch vom Typ Number ist. Das mache ich vorher im Listenfilter:

Code: Alles auswählen

(i.state instanceof Number)
Nicht verwirren lassen! Alle Elemente, die durch j symbolisiert werden, gehören auch zu denen, die mit i symbolisiert werden, das ist nur der Optik wegen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten