hier möchte ich nun mein Projekt der automatischen Verschattung vorstellen.
Vorweg: Der Urheber der Rule ist Florian Schießl. Ihm möchte ich auch hiermit danken, das ich mein Projekt hier veröffentlichen darf.
https://www.forwardme.de/2018/03/12/ele ... -openhab2/
Ebenso danke ich auch Udo hier aus dem Forum für die ein oder andere "Fachfrage"
Was wird alles benötigt ?
Software:
OpenHab 2.4
MqTT
Weather Binding
Astro Binding
OpenHab Cloud Connector
Hardware:
Shelly 2.5 Rolladenaktor
Was kann das Ganze ?
Die Rule kann abhängig vom Sonnenstand, Temperatur und Wolken über einen elektrischen Rolladen ein Zimmer Verschatten.
Zusätzlich wird zu Beginn und Ende der Verschattung eine Pushnachricht versendet.
Wie es sich mit Sonnenrichtung und Sonnenhöhe so verhält, findet man hier:
https://www.sunearthtools.com
Das ganz ist natürlich individuell konfigurierbar.
Und funktioniert folgendermaßen:
*Es soll eine Schaltung abhängig von Sonnenwinkel und Sonnenhöhe erfolgen.
Natürlich soll das aber erst ab einer bestimmten Außentemperatur greifen, denn im Winter sind wir dann doch eher froh über das Licht und wenn Regen oder auch nur Wolken am Himmel stehen, ist eine Beschattung auch nicht notwendig. Ist der Rolladen bereits weiter geschlossen, als er geschlossen werden soll, soll nichts passieren.
Ebenso soll nichts passieren, der Rolladen beim Versuch ihn hochzufahren einen inzwischen veränderten Zustand hat.
[*Original Beschreibung von Florian]
Hier zunächst die entsprechende Items Datei: (Exemplarisch für die Westseite unseres Hauses)
Code: Alles auswählen
Group gruppeRolladen_West
// Konfiguration Rollo-Automatik West
Switch Rolloautomatik "Rollo-Automatik aus/an"
Switch Rolloautomatik_oeffnen "Rolladen öffnen aus/an"
Number Rolloautomatik_zielwert "Schließen auf [%d Prozent]"
Number Rolloautomatik_temp_min "Temperatur größer [%d °C]"
Number Rolloautomatik_wolken_max "Bewölkung weniger als [%d Prozent]"
Number Rolloautomatik_azimuth_start "Sonnenrichtung größer gleich [%d °]"
Number Rolloautomatik_elevation_ende "Sonnenhöhe kleiner gleich [%d °]"
DateTime Rolloautomatik_start_last "Letzte Ausführung (Rollo ab)"
DateTime Rolloautomatik_ende_last "Letzte Ausführung (Rollo hoch)"
Code: Alles auswählen
var boolean log = true
rule "Rollos West abfahren"
when Item Azimuth changed
then
val String logPrefix = 'Rolloautomatik (Rollo West ab) - '
if (log) logInfo('rules', logPrefix + 'Regel wurde gestartet')
var String timeLast = 'xxxx-xx-xx'
if (Rolloautomatik_start_last.state == NULL) {
if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
} else {
timeLast = Rolloautomatik_start_last.state.toString().substring(0,10)
}
var String timeNow = now.toString().substring(0,10)
if (Rolloautomatik.state == ON) {
if (timeNow != timeLast) {
if (Azimuth.state > Integer::parseInt(Rolloautomatik_azimuth_start.state.toString())) {
if (AussenTemp.state > Integer::parseInt(Rolloautomatik_temp_min.state.toString())) {
if (LocalWeatherAndForecast_Current_Cloudiness.state <= Integer::parseInt(Rolloautomatik_wolken_max.state.toString())) { if (Elevation.state > Integer::parseInt(Rolloautomatik_elevation_ende.state.toString())) {
// Rollos runterfahren
if (log) logInfo('rules', logPrefix + 'Rollos werden abgefahren')
gruppeRolladen_West.members.forEach[i|
if (i.state <= Integer::parseInt(Rolloautomatik_zielwert.state.toString())) {
if (log) logInfo('rules', logPrefix + 'Fahre Rolladen auf ' + Rolloautomatik_zielwert.state.toString() + '%: ' + i.name)
i.sendCommand(Integer::parseInt(Rolloautomatik_zielwert.state.toString()))
} else {
if (log) logInfo('rules', logPrefix + 'Rolladen ist bereits weiter geschlossen (' + i.state.toString() + '%) als er geschlossen werden sollte und wird daher ignoriert')
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
sendBroadcastNotification("Verschattung Westseite aktiv") //Pushnachricht
Rolloautomatik_start_last.postUpdate(now.toString())
} else {
if (log) logInfo('rules', logPrefix + 'Elevation für wieder abfahren (' + Rolloautomatik_elevation_ende.state.toString() + ') ist groesser als aktuelle (' + Elevation.state.toString() + ')')
}
} else {
if (log) logInfo('rules', logPrefix + 'Mindestbewoelkung (' + Rolloautomatik_wolken_max.state.toString() + ') wurde unterschritten (' + LocalWeatherAndForecast_Current_Cloudiness.state.toString() + ')')
}
} else {
if (log) logInfo('rules', logPrefix + 'Mindest-Temperatur (' + Rolloautomatik_temp_min.state.toString() + ') wurde nicht erreicht durch aktuelle Temperatur (' + AussenTemp.state.toString() + ')')
}
} else {
if (log) logInfo('rules', logPrefix + 'Azimuth (' + Azimuth.state.toString() + ') hat noch nicht Schwellwert (rolloautomatik_azimuth_start.state.toString()) erreicht')
}
} else {
if (log) logInfo('rules', logPrefix + 'Automatik heute bereits einmal gelaufen, wird daher ignoriert')
}
} else {
if (log) logInfo('rules', logPrefix + 'Beende, da Automatik generell nicht aktiv')
}
end
rule "Rollo West wieder öffnen"
when Item Elevation changed
then
val String logPrefix = 'Rolloautomatik (Rollo West hoch) - '
if (log) logInfo('rules', logPrefix + 'Regel wurde gestartet')
var String timeLastEnde = 'xxxx-xx-xx'
if (Rolloautomatik_ende_last.state == NULL) {
if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
} else {
timeLastEnde = Rolloautomatik_ende_last.state.toString().substring(0,10)
}
var String timeLastStart = 'yyyy-yy-yy'
if (Rolloautomatik_start_last.state == NULL) {
if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
} else {
timeLastStart = Rolloautomatik_start_last.state.toString().substring(0,10)
}
var String timeNow = now.toString().substring(0,10)
if (Rolloautomatik_oeffnen.state == ON) {
if (Elevation.state <= Integer::parseInt(Rolloautomatik_elevation_ende.state.toString())) {
if (timeLastStart == timeNow) {
if (timeLastEnde != timeNow) {
// Rollos wieder hoch
if (log) logInfo('rules', logPrefix + 'Rollos werden hinaufgefahren')
gruppeRolladen_West.members.forEach[i|
if((Rolloautomatik_zielwert.state as Number).intValue <= (i.state as Number).intValue +5 && (Rolloautomatik_zielwert.state as Number).intValue >= (i.state as Number).intValue -5) {
if (log) logInfo('rules', logPrefix + 'Fahre Rolladen auf 0%: ' + i.name)
i.sendCommand(0)
} else {
if (log) logInfo('rules', logPrefix + 'Fahre Rolladen nicht auf 0%, da dieser zwischenzeitlich manuell verändert wurde: ' + i.name)
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
sendBroadcastNotification("Verschattung Westseite beendet") //Pushnachricht
Rolloautomatik_ende_last.postUpdate(now.toString())
} else {
if (log) logInfo('rules', logPrefix + 'Beende, da heute bereits ein automatisches Wiederhochfahren stattfand')
}
} else {
if (log) logInfo('rules', logPrefix + 'Beende, da heute noch keine Ausführung stattfand. Demzufolge kann auch kein automatisches Öffnen gewollt sein')
}
} else {
if (log) logInfo('rules', logPrefix + 'Beende, da Elevation (' + Elevation.state.toString() + ') nicht kleiner der eingestellten Elevation (' + Rolloautomatik_elevation_ende.state.toString()+ ') war')
}
} else {
if (log) logInfo('rules', logPrefix + 'Beende, da Automatik generell nicht aktiv')
}
end
Wichtig ist: Alle Rolläden müssen der Gruppe gruppeRolladen_West zugeordnet werden.
Ist zum errechneten Zeitpunkt des wieder-hinauf-fahrens ein Rolladen in einem anderen Status, als er hätte sein müssen, als er heruntergefahren wurde, wird er nicht automatisch wieder hochgefahren.
Und hier der relevante Teil aus der Sitemap:
Code: Alles auswählen
Text label="Konfiguration Verschattung West" icon="rollershutter" {
Frame label="Aktivieren der Automatik" {
Switch item=Rolloautomatik
Setpoint item=Rolloautomatik_zielwert minValue=0 maxValue=100 step=1
}
Frame label="Rollo ab, wenn..." {
Setpoint item=Rolloautomatik_temp_min minValue=0 maxValue=35 step=1
Text item=AussenTemp label="Temperatur Aussen [%.1f °C]" icon="temperature" valuecolor=[>27="red",>20="orange",>10="purple",>5="green",<=5="blue"]
Setpoint item=Rolloautomatik_wolken_max minValue=0 maxValue=100 step=1
Text item=LocalWeatherAndForecast_Current_Cloudiness icon="sun_clouds" label="Bewölkung [%.0f %%]"
Setpoint item=Rolloautomatik_azimuth_start minValue=0 maxValue=360 step=1
Default item=Azimuth icon="niveau" label="Azimuth"
}
Frame label="Rollo hoch, wenn..." {
Switch item=Rolloautomatik_oeffnen
Setpoint item=Rolloautomatik_elevation_ende minValue=-20 maxValue=60 step=1
Default item=Elevation label="Elevation"
So kann das in der Sitemap aussehen: