Seite 2 von 26
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 3. Jun 2019 18:15
von PeterA
Hier nun eine Frage zu einem bestimmten Item in der Rule.
Code: Alles auswählen
timeLast = Rolloautomatik_start_last.state.toString().substring(0,10)
In das Item "Rolloautomatik_start_last" wird der Zeitpunkt geschrieben wann die Rolladen runter gefahren wurden
so das die Rule nur einmal am Tag ausführt.
Kann ich diese Item auch persistieren ? Denn wenn OpenHab zwischenzeitlich neugestartet wurde, ist das Item ja erst mal
ohne "Zeitstempel"....
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 4. Jun 2019 12:48
von Cyrelian
Hi Peter,
den timeLast direkt nicht. Ich würde ein ITEM vom Typ DateTime anlegen und dann immer ein postUpdate drauf machen, bzw. einfach das Rollladenautomatik_Start_last persistieren mit everyChange, everyMinute, restoreOnStartup.
CU
Cyrelian
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 21. Jun 2019 13:58
von Cyrelian
Hi,
ich versuche gerade die Rule um eine lambda Funktion zu erweitern. Hänge aber gerade (ich vermute irgendwo falsch "geklammert")
bei dem VAL bekomme ich:
missing EOF at 'val'(org.eclipse.xtext.diagnostics.Diagnostic.Syntax)
Code: Alles auswählen
val Functions$Function1<GenericItem, String> Shading= [ shutter |
if ((localCurrentTemperature.state as Number).floatValue > (AutoShading_Temp_min.state as Number)) {
if ((localCurrentCloudiness.state as Number).floatValue <= (AutoShading_Cloudiness_max.state as Number)) {
if ((Elevation.state as Number) > (AutoShading_Elevation_ende.state as Number)) {
// Rollladen runterfahren
if (log) logInfo(filename, logPrefix + 'Rollladen werden runtergefahren')
shutter.forEach[blind|
if (blind.state as Number < (AutoShading_ShutterTargetPercent.state as Number)) {
if (log) logInfo(filename, logPrefix + 'Fahre Rollladen auf ' + AutoShading_ShutterTargetPercent.state.toString() + '%: ' + blind.name)
blind.sendCommand(AutoShading_ShutterTargetPercent.state as Number)
//Pushnachricht versenden
sendPushoverMessage(pushoverBuilder("Abschattung für " + blind.name.toString "aktiviert"))
} else {
if (log) logInfo(filename, logPrefix + 'Rollladen ist bereits weiter geschlossen (' + blind.state.toString() + '%) als er geschlossen werden sollte und wird daher ignoriert')
}
]
// Letzte Ausführung mit entsprechendem Zeitstempel belegen
AutoShading_Start_last.postUpdate(new DateTimeType())
} else {
if (log) logInfo(filename, logPrefix + 'Elevation für wieder abfahren (' + AutoShading_Elevation_ende.state.toString() + ') ist groesser als aktuelle (' + Elevation.state.toString() + ')')
}
} else {
if (log) logInfo(filename, logPrefix + 'Mindestbewoelkung (' + AutoShading_Cloudiness_max.state.toString() + ') wurde unterschritten (' + localCurrentCloudiness.state.toString() + ')')
}
} else {
if (log) logInfo(filename, logPrefix + 'Mindest-Temperatur (' + AutoShading_Temp_min.state.toString() + ') wurde nicht erreicht durch aktuelle Temperatur (' + localCurrentTemperature.state.toString() + ')')
}
end
Ideen?
CYA
Cyrelian
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 05:31
von udo1toni
Eine Funktion endet mit der schließenden eckigen Klammer, nicht mit dem Schlüsselwort end (das hat überhaupt nichts in der Funktion zu suchen).
Allgemein ist der Ansatz der Funktionen in openHAB eher fragwürdig. rikoshak hat da im englischen Forum mal einen längeren Erklär-Artikel geschrieben; Normalerweise gibt es elegantere Ansätze, die ohne Funktionsaufrufe auskommen.
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 10:03
von Cyrelian
Hi,
ups, das war noch ne alte Version. Die eckige Klammer hab ich bereits gefunden

. Du meinst den Artikel oder?
https://community.openhab.org/t/reusabl ... s/15888/11
Mein Ziel ist es eigentlich die Rollladen der verschiedenen Himmelsrichtungen in einer Rule abzufangen. Das würde mit eine Funktion relativ einfach laufen.
Code: Alles auswählen
rule "Abschattung starten"
when
Item Azimuth changed
then
val String logPrefix = 'Abschattung aktivieren - '
if (log) logInfo(filename, logPrefix + 'Regel wurde gestartet')
var String timeLast = 'xxxx-xx-xx'
if (AutoShading_Start_last.state == NULL) {
if (log) logInfo(filename, logPrefix + 'Erstmalige Ausführung, Belegung mit Initialwerten')
} else {
timeLast = AutoShading_Start_last.state.toString().substring(0,10)
}
var String timeNow = now.toString().substring(0,10)
if (AutoShading.state == ON) {
if (timeNow != timeLast) {
//175 >
if ((Azimuth.state as Number).floatValue > (AutoShading_Azimuth_west.state as Number)) {
Shading.apply(gRollladenWest)
return;
}
//110 >
if ((Azimuth.state as Number).floatValue < (AutoShading_Azimuth_south.state as Number)) {
Shading.apply(gRollladenSouth)
return;
}
//70 >
if ((Azimuth.state as Number).floatValue < (AutoShading_Azimuth_east.state as Number)) {
Shading.apply(gRollladenEast)
return;
}
} else {
if (log) logInfo(filename, logPrefix + 'Automatik heute bereits einmal gelaufen, wird daher ignoriert')
}
} else {
if (log) logInfo(filename, logPrefix + 'Beende, da Abschattung deaktiviert ist')
}
end
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 10:16
von PeterA
Cyrelian hat geschrieben: ↑22. Jun 2019 10:03
Hi,
ups, das war noch ne alte Version. Die eckige Klammer hab ich bereits gefunden

. Du meinst den Artikel oder?
https://community.openhab.org/t/reusabl ... s/15888/11
Mein Ziel ist es eigentlich die Rollladen der verschiedenen Himmelsrichtungen in einer Rule abzufangen. Das würde mit eine Funktion relativ einfach laufen.
Code: Alles auswählen
rule "Abschattung starten"
when
Item Azimuth changed
then
val String logPrefix = 'Abschattung aktivieren - '
if (log) logInfo(filename, logPrefix + 'Regel wurde gestartet')
var String timeLast = 'xxxx-xx-xx'
if (AutoShading_Start_last.state == NULL) {
if (log) logInfo(filename, logPrefix + 'Erstmalige Ausführung, Belegung mit Initialwerten')
} else {
timeLast = AutoShading_Start_last.state.toString().substring(0,10)
}
var String timeNow = now.toString().substring(0,10)
if (AutoShading.state == ON) {
if (timeNow != timeLast) {
//175 >
if ((Azimuth.state as Number).floatValue > (AutoShading_Azimuth_west.state as Number)) {
Shading.apply(gRollladenWest)
return;
}
//110 >
if ((Azimuth.state as Number).floatValue < (AutoShading_Azimuth_south.state as Number)) {
Shading.apply(gRollladenSouth)
return;
}
//70 >
if ((Azimuth.state as Number).floatValue < (AutoShading_Azimuth_east.state as Number)) {
Shading.apply(gRollladenEast)
return;
}
} else {
if (log) logInfo(filename, logPrefix + 'Automatik heute bereits einmal gelaufen, wird daher ignoriert')
}
} else {
if (log) logInfo(filename, logPrefix + 'Beende, da Abschattung deaktiviert ist')
}
end
Coole Sache.
Aber wenn die Rule einmal etwas ausgeführt hat dann wird doch ein Zeitstempel Gesetzt damit die Rule nicht noch mal ausführt...
Das würde ja bedeuten es müsste für jede Himmelsrichtung ein eigener Zeitstempel gesetzt werden ?
Gruß Peter
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 11:31
von Cyrelian
Hi Peter,
gutes Auge

. Genau so ist es. Bis jetzt gibt es nur einen Zeitstempel. Ich baue es noch so um, dass jede Himmelsrichtung eine Zeitstempel bekommt.
Bin mir aber noch nicht sicher, ob ich das mit in die Funktion oder in die Rule packe. Eigentlich ist es mir in der Rule lieber, da ich mir dann den Aufruf der Funktion spare...mal schauen

.
Erstmal will ich die Funktion ans laufen bekommen.
CU
Cyrelian
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 14:17
von PeterA
Cyrelian hat geschrieben: ↑22. Jun 2019 11:31
Hi Peter,
gutes Auge

. Genau so ist es. Bis jetzt gibt es nur einen Zeitstempel. Ich baue es noch so um, dass jede Himmelsrichtung eine Zeitstempel bekommt.
Bin mir aber noch nicht sicher, ob ich das mit in die Funktion oder in die Rule packe. Eigentlich ist es mir in der Rule lieber, da ich mir dann den Aufruf der Funktion spare...mal schauen

.
Erstmal will ich die Funktion ans laufen bekommen.
CU
Cyrelian
Top!
Ich bin gespannt. Denn ich habe derzeit für zwei Himmelsrichtungen jeweils zwei individuelle Rules (Schliessen und Öffnen). Wenn man das im eine Rule packen könnte ist das bestimmt besser....
Gruß Peter
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 22. Jun 2019 22:54
von PeterA
Und was natürlich auch besser ist die "Sollwerte" fest in die Rule zu schreiben. Das spart auch das persistieren usw.....
Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen
Verfasst: 16. Jul 2019 15:27
von Cyrelian
Hi,
so, hat was länger gedauert und ich hatte noch ein kleines Problem mit der LAMBDA Funktion, bei der mir Rich aus der Community geholfen hat.
Danke auch an Seppy, bei dem hab ich die "val Map" abgeschaut
Der Ansatz ist etwas anders, da ich viel mit "early returns" gearbeitet habe, sobald ein Parameter nicht zutrifft. Damit wird die rule übersichtlicher (kaum einrücken und verschateln).
Code: Alles auswählen
import java.util.Map
// Das Logging und Messaging kann für diese Rules separat aktiviert werden (log=true)
var boolean log = true
var boolean message = true
val String filename = "shutter.rules"
var boolean returnvalueWest = false
var boolean returnvalueEast = false
var boolean returnvalueSouth = false
val Number blindClosed = 100
val Number blindOpen = 0
val Number blindTranslucent = 35
var Number closingAzimuth_west = 181
var Number closingAzimuth_south = 111
var Number closingAzimuth_east = 65
var Number closingCloudiness = 25
var Number openingTemperature = 22
val Map<String, Number> targetHights = newHashMap (
"KuecheRollladenTuer" -> 58,
"SchlafzimmerRollladenTuer" -> 100,
"BadezimmerRollladen" -> 55,
"WohnzimmerRollladenEsstisch" -> 65,
"WohnzimmerRollladenTuer" -> 68,
"WohnzimmerRollladenBalkon" -> 100
)
/* ------------- Automatische Abschattung ein/aus --------------------
*/
//------------- Abschattung FUNKTION --------------------
val shadingStart = [GroupItem shutter |
val String logPrefix = "Abschattung aktivieren - "
var boolean log = true
logInfo ("Lambda", logPrefix + shutter)
val Map<String, Number> targetHights = newHashMap (
"KuecheRollladenTuer" -> 58,
"SchlafzimmerRollladenTuer" -> 100,
"BadezimmerRollladen" -> 55,
"WohnzimmerRollladenEsstisch" -> 65,
"WohnzimmerRollladenTuer" -> 68,
"WohnzimmerRollladenBalkon" -> 100
)
if ((localCurrentTemperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
if (log) logInfo ("Lambda", logPrefix + "Mindesttemperatur von (" + AutoShading_Temp_min.state.toString() + ") wurde nicht erreicht. Aktuelle Temperatur (" + localCurrentTemperature.state.toString() + ")")
return false;
}
if ((localCurrentCloudiness.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) {
if (log) logInfo ("Lambda", logPrefix + "Aktuelle Bewoelkung (" + localCurrentCloudiness.state.toString() + ") ueberschreitet den eingestellten Grenzwert von (" + AutoShading_Cloudiness_max.state.toString() + ")")
return false;
}
if ((Elevation.state as Number) <= (AutoShading_Elevation_end.state as Number)) {
if (log) logInfo ("Lambda", logPrefix + "Elevation für das Beenden der Abschattung (" + AutoShading_Elevation_end.state.toString() + ") ist groesser als aktuelle (" + Elevation.state.toString() + ")")
return false;
}
// Rollladen werden geschlossen
if (log) 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("Abschattung 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;
]
//------------- Abschattung starten --------------------
rule "Abschattung starten"
when
Time cron "0/30 * * * * ?" or
Item Azimuth changed
then
val String logPrefix = "Abschattung aktivieren - "
//Prüfung ob Abschattungsautomatik an ist und ob es Tag ist
if (AutoShading.state == ON && IsDay.state == ON) {
//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)
}
//Azimuth ist größer als 181° (WEST)
if (returnvalueWest == false) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_west)) {
if (log) logInfo (filename, logPrefix + "Abschatung für Rollläden WEST")
returnvalueWest = shadingStart.apply(gRollladenWest)
return;
}
}
//Azimuth ist größer als 111° (SÜD)
if (returnvalueSouth == false) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_south) && (Azimuth.state as Number).floatValue < (closingAzimuth_west)) {
if (log) logInfo (filename, logPrefix + "Abschatung für Rollläden SÜD")
returnvalueSouth = shadingStart.apply(gRollladenSouth)
return;
}
}
//Azimuth ist größer als 65° (OST)
if (returnvalueEast == false) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_east) && (Azimuth.state as Number).floatValue < (closingAzimuth_south)) {
if (log) logInfo (filename, logPrefix + "Abschatung für Rollläden OST")
returnvalueEast = shadingStart.apply(gRollladenEast)
return;
}
}
} else {
if (log) logInfo(filename, logPrefix + "Abschattung ist deaktiviert, oder es ist Nacht.")
}
end
//------------- Abschattung beenden --------------------
rule "Abschattung beenden"
when
Time cron "0/45 * * * * ?" or
Item Elevation changed
then
if (AutoShading_end.state == ON && IsDay.state == ON) {
val String logPrefix = "Abschattung deaktivieren - "
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow) {
if (log) logInfo(filename, logPrefix + "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if ((localCurrentTemperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
if (log) logInfo(filename, logPrefix + "Beende, aktuelle Temperatur (" + localCurrentTemperature.state.toString() + ") ueberschreitet den eingestellten Grenzwert zum hochfahren von (" + AutoShading_Temp_raise.state.toString()+ ") ")
return;
}
if ((Elevation.state as Number) > (AutoShading_Elevation_end.state as Number)) {
if (log) logInfo(filename, logPrefix + "Beende, aktuelle Elevation (" + Elevation.state.toString() + ") ueberschreitet den eingestellten Grenzwert von (" + AutoShading_Elevation_end.state.toString()+ ") ")
return;
}
if (returnvalueWest == false && returnvalueEast == false && returnvalueSouth == false) {
if (log) logInfo(filename, logPrefix + "Beende, da heute noch keine automatische Abschattung stattfand")
return;
}
if (returnvalueWest == true || returnvalueEast == true || returnvalueSouth == true) {
// Rollladen öffnen
if (log) logInfo(filename, logPrefix + "Rollladen werden geoeffnet")
gRollladen.allMembers.forEach[blind|
if((blind.state as Number).intValue == targetHights.get(blind.name.toString()).intValue) {
if (log) logInfo(filename, logPrefix + "Oeffne Rollladen: " + blind.name.toString())
blind.sendCommand(UP)
//Pushnachricht versenden
sendPushoverMessage(pushoverBuilder("Abschattung für (" + blind.name.toString() + ") beendet, Rollladen wird geöffnet."))
} else {
if (log) logInfo(filename, 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
returnvalueWest = false
returnvalueEast = false
returnvalueSouth = false
}
}
end
Hoffe das hilft dem einen oder anderen weiter oder dient als Gedankenanstoß. Bei Fragen...immer raus damit
CYA
Cyrelian