Hello OpenHABers,
here i want to share my Project to have a automatic shading with
OpenHab, Astro, OpenWeather and MqTT.
First of all: The author of the Rule is Florian Schießl. I would also like to thank him for allowing me to publish my project here. His origin project can be found here:
https://www.forwardme.de/2018/03/12/elektrischen-rolladen-abhaengig-von-sonnenstand-und-wetter-steuern-lassen-mit-openhab2/
What is needed?
Software:
OpenHab 2.4
MQTT
Weather binding installed
Astro Binding installed
OpenHab Cloud Connector
Hardware:
RaspBerry 3
Shelly 2.5 shutter actuator
What is the whole thing doing?
Depending on the position of the sun, temperature and clouds, the rule can shade a room via an electric shutter.
In addition, a push message is sent at the beginning and end of the shading.
How it behaves with sun direction and sun altitude, you will find here:
https://www.sunearthtools.com
The whole thing is of course individually configurable.
And works like this:
It should be a circuit depending on sun angle and altitude.
Of course, this should take effect but only from a certain outside temperature, because in winter we are then rather happy about the light and if rain or even clouds are in the sky, a shading is not necessary. If the shutter is already closed when it is to be closed, nothing should happen.
Likewise, nothing should happen, the shutter in trying to open it has now changed state.
Here first the corresponding item file: (Exemplary for the west side of our house)
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)"
Here is the rule:
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
The rule asks whether the automatic system has generally been running, possibly already running, whether the temperature, cloudiness and current status of the blinds are suitable and if so they will be driven down.
Important: All blinds must be assigned to group groupRolladen_West.
If a shutter is in a different state than it should have been when it was shut down at the calculated time of going back up, it will not automatically open.
And here the relevant part from the sitemap:
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"
It look like this in the sitemap:
Have Fun!