Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
-
- Beiträge: 4
- Registriert: 24. Apr 2020 07:39
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Vielen Dank für den Input zum Logging. Was das genau in der Rule bewirkt hat war mir bewusst. Mich hat es nur gewundert, dass es wohl nicht mehr mit neueren openhab Versionen funktioniert. @udo1toni Danke für den Tipp mit vscode und openhab. Das nutze ich auch schon, nur vll sollte ich auch die Instanz in den Settings hinterlegen an der ich gerade arbeite Aber ich debugge dann jetzt mal genauer.
-
- Beiträge: 4
- Registriert: 24. Apr 2020 07:39
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Das Debugging mit vscode war extrem hilfreich! Danke dafür.
Jetzt habe ich nur noch ein kleines Problem. Für die Items AutoShading_Temp_diff, AutoShading_Cloudiness_Hyst, AutoShading_Rain_min sind bei mir NULL. Mir fehlt also die Rule zur Berechnung dieser Werte. @Cyrelian kannst du mir deine Rule dafür posten?
Edit:
Hat sich erledigt
Jetzt habe ich nur noch ein kleines Problem. Für die Items AutoShading_Temp_diff, AutoShading_Cloudiness_Hyst, AutoShading_Rain_min sind bei mir NULL. Mir fehlt also die Rule zur Berechnung dieser Werte. @Cyrelian kannst du mir deine Rule dafür posten?
Edit:
Hat sich erledigt
-
- Beiträge: 4
- Registriert: 24. Apr 2020 07:39
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
So letztes Problem
Leider bewegen sich die Rollladen noch nicht. Ich habe meine Rollläden entsprechenden in Gruppen gesteckt. Beispiel gruppeRolloWest beinhaltet "Rollo_KiziWest_Percent".
Laut dem nachfolgende Code
sollte er in die Funktion
gehen. Laut openhab.log passiert das auch aber es bewegt sich nichts. Ich vermutet das hat etwas mit dieser Map zu tun. Daher die Frage zu den Strings in dieser Map. Ich habe dort meine Rollläden Items eingetragen. Sollte ja richtig sein, oder? Und was ich nicht verstehe ich das "GroupItem shutter". Ist das eine neue Gruppe die dynamisch erstellt wird? Ich habe nämlich keine Gruppe "shutter" bei mir in Openhab. Ich habe eine andere Gruppe die alle Rollläden beinhaltet (gruppeRollo).
Hier der ganze Code, falls das einfacher zu verstehen ist:
EDIT: Klappt nun.
Leider bewegen sich die Rollladen noch nicht. Ich habe meine Rollläden entsprechenden in Gruppen gesteckt. Beispiel gruppeRolloWest beinhaltet "Rollo_KiziWest_Percent".
Laut dem nachfolgende Code
Code: Alles auswählen
//Azimuth ist größer als 181° (WEST)
if (!isActiveWest) {
if ((astro_azimuth.state as Number).floatValue > (closingAzimuth_west)) {
logInfo( logPrefix, "Verschattung für Rollläden WEST")
isActiveWest = shadingStart.apply(gruppeRolloWest)
return;
}
} else {
logInfo(logPrefix, "Verschattung für Rollläden WEST bereits aktiviert")
}
Code: Alles auswählen
val shadingStart = [GroupItem shutter |
val String logPrefix = "Verschattung aktivieren - "
val Map<String, Number> targetHights = newHashMap (
// "KuecheRollladenTuer" -> 58,
// "SchlafzimmerRollladenTuer" -> 100,
// "BadezimmerRollladen" -> 55,
// "WohnzimmerRollladenEsstisch" -> 65,
"Rollo_KiziWest_Percent" -> 50,
"Rollo_KiziSued_Percent" -> 50
)
Hier der ganze Code, falls das einfacher zu verstehen ist:
Code: Alles auswählen
// Values und Variablen für die Verschattung
//val Number blindClosed = 100
//val Number blindOpen = 0
//val Number blindTranslucent = 35
import java.util.Map
var Number closingAzimuth_west = 181
var Number closingAzimuth_south = 111
var Number closingAzimuth_east = 65
var Number closingCloudiness = 20
val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde
var Number openingTemperature = 22
val Number temperatureHysteresis = 4 //Temperaturabfall von min. 4 Grad in der letzten Stunde
val Number minPrecip = 5 //die Mindestmenge an Regen in der letzten Stunde
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
/* ------------- Verschattung FUNKTIONEN --------------------
*/
//------------- Verschattung starten --------------------
val shadingStart = [GroupItem shutter |
val String logPrefix = "Verschattung aktivieren - "
val Map<String, Number> targetHights = newHashMap (
// "KuecheRollladenTuer" -> 58,
// "SchlafzimmerRollladenTuer" -> 100,
// "BadezimmerRollladen" -> 55,
// "WohnzimmerRollladenEsstisch" -> 65,
"Rollo_KiziWest_Percent" -> 50,
"Rollo_KiziSued_Percent" -> 50
)
if ((Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
logInfo ("Lambda", logPrefix, "Mindesttemperatur von ({}) wurde nicht erreicht. Aktuelle Temperatur ({}) ", AutoShading_Temp_min.state, Temperature.state)
return false;
}
if ((Clouds.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) {
//if (log) logInfo ("Lambda", logPrefix, "Aktuelle Bewoelkung (" + Clouds.state.toString() + ") ueberschreitet den eingestellten Grenzwert von (" + AutoShading_Cloudiness_max.state.toString() + ")")
logInfo ("Lambda", logPrefix, "Aktuelle Bewoelkung ({}) ueberschreitet den eingestellten Grenzwert von ({})", Clouds.state, AutoShading_Cloudiness_max.state)
return false;
}
if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) {
//if (log) logInfo ("Lambda", logPrefix, "Elevation für das Beenden der Verschattung (" + AutoShading_Elevation_end.state.toString() + ") ist groesser als aktuelle (" + Elevation.state.toString() + ")")
logInfo ("Lambda", logPrefix, "Elevation für das Beenden der Verschattung ({}) ist groesser als aktuelle ({}) ", AutoShading_Elevation_end.state, Elevation.state)
return false;
}
// Rollladen werden geschlossen
logInfo ("Lambda", logPrefix, "Grenzwert wurden erreicht, Rollladen werden geschlossen")
shutter.members.forEach[ blind |
if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) {
logInfo ("Lambda", logPrefix, "Fahre Rollladen (" + blind.name.toString() + ") auf (" + targetHights.get(blind.name.toString()).intValue + ") %" )
blind.sendCommand(targetHights.get(blind.name.toString()).intValue)
//Pushnachricht versenden
//sendPushoverMessage(pushoverBuilder("Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %"))
} else {
logInfo ("Lambda", logPrefix, "Rollladen ist bereits weiter geschlossen (" + blind.state.toString() + "%) als er geschlossen werden sollte und wird daher ignoriert")
}
]
AutoShading_Start_last.postUpdate(now.toString())
return true;
]
//------------- Verschattung beenden -------------------
val shadingEnd = [GroupItem shutter |
val String logPrefix = "Verschattung deaktivieren - "
val Map<String, Number> targetHights = newHashMap (
// "KuecheRollladenTuer" -> 58,
// "SchlafzimmerRollladenTuer" -> 100,
// "BadezimmerRollladen" -> 55,
// "WohnzimmerRollladenEsstisch" -> 65,
"Rollo KiziWest" -> 50,
"Rollo KiziSued" -> 100
)
// Rollladen öffnen
logInfo ("Lambda", logPrefix, "Rollladen werden geoeffnet")
shutter.allMembers.forEach[blind|
if((blind.state as Number).intValue == targetHights.get(blind.name).intValue) {
logInfo ("Lambda", logPrefix, "Oeffne Rollladen: " + blind.name.toString())
blind.sendCommand(100)
//Pushnachricht versenden
//sendPushoverMessage(pushoverBuilder("Verschattung für (" + blind.name.toString() + ") beendet, Rollladen wird geöffnet."))
} else {
logInfo ("Lambda", logPrefix, "Rollladen: (" + blind.name.toString() + ") wird nicht geoeffnet, da dieser zwischenzeitlich manuell verändert wurde.")
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
AutoShading_End_last.postUpdate(now.toString())
//Variablen zurücksetzen
isActiveWest = false
isActiveEast = false
isActiveSouth = false
return true;
]
/* ------------- Verschattung RULES --------------------
*/
//------------- Verschattung starten --------------------
rule "Verschattung starten"
when
Item astro_azimuth changed
then
val String logPrefix = "Verschattung aktivieren - "
//Prüfung auf: Verschattungsautomatik an / ob es Tag ist / Präsenz / Jahreszeit
if ((AutoShading.state == ON && Daylight.state == ON) && (Jahreszeit.state== "SPRING" || Jahreszeit.state== "SUMMER")) {
if (AutoShading_Start_last.state === NULL) {
logInfo(logPrefix, "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_Start_last.postUpdate(now.minusDays(1).toString())
}
//var String timeNow = now.toString().substring(0,10)
//var String timeLastStart = AutoShading_Start_last.state.toString().substring(0,10)
// Items für Sitemap füllen
if (AutoShading_Azimuth_east == "NULL" || AutoShading_Azimuth_south == "NULL" || AutoShading_Azimuth_west == "NULL" ){
AutoShading_Azimuth_east.postUpdate(closingAzimuth_west)
AutoShading_Azimuth_south.postUpdate(closingAzimuth_south)
AutoShading_Azimuth_west.postUpdate(closingAzimuth_west)
AutoShading_Temp_diff.postUpdate(temperatureHysteresis)
AutoShading_Cloudiness_Hyst.postUpdate(cloudHysteresis)
AutoShading_Rain_min.postUpdate(minPrecip)
}
//Azimuth ist größer als 181° (WEST)
if (!isActiveWest) {
if ((astro_azimuth.state as Number).floatValue > (closingAzimuth_west)) {
logInfo( logPrefix, "Verschattung für Rollläden WEST")
isActiveWest = shadingStart.apply(gruppeRolloWest)
return;
}
} else {
logInfo(logPrefix, "Verschattung für Rollläden WEST bereits aktiviert")
}
//Azimuth ist größer als 111° (SÜD)
if (!isActiveSouth) {
if ((astro_azimuth.state as Number).floatValue > (closingAzimuth_south) && (astro_azimuth.state as Number).floatValue < (closingAzimuth_west)) {
logInfo(logPrefix, "Verschattung für Rollläden SÜD")
isActiveSouth = shadingStart.apply(gruppeRolloSouth)
return;
}
} else {
logInfo(logPrefix, "Verschattung für Rollläden SÜD bereits aktiviert")
}
//Azimuth ist größer als 65° (OST)
if (!isActiveEast) {
if ((astro_azimuth.state as Number).floatValue > (closingAzimuth_east) && (astro_azimuth.state as Number).floatValue < (closingAzimuth_south)) {
logInfo(logPrefix, "Verschattung für Rollläden OST")
isActiveEast = shadingStart.apply(gruppeRolloEast)
return;
}
} else {
logInfo(logPrefix, "Verschattung für Rollläden OST bereits aktiviert")
}
} else {
logInfo(logPrefix, "Verschattung wird nicht ausgeführt, da einer der folgenden Parameter matched: Verschattung deakiviert, es ist Nacht, Herbst oder Winter erkannt.")
}
end
//------------- Verschattung beenden --------------------
rule "Verschattung beenden"
when
Item Elevation changed
then
if ((AutoShading_end.state == ON && Daylight.state == ON) && (Jahreszeit.state=="SPRING" || Jahreszeit.state=="SUMMER")) {
val String logPrefix = "Verschattung deaktivieren - "
val boolean isRainLastHour = (Rain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
logInfo(logPrefix, "Rain " + isRainLastHour)
val boolean isCloudLastHour = (Clouds.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
logInfo(logPrefix, "Clouds " + isCloudLastHour )
val boolean isTemperature = ((Temperature.state as Number).intValue < (Temperature.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(temperatureHysteresis)))
logInfo(logPrefix, "Temperatur " + isTemperature)
if (AutoShading_End_last.state === NULL) {
logInfo(logPrefix, "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_End_last.postUpdate(now.minusDays(1).toString())
}
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow) {
logInfo(logPrefix, "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if (!isActiveWest && !isActiveEast && !isActiveSouth) {
logInfo(logPrefix, "Beende, da heute noch keine automatische Verschattung stattfand")
return;
}
if (isTemperature) {
logInfo(logPrefix, "Verschattung beenden, Temperaturabfall von min. ({})° erkannt", temperatureHysteresis)
shadingEnd.apply(gruppeRollo)
return;
}
if ((Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
logInfo(logPrefix, "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",Temperature.state, AutoShading_Temp_raise.state )
return;
}
if (isRainLastHour || isCloudLastHour) {
logInfo(logPrefix, "Verschattung beenden, Mindestregenmenge von ({}) mm oder druchschnittliche Bewölkung von ({}) % erreicht",minPrecip, cloudHysteresis)
shadingEnd.apply(gruppeRollo)
return;
}
if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) {
logInfo(logPrefix, "Beende, aktuelle Elevation ({}) ueberschreitet den eingestellten Grenzwert von ({}) ", Elevation.state, AutoShading_Elevation_end.state)
return;
}
if (isActiveWest || isActiveEast || isActiveSouth ) {
logInfo (logPrefix, "Verschattung beenden")
shadingEnd.apply(gruppeRollo)
return;
}
}
end
/* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt --------------------
*/
rule "Verschattung Variablen zurücksetzen"
when
Time cron "15 59 23 * * ?"
then
if (isActiveWest == true || isActiveEast == true || isActiveSouth == true) {
isActiveWest = false
isActiveEast = false
isActiveSouth = false
}
end
EDIT: Klappt nun.
-
- Beiträge: 35
- Registriert: 4. Jan 2019 22:09
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Erstmal vielen herzlichen Dank an ALLE die hier mitgewirkt haben, eine MEGA Projekt !!!
Habe sehr lange auf sowas gewartet und ich glaube ich bin kurz davor, dass es auch funktioniert
Leider will bei mir die Regel nicht:
hier die RULES Datei
Folgende Fehlermeldung bekomme ich:
Habe sehr lange auf sowas gewartet und ich glaube ich bin kurz davor, dass es auch funktioniert
Leider will bei mir die Regel nicht:
hier die RULES Datei
Code: Alles auswählen
// Values und Variablen für die Verschattung
//val Number blindClosed = 100
//val Number blindOpen = 0
//val Number blindTranslucent = 35
import java.util.Map
var Number closingAzimuth_east = 85
var Number closingAzimuth_south = 111
var Number closingAzimuth_west = 171
var Number closingAzimuth_north = 260
var Number closingCloudiness = 20
val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde
var Number openingTemperature = 22
val Number temperatureHysteresis = 4 //Temperaturabfall von min. 4 Grad in der letzten Stunde
val Number minPrecip = 5 //die Mindestmenge an Regen in der letzten Stunde
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
var boolean isActiveNorth = false
/* ------------- Verschattung FUNKTIONEN --------------------
*/
//------------- Verschattung starten --------------------
val shadingStart = [GroupItem shutter |
val String logPrefix = "Verschattung aktivieren - "
//var boolean log = true
val Map<String, Number> targetHights = newHashMap (
"Shutter_EG_Office" -> 74,
"Shutter_EG_Wohnen3" -> 64,
"Shutter_EG_Kueche2" -> 40,
"Shutter_EG_Wohnen1" -> 78,
"Shutter_EG_Wohnen2" -> 78,
"Shutter_EG_Technik" -> 73,
"Shutter_OG_HWR" -> 74
//"KuecheRollladenTuer" -> 58,
//"SchlafzimmerRollladenTuer" -> 100,
//"BadezimmerRollladen" -> 55,
//"WohnzimmerRollladenEsstisch" -> 65,
//"WohnzimmerRollladenTuer" -> 68,
//"WohnzimmerRollladenBalkon" -> 100
)
// Temperature.state wird durch weatherN_Temperature ausgetauscht !!! insgesamt 4x
//if ((Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
if ((weatherN_Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
//logInfo ("Lambda", logPrefix + "Mindesttemperatur von (" + AutoShading_Temp_min.state.toString() + ") wurde nicht erreicht. Aktuelle Temperatur (" + Temperature.state.toString() + ")")
logInfo ("Lambda", logPrefix + "Mindesttemperatur von ({}) wurde nicht erreicht. Aktuelle Temperatur ({}) ", AutoShading_Temp_min.state, weatherN_Temperature.state)
return false;
}
if ((Clouds.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) {
//logInfo ("Lambda", logPrefix + "Aktuelle Bewoelkung (" + Clouds.state.toString() + ") ueberschreitet den eingestellten Grenzwert von (" + AutoShading_Cloudiness_max.state.toString() + ")")
logInfo ("Lambda", logPrefix + "Aktuelle Bewoelkung ({}) ueberschreitet den eingestellten Grenzwert von ({})", Clouds.state, AutoShading_Cloudiness_max.state)
return false;
}
if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) {
//logInfo ("Lambda", logPrefix + "Elevation für das Beenden der Verschattung (" + AutoShading_Elevation_end.state.toString() + ") ist groesser als aktuelle (" + Elevation.state.toString() + ")")
logInfo ("Lambda", logPrefix + "Elevation für das Beenden der Verschattung ({}) ist groesser als aktuelle ({}) ", AutoShading_Elevation_end.state, Elevation.state)
return false;
}
// Rollladen werden geschlossen
logInfo("Lambda", logPrefix + "Grenzwerte wurden erreicht, Rollladen werden geschlossen")
shutter.members.forEach[ blind |
if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) {
logInfo ("Lambda", logPrefix + "Fahre Rollladen (" + blind.name.toString() + ") auf (" + targetHights.get(blind.name.toString()).intValue + ") %" )
blind.sendCommand(targetHights.get(blind.name.toString()).intValue)
//Pushnachricht versenden
//sendPushoverMessage(pushoverBuilder("Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %"))
sendTelegram("bot1","Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %")
} else {
logInfo ("Lambda", logPrefix + "Rollladen ist bereits weiter geschlossen (" + blind.state.toString() + "%) als er geschlossen werden sollte und wird daher ignoriert")
}
]
AutoShading_Start_last.postUpdate(now.toString())
return true;
]
//------------- Verschattung beenden -------------------
val shadingEnd = [GroupItem shutter |
val String logPrefix = "Verschattung deaktivieren - "
//var boolean log = true
val Map<String, Number> targetHights = newHashMap (
"Shutter_EG_Office" -> 74,
"Shutter_EG_Wohnen3" -> 64,
"Shutter_EG_Kueche2" -> 40,
"Shutter_EG_Wohnen1" -> 78,
"Shutter_EG_Wohnen2" -> 78,
"Shutter_EG_Technik" -> 73,
"Shutter_OG_HWR" -> 74
//"KuecheRollladenTuer" -> 58,
//"SchlafzimmerRollladenTuer" -> 100,
//"BadezimmerRollladen" -> 55,
//"WohnzimmerRollladenEsstisch" -> 65,
//"WohnzimmerRollladenTuer" -> 68,
//"WohnzimmerRollladenBalkon" -> 100
//"KuecheRollladenTuer" -> 58,
//"SchlafzimmerRollladenTuer" -> 100,
//"BadezimmerRollladen" -> 55,
//"WohnzimmerRollladenEsstisch" -> 65,
//"WohnzimmerRollladenTuer" -> 68,
//"WohnzimmerRollladenBalkon" -> 100
)
// Rollladen öffnen
logInfo ("Lambda", logPrefix + "Rollladen werden geoeffnet")
shutter.allMembers.forEach[blind|
if((blind.state as Number).intValue == targetHights.get(blind.name).intValue) {
logInfo ("Lambda", logPrefix + "Oeffne Rollladen: " + blind.name.toString())
blind.sendCommand(UP)
//Pushnachricht versenden
//sendPushoverMessage(pushoverBuilder("Verschattung für (" + blind.name.toString() + ") beendet, Rollladen wird geöffnet."))
sendTelegram("bot1", "Verschattung für (" + blind.name.toString() + ") beendet, Rollladen wird geöffnet.")
} else {
logInfo ("Lambda", logPrefix + "Rollladen: (" + blind.name.toString() + ") wird nicht geoeffnet, da dieser zwischenzeitlich manuell verändert wurde.")
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
AutoShading_End_last.postUpdate(now.toString())
//Variablen zurücksetzen
isActiveWest = false
isActiveEast = false
isActiveSouth = false
isActiveNorth = false
return true;
]
/* ------------- Verschattung RULES --------------------
*/
//------------- Verschattung starten --------------------
rule "Verschattung starten"
when
Item Azimuth changed
then
val String logPrefix = "Verschattung aktivieren - "
//Prüfung auf: Verschattungsautomatik an / ob es Tag ist / Präsenz / Jahreszeit
//if ((AutoShading.state == ON && IsDay.state == ON) && (DinesiPhone_Presence.state == OFF && OllisiPhone_Presence.state == OFF) && (Jahreszeit.state=="SPRING" || Jahreszeit.state=="SUMMER")) {
if ((AutoShading.state == ON && IsDay.state == ON) && (Jahreszeit.state=="SPRING" || Jahreszeit.state=="SUMMER")) {
if (AutoShading_Start_last.state === NULL) {
logInfo(logPrefix, 'Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)')
AutoShading_Start_last.postUpdate(now.minusDays(1).toString())
}
//var String timeNow = now.toString().substring(0,10)
//var String timeLastStart = AutoShading_Start_last.state.toString().substring(0,10)
// Items für Sitemap füllen
if (AutoShading_Azimuth_east == "NULL" || AutoShading_Azimuth_south == "NULL" || AutoShading_Azimuth_west == "NULL" || AutoShading_Azimuth_north == "NULL" ){
//AutoShading_Azimuth_east.postUpdate(closingAzimuth_west)
AutoShading_Azimuth_east.postUpdate(closingAzimuth_east)
AutoShading_Azimuth_south.postUpdate(closingAzimuth_south)
AutoShading_Azimuth_west.postUpdate(closingAzimuth_west)
AutoShading_Azimuth_north.postUpdate(closingAzimuth_north)
AutoShading_Temp_diff.postUpdate(temperatureHysteresis)
AutoShading_Cloudiness_Hyst.postUpdate(cloudHysteresis)
AutoShading_Rain_min.postUpdate(minPrecip)
}
//Azimuth ist größer als 270° (NORD)
if (!isActiveNorth) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_north)) {
logInfo ("rules", logPrefix + "Verschattung für Rollläden NORD")
isActiveNorth = shadingStart.apply(gRollladenNorth)
return;
}
} else {
logInfo ("rules", logPrefix + "Verschattung für Rollläden NORD bereits aktiviert")
}
//Azimuth ist größer als 181° (WEST)
if (!isActiveWest) {
//if ((Azimuth.state as Number).floatValue > (closingAzimuth_west)) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_west) && (Azimuth.state as Number).floatValue < (closingAzimuth_north)) {
logInfo ("rules", logPrefix + "Verschattung für Rollläden WEST")
isActiveWest = shadingStart.apply(gRollladenWest)
return;
}
} else {
logInfo ("rules", logPrefix + "Verschattung für Rollläden WEST bereits aktiviert")
}
//Azimuth ist größer als 111° (SÜD)
if (!isActiveSouth) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_south) && (Azimuth.state as Number).floatValue < (closingAzimuth_west)) {
logInfo ("rules", logPrefix + "Verschattung für Rollläden SÜD")
isActiveSouth = shadingStart.apply(gRollladenSouth)
return;
}
} else {
logInfo ("rules", logPrefix + "Verschattung für Rollläden SÜD bereits aktiviert")
}
//Azimuth ist größer als 65° (OST)
if (!isActiveEast) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_east) && (Azimuth.state as Number).floatValue < (closingAzimuth_south)) {
logInfo ("rules", logPrefix + "Verschattung für Rollläden OST")
isActiveEast = shadingStart.apply(gRollladenEast)
return;
}
} else {
logInfo ("rules", logPrefix + "Verschattung für Rollläden OST bereits aktiviert")
}
} else {
//logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da einer der folgenden Parameter matched: Verschattung deakiviert, es ist Nacht, Herbst oder Winter oder Anwesenheit erkannt.")
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da einer der folgenden Parameter matched: Verschattung deakiviert, es ist Nacht, Herbst oder Winter erkannt.")
}
end
//------------- Verschattung beenden --------------------
rule "Verschattung beenden"
when
Item Elevation changed
then
if ((AutoShading_end.state == ON && IsDay.state == ON) && (Jahreszeit.state=="SPRING" || Jahreszeit.state=="SUMMER")) {
val String logPrefix = "Verschattung deaktivieren - "
val boolean isRainLastHour = (Rain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
logInfo("rules", logPrefix + "Rain " + isRainLastHour)
val boolean isCloudLastHour = (Clouds.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
logInfo("rules", logPrefix + "Clouds " + isCloudLastHour )
val boolean isTemperature = ((weatherN_Temperature.state as Number).intValue < (weatherN_Temperature.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(temperatureHysteresis)))
logInfo("rules", logPrefix + "Temperatur " + isTemperature)
if (AutoShading_End_last.state === NULL) {
logInfo(logPrefix, "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_End_last.postUpdate(now.minusDays(1).toString())
}
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow) {
logInfo("rules", logPrefix + "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if (!isActiveWest && !isActiveEast && !isActiveSouth) {
logInfo("rules", logPrefix + "Beende, da heute noch keine automatische Verschattung stattfand")
return;
}
if (isTemperature) {
logInfo ("rules", logPrefix + "Verschattung beenden, Temperaturabfall von min. ({})° erkannt", temperatureHysteresis)
shadingEnd.apply(gRollladen)
return;
}
if ((weatherN_Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
logInfo("rules", logPrefix + "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",weatherN_Temperature.state, AutoShading_Temp_raise.state )
return;
}
if (isRainLastHour || isCloudLastHour) {
logInfo ("rules", logPrefix + "Verschattung beenden, Mindestregenmenge von ({}) mm oder druchschnittliche Bewölkung von ({}) % erreicht",minPrecip, cloudHysteresis)
shadingEnd.apply(gRollladen)
return;
}
if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) {
logInfo("rules", logPrefix + "Beende, aktuelle Elevation ({}) ueberschreitet den eingestellten Grenzwert von ({}) ", Elevation.state, AutoShading_Elevation_end.state)
return;
}
if (isActiveWest || isActiveEast || isActiveSouth ) {
logInfo ("rules", logPrefix + "Verschattung beenden")
shadingEnd.apply(gRollladen)
return;
}
}
end
/* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt --------------------
*/
rule "Verschattung Variablen zurücksetzen"
when
Time cron "15 59 23 * * ?"
then
if (isActiveNorth == true || isActiveWest == true || isActiveEast == true || isActiveSouth == true) {
isActiveNorth = false
isActiveWest = false
isActiveEast = false
isActiveSouth = false
}
end
Code: Alles auswählen
2020-06-07 20:49:40.206 [INFO ] [clipse.smarthome.model.script.Lambda] - Verschattung aktivieren - Grenzwerte wurden erreicht, Rollladen werden geschlossen
2020-06-07 20:49:40.215 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Verschattung starten': cannot invoke method public abstract int java.lang.Number.intValue() on null
- udo1toni
- Beiträge: 13864
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Also, <Nörgelmodus>
Die Formatierung Deiner Rules ist unübersichtlich. Einrückungen sind dazu da, zusammengehörende Codeteile deutlicher erkennbar zu machen. Massig auskommentierte Befehle helfen auch nicht. Die Hashmap wird unnötigerweise mehrfach definiert.
Du verwendest das Logging falsch. Der Befehl logInfo() erwartet zwei Strings als Parameter, wobei der erste String der Logger Name ist. Weder "Rules" noch "Lambda" sind im openHAB-Umfeld sinnvolle Loggernamen. Der Loggername in Rules wird ohnehin immer in den Loggerbaum integriert, und zwar im Zweig org.openhab.model.script.
Die Auslagerung eines Teils des Codes in ein Lambda erhöht die Komplexität, ohne dass es (hier) Vorteile bringt.
</Nörgelmodus>
Die (ungetesteten) Rules, (einigermaßen) vom Balast befreit:
Das Problem, warum die Rule nicht funktioniert, ist eine Variable, die nicht mit einem gültigen Wert gefüllt ist (null kann nicht nach Integer gecastet werden). Dieses Problem ist noch nicht in den Rules berücksichtigt.
Beide Rules (Beschattung Ein/Aus) werden immer gleichzeitig getriggert, da beide Rules von Astro Items abhängen, welche sich bei jedem Update ändern. So gesehen wäre es sinnvoller, beide Rules als eine Rule zu definieren und die Funktionsweise der Rules entsprechend anzupassen. Auch wäre es sinnvoll, das Logging zu minimieren, soweit die Rule nichts zu tun hat.
Die Formatierung Deiner Rules ist unübersichtlich. Einrückungen sind dazu da, zusammengehörende Codeteile deutlicher erkennbar zu machen. Massig auskommentierte Befehle helfen auch nicht. Die Hashmap wird unnötigerweise mehrfach definiert.
Du verwendest das Logging falsch. Der Befehl logInfo() erwartet zwei Strings als Parameter, wobei der erste String der Logger Name ist. Weder "Rules" noch "Lambda" sind im openHAB-Umfeld sinnvolle Loggernamen. Der Loggername in Rules wird ohnehin immer in den Loggerbaum integriert, und zwar im Zweig org.openhab.model.script.
Die Auslagerung eines Teils des Codes in ein Lambda erhöht die Komplexität, ohne dass es (hier) Vorteile bringt.
</Nörgelmodus>
Die (ungetesteten) Rules, (einigermaßen) vom Balast befreit:
Code: Alles auswählen
import java.util.Map
var Number closingAzimuth_east = 85
var Number closingAzimuth_south = 111
var Number closingAzimuth_west = 171
var Number closingAzimuth_north = 260
var Number closingCloudiness = 20
val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde
var Number openingTemperature = 22
val Number temperatureHysteresis = 4 //Temperaturabfall von min. 4 Grad in der letzten Stunde
val Number minPrecip = 5 //die Mindestmenge an Regen in der letzten Stunde
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
var boolean isActiveNorth = false
val Map<String, Number> targetHights = newHashMap (
"Shutter_EG_Office" -> 74,
"Shutter_EG_Wohnen3" -> 64,
"Shutter_EG_Kueche2" -> 40,
"Shutter_EG_Wohnen1" -> 78,
"Shutter_EG_Wohnen2" -> 78,
"Shutter_EG_Technik" -> 73,
"Shutter_OG_HWR" -> 74
)
rule "Verschattung starten"
when
Item Azimuth changed
then
if (AutoShading.state != ON) { // Verschattung deaktiviert?
logInfo("shading", "Verschattung wird nicht ausgeführt, da deaktiviert."
return;
}
if (IsDay.state != ON) { // Nacht?
logInfo("shading", "Verschattung wird nicht ausgeführt, da Nacht."
return;
}
if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst?
logInfo("shading", "Verschattung wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
if (AutoShading_Start_last.state == NULL) {
logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (gestern)")
AutoShading_Start_last.postUpdate(now.minusDays(1).toString())
}
// Items für Sitemap füllen
if(AutoShading_Azimuth_east.state == NULL) AutoShading_Azimuth_east.postUpdate(closingAzimuth_east)
if(AutoShading_Azimuth_south.state == NULL) AutoShading_Azimuth_south.postUpdate(closingAzimuth_south)
if(AutoShading_Azimuth_west.state == NULL) AutoShading_Azimuth_west.postUpdate(closingAzimuth_west)
if(AutoShading_Azimuth_north.state == NULL) AutoShading_Azimuth_north.postUpdate(closingAzimuth_north)
if(AutoShading_Temp_diff.state == NULL) AutoShading_Temp_diff.postUpdate(temperatureHysteresis)
if(AutoShading_Cloudiness_Hyst.state == NULL) AutoShading_Cloudiness_Hyst.postUpdate(cloudHysteresis)
if(AutoShading_Rain_min.state == NULL) AutoShading_Rain_min.postUpdate(minPrecip)
if ((weatherN_Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
logInfo ("shading", "Mindesttemperatur von {} °C wurde nicht erreicht. Aktuelle Temperatur {} °C", AutoShading_Temp_min.state, weatherN_Temperature.state)
return false;
}
if ((Clouds.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) {
logInfo ("shading", "Aktuelle Bewoelkung {} % ueberschreitet den eingestellten Grenzwert von {} %", Clouds.state, AutoShading_Cloudiness_max.state)
return false;
}
if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) {
logInfo ("shading", "Elevation für das Beenden der Verschattung {} ° ist groesser als aktuelle {}°", AutoShading_Elevation_end.state, Elevation.state)
return false;
}
val nAz = Azimuth.state as Number).floatValue
//Azimuth ist größer als 270° (NORD)
switch(true) { // erste zutreffende Bedingung wird exclusiv ausgeführt (alle nachfolgenden nicht, auch wenn sie zutreffen)
case nAz > closingAzimuth_north : {
if(!isActiveNorth) {
logInfo ("shading", "Verschattung für Rollläden NORD")
val myGroup = gRollladenNorth
isActiveNorth = true
}
}
case nAz > closingAzimuth_west : { // hinreichend, da 1. Bedingung nicht zutrifft
if(!isActiveWest) {
logInfo ("shading", "Verschattung für Rollläden WEST")
val myGroup = gRollladenWest
isActiveWest = true
}
}
case nAz > closingAzimuth_south : {// hinreichend, da 2. Bedingung nicht zutrifft
if(!isActiveSouth) {
logInfo ("shading", "Verschattung für Rollläden SÜD")
val myGroup = gRollladenSouth
isActiveSouth = true
}
}
case nAz > closingAzimuth_east : {// hinreichend, da 3. Bedingung nicht zutrifft
if(!isActiveEast){
logInfo ("shading", "Verschattung für Rollläden OST")
val myGroup = gRollladenEast
isActiveEast = true
}
}
}
if(myGroup === null) { // myGroup ist leer bzw. nicht definiert
logInfo ("shading", "Verschattung bereits aktiv oder außerhalb des Verschattungsbereichs")
return;
}
myGroup.members.forEach[ blind |
if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) {
logInfo ("shading", "Fahre Rollladen ({}) auf ({}) %",blind.name,targetHights.get(blind.name.toString()))
blind.sendCommand(targetHights.get(blind.name.toString()).intValue)
sendTelegram("bot1","Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %")
} else {
logInfo ("shading", "Rollladen ist bereits weiter geschlossen ({} %) als er geschlossen werden sollte und wird daher ignoriert",blind.state)
}
]
AutoShading_Start_last.postUpdate(now.toString())
end
//------------- Verschattung beenden --------------------
rule "Verschattung beenden"
when
Item Elevation changed
then
if (AutoShading.state != ON) { // Verschattung deaktiviert?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da deaktiviert."
return;
}
if (IsDay.state != ON) { // Nacht?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da Nacht."
return;
}
if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
val boolean isRainLastHour = (Rain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
logInfo("shading", "Rain " + isRainLastHour)
val boolean isCloudLastHour = (Clouds.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
logInfo("shading", "Clouds " + isCloudLastHour )
val boolean isTemperature = ((weatherN_Temperature.state as Number).intValue < (weatherN_Temperature.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(temperatureHysteresis)))
logInfo("shading", "Temperatur " + isTemperature)
if (AutoShading_End_last.state === NULL) {
logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_End_last.postUpdate(now.minusDays(1).toString())
}
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow) {
logInfo("shading", "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if (!isActiveWest && !isActiveEast && !isActiveSouth && !isActiveNorth) {
logInfo("shading", "Beende, da heute noch keine automatische Verschattung stattfand")
return;
}
if ((weatherN_Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
logInfo("shading", "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",weatherN_Temperature.state, AutoShading_Temp_raise.state )
return;
}
if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) {
logInfo("shading", "Beende, aktuelle Elevation ({}) ueberschreitet den eingestellten Grenzwert von ({}) ", Elevation.state, AutoShading_Elevation_end.state)
return;
}
var boolean bEnd = false
if (isTemperature) {
logInfo ("shading", "Verschattung beenden, Temperaturabfall von min. ({})°C erkannt", temperatureHysteresis)
bEnd = true
}
if (isRainLastHour || isCloudLastHour) {
logInfo ("shading", "Verschattung beenden, Mindestregenmenge von ({}) mm oder druchschnittliche Bewölkung von ({}) % erreicht",minPrecip, cloudHysteresis)
bEnd = true
}
if (isActiveWest || isActiveEast || isActiveSouth ) {
logInfo ("shading", "Verschattung beenden")
bEnd = true
}
if (!bEnd) return;
gRolladen.allMembers.forEach[blind|
if((blind.state as Number) == targetHights.get(blind.name)) {
logInfo ("shading", "Öffne Rollladen ", blind.name)
blind.sendCommand(UP)
sendTelegram("bot1", "Verschattung für (" + blind.name + ") beendet, Rollladen wird geöffnet.")
} else {
logInfo ("shading", "Rollladen {} wird nicht geoeffnet, da dieser zwischenzeitlich manuell verändert wurde.",blind.name)
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
AutoShading_End_last.postUpdate(now.toString())
//Variablen zurücksetzen
isActiveWest = false
isActiveEast = false
isActiveSouth = false
isActiveNorth = false
end
/* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt --------------------
*/
rule "Verschattung Variablen zurücksetzen"
when
Time cron "15 59 23 * * ?"
then
isActiveNorth = false
isActiveWest = false
isActiveEast = false
isActiveSouth = false
end
Beide Rules (Beschattung Ein/Aus) werden immer gleichzeitig getriggert, da beide Rules von Astro Items abhängen, welche sich bei jedem Update ändern. So gesehen wäre es sinnvoller, beide Rules als eine Rule zu definieren und die Funktionsweise der Rules entsprechend anzupassen. Auch wäre es sinnvoll, das Logging zu minimieren, soweit die Rule nichts zu tun hat.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet
- Cyrelian
- Beiträge: 601
- Registriert: 24. Sep 2015 17:55
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Hi,
bin heute zufälligerweise über etwas gestolpert was die "boolean" angeht.
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
Diese werde zur Laufzeit auf TRUE gesetzt. Gibt es die Möglichkeit, von "aussen" zu prüfen, ob diese auf TRUE oder FALSE stehen, oder sie gar zu ändern? Via REST API gehts nicht.
THX
Cyrelian
bin heute zufälligerweise über etwas gestolpert was die "boolean" angeht.
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
Diese werde zur Laufzeit auf TRUE gesetzt. Gibt es die Möglichkeit, von "aussen" zu prüfen, ob diese auf TRUE oder FALSE stehen, oder sie gar zu ändern? Via REST API gehts nicht.
THX
Cyrelian
- Cyrelian
- Beiträge: 601
- Registriert: 24. Sep 2015 17:55
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Hi,
ich habs jetzt mal so gebaut .
Vielleicht habt ihr ja noch andere Ideen.
CYA
Cyrelian
ich habs jetzt mal so gebaut .
Code: Alles auswählen
rule "Verschattung Variablen update"
when
Item Shading_Var received command
then
logInfo("rules", "Verschattung Variablen: " + receivedCommand)
switch (receivedCommand) {
case "queryState" : {
logInfo("rules", logPrefix + "Verschattung Variablen update")
if (isActiveWest) {
logInfo("rules", logPrefix + "Verschattung für Rollläden WEST aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden WEST inaktiv")
}
if (isActiveEast) {
logInfo("rules", logPrefix + "Verschattung für Rollläden OST aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden OST inaktiv")
}
if (isActiveSouth) {
logInfo("rules", logPrefix + "Verschattung für Rollläden SÜD aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden SÜD inaktiv")
}
if (isActiveBalkon) {
logInfo("rules", logPrefix + "Verschattung für Markise (Balkon) aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Markise (Balkon) inaktiv")
}
}
case "reset" : {
logInfo("rules", logPrefix + "Verschattung Variablen reset")
isActiveWest = false
isActiveEast = false
isActiveSouth = false
isActiveBalkon = false
}
}
Shading_Var.postUpdate(NULL)
end
CYA
Cyrelian
-
- Beiträge: 1
- Registriert: 12. Jun 2020 22:55
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
hallo Bin ganz neu
bei mir kommt in log immer diese Meldung. Habe es versucht zu verstehen aber ohne Erfolg. Galube se hängt vom grad Zeichen?
bei mir kommt in log immer diese Meldung. Habe es versucht zu verstehen aber ohne Erfolg. Galube se hängt vom grad Zeichen?
Code: Alles auswählen
2020-07-01 12:10:20.219 [INFO ] [eclipse.smarthome.model.script.rules] - Rolloautomatik (Rollo West ab) - Azimuth (143.45207931536362 °) hat noch nicht Schwellwert (119) erreicht
- Cyrelian
- Beiträge: 601
- Registriert: 24. Sep 2015 17:55
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Hi msantoni,
ohne deine Items/Code zu kennen ist das etwas schwierig zu analysieren. Ich Tippe aber mal drauf, dass dein Item für Azimuth so aussieht:
Deine Rule kann die beiden Werte nicht vergleichen.
Deswegen versuch es mal so:
Cu
Cyrelian
ohne deine Items/Code zu kennen ist das etwas schwierig zu analysieren. Ich Tippe aber mal drauf, dass dein Item für Azimuth so aussieht:
Code: Alles auswählen
Number:Angle Azimuth "Azimuth"
Deswegen versuch es mal so:
Code: Alles auswählen
Number Azimuth "Azimuth"
Cyrelian
-
- Beiträge: 35
- Registriert: 4. Jan 2019 22:09
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Wow, vielen herzlichen Dank für die Überarbeitung und Korrektur meines Codes. Und das ganze auch noch nachts, MEGA !udo1toni hat geschrieben: ↑8. Jun 2020 01:20 Also, <Nörgelmodus>
Die Formatierung Deiner Rules ist unübersichtlich. Einrückungen sind dazu da, zusammengehörende Codeteile deutlicher erkennbar zu machen. Massig auskommentierte Befehle helfen auch nicht. Die Hashmap wird unnötigerweise mehrfach definiert.
Du verwendest das Logging falsch. Der Befehl logInfo() erwartet zwei Strings als Parameter, wobei der erste String der Logger Name ist. Weder "Rules" noch "Lambda" sind im openHAB-Umfeld sinnvolle Loggernamen. Der Loggername in Rules wird ohnehin immer in den Loggerbaum integriert, und zwar im Zweig org.openhab.model.script.
Die Auslagerung eines Teils des Codes in ein Lambda erhöht die Komplexität, ohne dass es (hier) Vorteile bringt.
</Nörgelmodus>
Die (ungetesteten) Rules, (einigermaßen) vom Balast befreit:Das Problem, warum die Rule nicht funktioniert, ist eine Variable, die nicht mit einem gültigen Wert gefüllt ist (null kann nicht nach Integer gecastet werden). Dieses Problem ist noch nicht in den Rules berücksichtigt.Code: Alles auswählen
import java.util.Map var Number closingAzimuth_east = 85 var Number closingAzimuth_south = 111 var Number closingAzimuth_west = 171 var Number closingAzimuth_north = 260 var Number closingCloudiness = 20 val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde var Number openingTemperature = 22 val Number temperatureHysteresis = 4 //Temperaturabfall von min. 4 Grad in der letzten Stunde val Number minPrecip = 5 //die Mindestmenge an Regen in der letzten Stunde var boolean isActiveWest = false var boolean isActiveEast = false var boolean isActiveSouth = false var boolean isActiveNorth = false val Map<String, Number> targetHights = newHashMap ( "Shutter_EG_Office" -> 74, "Shutter_EG_Wohnen3" -> 64, "Shutter_EG_Kueche2" -> 40, "Shutter_EG_Wohnen1" -> 78, "Shutter_EG_Wohnen2" -> 78, "Shutter_EG_Technik" -> 73, "Shutter_OG_HWR" -> 74 ) rule "Verschattung starten" when Item Azimuth changed then if (AutoShading.state != ON) { // Verschattung deaktiviert? logInfo("shading", "Verschattung wird nicht ausgeführt, da deaktiviert." return; } if (IsDay.state != ON) { // Nacht? logInfo("shading", "Verschattung wird nicht ausgeführt, da Nacht." return; } if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst? logInfo("shading", "Verschattung wird nicht ausgeführt, da weder, Frühling noch Sommer.") return; } if (AutoShading_Start_last.state == NULL) { logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (gestern)") AutoShading_Start_last.postUpdate(now.minusDays(1).toString()) } // Items für Sitemap füllen if(AutoShading_Azimuth_east.state == NULL) AutoShading_Azimuth_east.postUpdate(closingAzimuth_east) if(AutoShading_Azimuth_south.state == NULL) AutoShading_Azimuth_south.postUpdate(closingAzimuth_south) if(AutoShading_Azimuth_west.state == NULL) AutoShading_Azimuth_west.postUpdate(closingAzimuth_west) if(AutoShading_Azimuth_north.state == NULL) AutoShading_Azimuth_north.postUpdate(closingAzimuth_north) if(AutoShading_Temp_diff.state == NULL) AutoShading_Temp_diff.postUpdate(temperatureHysteresis) if(AutoShading_Cloudiness_Hyst.state == NULL) AutoShading_Cloudiness_Hyst.postUpdate(cloudHysteresis) if(AutoShading_Rain_min.state == NULL) AutoShading_Rain_min.postUpdate(minPrecip) if ((weatherN_Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) { logInfo ("shading", "Mindesttemperatur von {} °C wurde nicht erreicht. Aktuelle Temperatur {} °C", AutoShading_Temp_min.state, weatherN_Temperature.state) return false; } if ((Clouds.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) { logInfo ("shading", "Aktuelle Bewoelkung {} % ueberschreitet den eingestellten Grenzwert von {} %", Clouds.state, AutoShading_Cloudiness_max.state) return false; } if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) { logInfo ("shading", "Elevation für das Beenden der Verschattung {} ° ist groesser als aktuelle {}°", AutoShading_Elevation_end.state, Elevation.state) return false; } val nAz = Azimuth.state as Number).floatValue //Azimuth ist größer als 270° (NORD) switch(true) { // erste zutreffende Bedingung wird exclusiv ausgeführt (alle nachfolgenden nicht, auch wenn sie zutreffen) case nAz > closingAzimuth_north : { if(!isActiveNorth) { logInfo ("shading", "Verschattung für Rollläden NORD") val myGroup = gRollladenNorth isActiveNorth = true } } case nAz > closingAzimuth_west : { // hinreichend, da 1. Bedingung nicht zutrifft if(!isActiveWest) { logInfo ("shading", "Verschattung für Rollläden WEST") val myGroup = gRollladenWest isActiveWest = true } } case nAz > closingAzimuth_south : {// hinreichend, da 2. Bedingung nicht zutrifft if(!isActiveSouth) { logInfo ("shading", "Verschattung für Rollläden SÜD") val myGroup = gRollladenSouth isActiveSouth = true } } case nAz > closingAzimuth_east : {// hinreichend, da 3. Bedingung nicht zutrifft if(!isActiveEast){ logInfo ("shading", "Verschattung für Rollläden OST") val myGroup = gRollladenEast isActiveEast = true } } } if(myGroup === null) { // myGroup ist leer bzw. nicht definiert logInfo ("shading", "Verschattung bereits aktiv oder außerhalb des Verschattungsbereichs") return; } myGroup.members.forEach[ blind | if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) { logInfo ("shading", "Fahre Rollladen ({}) auf ({}) %",blind.name,targetHights.get(blind.name.toString())) blind.sendCommand(targetHights.get(blind.name.toString()).intValue) sendTelegram("bot1","Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %") } else { logInfo ("shading", "Rollladen ist bereits weiter geschlossen ({} %) als er geschlossen werden sollte und wird daher ignoriert",blind.state) } ] AutoShading_Start_last.postUpdate(now.toString()) end //------------- Verschattung beenden -------------------- rule "Verschattung beenden" when Item Elevation changed then if (AutoShading.state != ON) { // Verschattung deaktiviert? logInfo("shading", "Verschattungsende wird nicht ausgeführt, da deaktiviert." return; } if (IsDay.state != ON) { // Nacht? logInfo("shading", "Verschattungsende wird nicht ausgeführt, da Nacht." return; } if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst? logInfo("shading", "Verschattungsende wird nicht ausgeführt, da weder, Frühling noch Sommer.") return; } val boolean isRainLastHour = (Rain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip)) logInfo("shading", "Rain " + isRainLastHour) val boolean isCloudLastHour = (Clouds.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis)) logInfo("shading", "Clouds " + isCloudLastHour ) val boolean isTemperature = ((weatherN_Temperature.state as Number).intValue < (weatherN_Temperature.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(temperatureHysteresis))) logInfo("shading", "Temperatur " + isTemperature) if (AutoShading_End_last.state === NULL) { logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)") AutoShading_End_last.postUpdate(now.minusDays(1).toString()) } var String timeNow = now.toString().substring(0,10) var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10) if (timeLastEnde == timeNow) { logInfo("shading", "Beende, da heute bereits ein automatisches Hochfahren stattfand") return; } if (!isActiveWest && !isActiveEast && !isActiveSouth && !isActiveNorth) { logInfo("shading", "Beende, da heute noch keine automatische Verschattung stattfand") return; } if ((weatherN_Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) { logInfo("shading", "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",weatherN_Temperature.state, AutoShading_Temp_raise.state ) return; } if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) { logInfo("shading", "Beende, aktuelle Elevation ({}) ueberschreitet den eingestellten Grenzwert von ({}) ", Elevation.state, AutoShading_Elevation_end.state) return; } var boolean bEnd = false if (isTemperature) { logInfo ("shading", "Verschattung beenden, Temperaturabfall von min. ({})°C erkannt", temperatureHysteresis) bEnd = true } if (isRainLastHour || isCloudLastHour) { logInfo ("shading", "Verschattung beenden, Mindestregenmenge von ({}) mm oder druchschnittliche Bewölkung von ({}) % erreicht",minPrecip, cloudHysteresis) bEnd = true } if (isActiveWest || isActiveEast || isActiveSouth ) { logInfo ("shading", "Verschattung beenden") bEnd = true } if (!bEnd) return; gRolladen.allMembers.forEach[blind| if((blind.state as Number) == targetHights.get(blind.name)) { logInfo ("shading", "Öffne Rollladen ", blind.name) blind.sendCommand(UP) sendTelegram("bot1", "Verschattung für (" + blind.name + ") beendet, Rollladen wird geöffnet.") } else { logInfo ("shading", "Rollladen {} wird nicht geoeffnet, da dieser zwischenzeitlich manuell verändert wurde.",blind.name) } ] // Letzte Ausführung mit entsprechendem Zeitstempel belegen AutoShading_End_last.postUpdate(now.toString()) //Variablen zurücksetzen isActiveWest = false isActiveEast = false isActiveSouth = false isActiveNorth = false end /* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt -------------------- */ rule "Verschattung Variablen zurücksetzen" when Time cron "15 59 23 * * ?" then isActiveNorth = false isActiveWest = false isActiveEast = false isActiveSouth = false end
Beide Rules (Beschattung Ein/Aus) werden immer gleichzeitig getriggert, da beide Rules von Astro Items abhängen, welche sich bei jedem Update ändern. So gesehen wäre es sinnvoller, beide Rules als eine Rule zu definieren und die Funktionsweise der Rules entsprechend anzupassen. Auch wäre es sinnvoll, das Logging zu minimieren, soweit die Rule nichts zu tun hat.
Wir kommen der Sache schon näher.
Ich habe deinen Code übernommen und nach "meinen Möglichkeiten" korrigiert, wann auch immer "VSC" gemeckert hat.
Allerdings gibt es noch ein paar Stellen, die ich alleine leider nicht lösen kann. Hier der Code:
Code: Alles auswählen
import java.util.Map
var Number closingAzimuth_east = 85
var Number closingAzimuth_south = 111
var Number closingAzimuth_west = 171
var Number closingAzimuth_north = 260
var Number closingCloudiness = 20
val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde
var Number openingTemperature = 22
val Number temperatureHysteresis = 4 //Temperaturabfall von min. 4 Grad in der letzten Stunde
val Number minPrecip = 5 //die Mindestmenge an Regen in der letzten Stunde
var boolean isActiveWest = false
var boolean isActiveEast = false
var boolean isActiveSouth = false
var boolean isActiveNorth = false
val Map<String, Number> targetHights = newHashMap (
"Shutter_EG_Office" -> 74,
"Shutter_EG_Wohnen3" -> 73,
"Shutter_EG_Kueche2" -> 40,
"Shutter_EG_Wohnen1" -> 78,
"Shutter_EG_Wohnen2" -> 78,
"Shutter_EG_Technik" -> 73,
"Shutter_OG_HWR" -> 74
)
rule "Verschattung starten"
when
Item Azimuth changed
then
if (AutoShading.state != ON) { // Verschattung deaktiviert?
logInfo("shading", "Verschattung wird nicht ausgeführt, da deaktiviert.")
return;
}
if (IsDay.state != ON) { // Nacht?
logInfo("shading", "Verschattung wird nicht ausgeführt, da Nacht.")
return;
}
if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst?
logInfo("shading", "Verschattung wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
if (AutoShading_Start_last.state == NULL) {
logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (gestern)")
AutoShading_Start_last.postUpdate(now.minusDays(1).toString())
}
// Items für Sitemap füllen
if(AutoShading_Azimuth_east.state == NULL) AutoShading_Azimuth_east.postUpdate(closingAzimuth_east)
if(AutoShading_Azimuth_south.state == NULL) AutoShading_Azimuth_south.postUpdate(closingAzimuth_south)
if(AutoShading_Azimuth_west.state == NULL) AutoShading_Azimuth_west.postUpdate(closingAzimuth_west)
if(AutoShading_Azimuth_north.state == NULL) AutoShading_Azimuth_north.postUpdate(closingAzimuth_north)
if(AutoShading_Temp_diff.state == NULL) AutoShading_Temp_diff.postUpdate(temperatureHysteresis)
if(AutoShading_Cloudiness_Hyst.state == NULL) AutoShading_Cloudiness_Hyst.postUpdate(cloudHysteresis)
if(AutoShading_Rain_min.state == NULL) AutoShading_Rain_min.postUpdate(minPrecip)
if ((weatherN_Temperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
logInfo ("shading", "Mindesttemperatur von {} °C wurde nicht erreicht. Aktuelle Temperatur {} °C", AutoShading_Temp_min.state, weatherN_Temperature.state)
return false;
}
if ((Clouds.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) {
logInfo ("shading", "Aktuelle Bewoelkung {} % ueberschreitet den eingestellten Grenzwert von {} %", Clouds.state, AutoShading_Cloudiness_max.state)
return false;
}
if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) {
logInfo ("shading", "Elevation für das Beenden der Verschattung {} ° ist groesser als aktuelle {}°", AutoShading_Elevation_end.state, Elevation.state)
return false;
}
val nAz = (Azimuth.state as Number).floatValue
//Azimuth ist größer als 270° (NORD)
switch(true) { // erste zutreffende Bedingung wird exclusiv ausgeführt (alle nachfolgenden nicht, auch wenn sie zutreffen)
case nAz > closingAzimuth_north : {
if(!isActiveNorth) {
logInfo ("shading", "Verschattung für Rollläden NORD")
val myGroup = gRollladenNorth
isActiveNorth = true
}
}
case nAz > closingAzimuth_west : { // hinreichend, da 1. Bedingung nicht zutrifft
if(!isActiveWest) {
logInfo ("shading", "Verschattung für Rollläden WEST")
val myGroup = gRollladenWest
isActiveWest = true
}
}
case nAz > closingAzimuth_south : {// hinreichend, da 2. Bedingung nicht zutrifft
if(!isActiveSouth) {
logInfo ("shading", "Verschattung für Rollläden SÜD")
val myGroup = gRollladenSouth
isActiveSouth = true
}
}
case nAz > closingAzimuth_east : {// hinreichend, da 3. Bedingung nicht zutrifft
if(!isActiveEast){
logInfo ("shading", "Verschattung für Rollläden OST")
val myGroup = gRollladenEast
isActiveEast = true
}
}
}
if(myGroup === null) { // myGroup ist leer bzw. nicht definiert
logInfo ("shading", "Verschattung bereits aktiv oder außerhalb des Verschattungsbereichs")
return;
}
myGroup.members.forEach[ blind |
if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) {
logInfo ("shading", "Fahre Rollladen ({}) auf ({}) %",blind.name,targetHights.get(blind.name.toString()))
blind.sendCommand(targetHights.get(blind.name.toString()).intValue)
sendTelegram("bot1","Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %")
} else {
logInfo ("shading", "Rollladen ist bereits weiter geschlossen ({} %) als er geschlossen werden sollte und wird daher ignoriert",blind.state)
}
]
AutoShading_Start_last.postUpdate(now.toString())
end
//------------- Verschattung beenden --------------------
rule "Verschattung beenden"
when
Item Elevation changed
then
if (AutoShading.state != ON) { // Verschattung deaktiviert?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da deaktiviert.")
return;
}
if (IsDay.state != ON) { // Nacht?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da Nacht.")
return;
}
if (Jahreszeit.state.toString !="SPRING" && Jahreszeit.state.toString != "SUMMER") { // Winter oder Herbst?
logInfo("shading", "Verschattungsende wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
val boolean isRainLastHour = (Rain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
logInfo("shading", "Rain " + isRainLastHour)
val boolean isCloudLastHour = (Clouds.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
logInfo("shading", "Clouds " + isCloudLastHour )
val boolean isTemperature = ((weatherN_Temperature.state as Number).intValue < (weatherN_Temperature.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(temperatureHysteresis)))
logInfo("shading", "Temperatur " + isTemperature)
if (AutoShading_End_last.state === NULL) {
logInfo("shading", "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_End_last.postUpdate(now.minusDays(1).toString())
}
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow) {
logInfo("shading", "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if (!isActiveWest && !isActiveEast && !isActiveSouth && !isActiveNorth) {
logInfo("shading", "Beende, da heute noch keine automatische Verschattung stattfand")
return;
}
if ((weatherN_Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
logInfo("shading", "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",weatherN_Temperature.state, AutoShading_Temp_raise.state )
return;
}
if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) {
logInfo("shading", "Beende, aktuelle Elevation ({}) ueberschreitet den eingestellten Grenzwert von ({}) ", Elevation.state, AutoShading_Elevation_end.state)
return;
}
var boolean bEnd = false
if (isTemperature) {
logInfo ("shading", "Verschattung beenden, Temperaturabfall von min. ({})°C erkannt", temperatureHysteresis)
bEnd = true
}
if (isRainLastHour || isCloudLastHour) {
logInfo ("shading", "Verschattung beenden, Mindestregenmenge von ({}) mm oder druchschnittliche Bewölkung von ({}) % erreicht",minPrecip, cloudHysteresis)
bEnd = true
}
if (isActiveWest || isActiveEast || isActiveSouth ) {
logInfo ("shading", "Verschattung beenden")
bEnd = true
}
if (!bEnd) return;
gRollladen.allMembers.forEach[blind|
if((blind.state as Number) == targetHights.get(blind.name)) {
logInfo ("shading", "Öffne Rollladen ", blind.name)
blind.sendCommand(UP)
sendTelegram("bot1", "Verschattung für (" + blind.name + ") beendet, Rollladen wird geöffnet.")
} else {
logInfo ("shading", "Rollladen {} wird nicht geoeffnet, da dieser zwischenzeitlich manuell verändert wurde.",blind.name)
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
AutoShading_End_last.postUpdate(now.toString())
//Variablen zurücksetzen
isActiveWest = false
isActiveEast = false
isActiveSouth = false
isActiveNorth = false
end
/* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt --------------------
*/
rule "Verschattung Variablen zurücksetzen"
when
Time cron "15 59 23 * * ?"
then
isActiveNorth = false
isActiveWest = false
isActiveEast = false
isActiveSouth = false
end
Nr. 1.
Bei den Zeilen 60,65 und 69 wird "return false;" unterstrichen mit der Fehlermeldung: "Void functions cannot return a value".
Nr. 2.
siehe mein Screenshot. Da wird über "myGroup" gemeckert mit dem Hinweis: "The value of the local variable myGroup is not used"
Zusätzlich Zeile Nr. 104: The method or field myGroup is undefined.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.