So... Habe die erste Codezeile von Dir, Udo, eingefügt. Leider kann ich es heute, aufgrund des Wetters, nicht testen.
Keine Ahnung was das bedeutet, aber das "using it anyway" hat mich erstmal beruhigt!
Den zweiten Code von Dir, verstehe ich so, dass erst eine Nachricht versendet wird, wenn alle Rollladen angesteuert wurden. Wenn dem so sein sollte, bleibe ich lieber bei Variante 1. 1. möchte ich immer eine Nachricht, wann Nord, Ost und Süd fährt, 2. fahren nicht immer alle Seiten (z.B. wenn vormittags bewölkt, bleiben Nord und Ost offen),
Und zum Frühling/Sommer nochmal... "Ist nicht" leuchtet mir jetzt ein, hätte ich die Rule geschrieben, hätte ich mir aber gedacht, es müssen im Item "Jahreszeit" dann beide Argumente zutreffen, was ja nie der Fall ist. Daher hätte ich eher ein "oder" verbaut. Und mit einem "oder" sollte doch die Rule trotzdem das Gleiche machen? Oder stehe ich immer noch auf der Leitung??
Code: Alles auswählen
import java.util.Map
var Boolean message = true
val String filename = "shutter.rules"
var DWD1 = null
var DWD2 = null
// Values und Variablen für die Verschattung
//val Number blindClosed = 100
//val Number blindOpen = 0
//val Number blindTranslucent = 35
var Number closingAzimuth_north = 60
var Number closingAzimuth_east = 65
var Number closingAzimuth_south = 111
var Number closingCloudiness = 30
val Number cloudHysteresis = 45 //die Mindestbewölkung in der letzten Stunde
var Number openingTemperature = 22
var Number closingTemperature = 24
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 isActiveNorth = false
var Boolean isActiveEast = false
var Boolean isActiveSouth = false
var Boolean isActiveTerasse = false
//var Boolean isActiveTerassebereitsausgefahren = false
val String logPrefix = "Rollläden - "
/* ------------- Verschattung FUNKTIONEN --------------------
*/
//------------- Verschattung starten --------------------
val shadingStart = [GroupItem shutter |
val String logPrefix = "Verschattung aktivieren - "
val Map<String, Number> targetHights = newHashMap (
"Shellyswitch25LesezimmerRollerControl" -> 40,
"Shellyswitch25BueroRollerControl" -> 100,
"Shellyswitch25SZRechtsRollerControl" -> 90,
"Shellyswitch25SZLinksRollerControl" -> 85,
"Shellyswitch25BadRollerControl" -> 80,
"Shellyswitch25RollladenRaphaelRollerControl" -> 80,
"Shellyswitch25KucheRollerControl" -> 0
)
// Rollladen werden geschlossen
logInfo("rules", logPrefix + "Grenzwerte wurden erreicht, Rollladen werden geschlossen")
shutter.allMembers.forEach[ blind |
if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue) {
logInfo("rules", logPrefix + "Fahre Rollladen (" + blind.name.toString() + ") auf (" + targetHights.get(blind.name.toString()).intValue + ") %" )
blind.sendCommand(targetHights.get(blind.name.toString()).intValue)
//Telegram versenden
val telegramAction = getActions("telegram","telegram:telegramBot:telegram")
//telegramAction.sendTelegram(5128384828L, "Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %%")
blinds.members.forEach[blind|
telegramAction.sendTelegram(5128384828L, "Verschattung für " + blind.label + " aktiviert, schließen auf " + targetHights.get(blind.name) + " %%")
blind.sendCommand(targetHights.get(blind.name))
]
}
else {
logInfo("rules", logPrefix + "Rollladen ist bereits weiter geschlossen (" + blind.state.toString() + "%) als er geschlossen werden sollte und wird daher ignoriert")
}
]
AutoShading_Start_last.postUpdate(new DateTimeType())
return true;
]
//------------- Verschattung beenden -------------------
val shadingEnd = [GroupItem shutter |
val String logPrefix = "Verschattung deaktivieren - "
val Map<String, Number> targetHights = newHashMap (
"Shellyswitch25LesezimmerRollerControl" -> 40,
"Shellyswitch25BueroRollerControl" -> 0,
"Shellyswitch25SZRechtsRollerControl" -> 20,
"Shellyswitch25SZLinksRollerControl" -> 25,
"Shellyswitch25BadRollerControl" -> 0,
"Shellyswitch25RollladenRaphaelRollerControl" -> 40,
"Shellyswitch25KucheRollerControl" -> 0
)
// Rollladen öffnen
logInfo("rules", logPrefix + "Rollladen werden geoeffnet")
shutter.allMembers.forEach[ blind |
if ((blind.state as Number) == targetHights.get(blind.name.toString()).intValue) {
logInfo("rules", logPrefix + "Öffne Rollladen: " + blind.name.toString())
blind.sendCommand(UP)
//Telegram versenden
val telegramAction = getActions("telegram","telegram:telegramBot:telegram")
telegramAction.sendTelegram(5128384828L, "Verschattung für (" + blind.name.toString + ") beendet, Rollladen wird geöffnet.")
blinds.members.forEach[blind|
telegramAction.sendTelegram(5128384828L, "Verschattung für " + blind.label + " beendet, Rollladen wird geöffnet." + targetHights.get(blind.name) + " %%")
blind.sendCommand(targetHights.get(blind.name))
]
} else {
logInfo("rules", 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(new DateTimeType(now.minusDays(1)))
//Variablen zurücksetzen
isActiveNorth = false
isActiveEast = false
isActiveSouth = false
Nordaktiv.sendCommand(OFF)
Ostaktiv.sendCommand(OFF)
Suedaktiv.sendCommand(OFF)
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 / Jahreszeit
if (AutoShading.state != ON) {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da deaktiviert.")
return;
}
if (IsDay.state != ON) {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, es ist Nacht.")
return;
}
if (Jahreszeit.state !="SPRING" && Jahreszeit.state!= "SUMMER") {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
if (AutoShading_Start_last.state == NULL) {
logInfo("rules", logPrefix + "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_Start_last.postUpdate(new DateTimeType(now.minusDays(1)))
}
//Markisenautomatik
if (!isActiveTerasse) /*&& (!isActiveTerassebereitsausgefahren/*Markise_heute_bereits_ausgefahren.changedSince(now.minusMinutes(600),"influxdb") == false)))*/ {
//Azimuth ist größer als 111° (WEST)
if ((Azimuth.state as Number).floatValue > (closingAzimuth_south)) {
logInfo("rules", logPrefix + "Markise Terasse - Azimuth erreicht")
if (((MultisensorXiaomiTemperature.state as Number).floatValue > (AutoShading_Temp_min.state as Number) && (WetterUndWettervorhersageCurrentCloudiness.state as Number).floatValue < (AutoShading_Cloudiness_max.state as Number)) ||
((MultisensorXiaomiTemperature.state as Number).floatValue > (AutoShading_Temp_min.state as Number) && (Sonnensensor_Durchschnitt_20min.state as Number).floatValue > (Autoshading_Lux_max.state as Number))) {
logInfo("rules", logPrefix + "Markise Terasse könnte fahren")
val telegramAction = getActions("telegram","telegram:telegramBot:telegram")
telegramAction.sendTelegram("Verschattung Markise starten?, aktuelle Temperatur %s" + " Helligkeit %s" + " Bewölkung %s", MultisensorXiaomiTemperature.state.toString, Sonnensensor_Durchschnitt_20min.state.toString, WetterUndWettervorhersageCurrentCloudiness.state.toString)
telegramAction.sendTelegramQuery("Verschattung Markise starten?", "Markise_ausfahren", "Ausfahren", "25%", "Nein")
logInfo("rules", logPrefix + "Verschattung (Markise) wird ausgeführt, Aktuelle Temperatur Terasse ({}), aktuelle Helligkeit ({}); aktuelle Bewölkung ist ({}) ", MultisensorXiaomiTemperature.state, Sonnensensor_Durchschnitt_20min.state, WetterUndWettervorhersageCurrentCloudiness.state)
AutoShadingM_Start_last.postUpdate(new DateTimeType())
//isActiveTerassebereitsausgefahren = true
Markiseaktiv.sendCommand(ON)
isActiveTerasse = true;
}
}
}
else {
logInfo("rules", logPrefix + "Verschattung für Terasse bereits aktiviert")
}
/*
//Rollladenautomatik
if (gElternanwesend.state != CLOSED) {
logInfo("rules", logPrefix + "Verschattung (Rollläden) wird nicht ausgeführt, Anwesenheit erkannt.")
return;
}
*/
// 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_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 ((Elevation.state as Number).floatValue <= (AutoShading_Elevation_end.state as Number)) {
logInfo("rules", logPrefix + "Verschattung (Rollläden) wird nicht ausgeführt, Elevation für das Beenden der Verschattung ({}) ist groesser als aktuelle ({}) ", AutoShading_Elevation_end.state, Elevation.state)
return;
}
//
//Azimuth ist größer als 65° (OST)
if (!isActiveEast) {
if ((Azimuth.state as Number).floatValue > (closingAzimuth_east) /*&& (Azimuth.state as Number).floatValue < (closingAzimuth_south)*/ && ((Sonnensensor_Xiaomi_Durchschnitt_20min.state as Number).floatValue ) > (Autoshading_Lux_max_ost.state as Number)) {
logInfo("rules", logPrefix + "Verschattung für Rollläden OST")
isActiveEast = shadingStart.apply(grollladeneast)
Ostaktiv.sendCommand(ON)
return;
}
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden OST bereits aktiviert")
}
//Azimuth ist größer als 60° (NORD)
if (!isActiveNorth) {
if ((MultisensorXiaomiTemperature.state as Number).floatValue <= (AutoShading_Temp_min.state as Number)) {
logInfo("rules", logPrefix + "Verschattung (Rollläden) wird nicht ausgeführt, Mindesttemperatur von ({}) wurde nicht erreicht. Aktuelle Temperatur ({}) ", AutoShading_Temp_min.state, MultisensorXiaomiTemperature.state)
return;
}
if (((Azimuth.state as Number).floatValue > (closingAzimuth_north)) && ((Sonnensensor_Xiaomi_Durchschnitt_20min.state as Number).floatValue ) > (Autoshading_Lux_max_ost.state as Number)) {
logInfo("rules", logPrefix + "Verschattung für Rollläden NORD")
isActiveNorth = shadingStart.apply(grollladennord)
Nordaktiv.sendCommand(ON)
return;
}
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden NORD bereits aktiviert")
}
if ((Sonnensensor_Durchschnitt_20min.state as Number).floatValue < (Autoshading_Lux_max.state as Number)) {
logInfo("rules", logPrefix + "Verschattung (Rollladen Süd) wird nicht ausgeführt, aktuelle Lichtstärke ({}) unterrschreitet den eingestellten Grenzwert von ({})", Sonnensensor_Durchschnitt_20min.state, Autoshading_Lux_max.state)
return;
}
//Azimuth ist größer als 111° (SÜD)
if (!isActiveSouth) {
if (((Azimuth.state as Number).floatValue > (closingAzimuth_south)) && ((Sonnensensor_Durchschnitt_20min.state as Number).floatValue > (Autoshading_Lux_max.state as Number)) /*&& (Azimuth.state as Number).floatValue < (closingAzimuth_north)*/) {
logInfo("rules", logPrefix + "Verschattung für Rollläden SÜD")
isActiveSouth = shadingStart.apply(grollladensued)
Suedaktiv.sendCommand(ON)
return;
}
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden SÜD bereits aktiviert")
}
end
//------------- Verschattung beenden --------------------
rule "Verschattung beenden"
when
Item Elevation changed
then
val String logPrefix = "Verschattung deaktivieren - "
//Prüfung auf: Verschattungsautomatik an / ob es Tag ist / Jahreszeit
if (AutoShading_end.state != ON) {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da deaktiviert.")
return;
}
if (IsDay.state != ON) {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, es ist Nacht.")
return;
}
if (Jahreszeit.state !="SPRING" && Jahreszeit.state!= "SUMMER") {
logInfo("rules", logPrefix + "Verschattung wird nicht ausgeführt, da weder, Frühling noch Sommer.")
return;
}
val Boolean isRainLastHour = (WetterUndWettervorhersageCurrentRain.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
logInfo("rules", logPrefix + "Rain " + isRainLastHour)
val Boolean isCloudLastHour = (WetterUndWettervorhersageCurrentCloudiness.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
logInfo("rules", logPrefix + "Clouds " + isCloudLastHour )
val Boolean isTemperature = ((MultisensorXiaomiTemperature.state as Number).floatValue < ((MultisensorXiaomiTemperature.minimumSince(now.minusHours(1), "influxdb").state as Number).floatValue -(temperatureHysteresis)))
logInfo("rules", logPrefix + "Temperatur " + isTemperature)
if (AutoShading_End_last.state === NULL || AutoShadingM_End_last.state === NULL) {
logInfo("rules", logPrefix + "Letzte Ausführung unbekannt, Belegung mit Initialwert (-1 Tag)")
AutoShading_End_last.postUpdate(new DateTimeType(now.minusDays(1)))
AutoShadingM_End_last.postUpdate(new DateTimeType(now.minusDays(1)))
}
var String timeNow = now.toString().substring(0,10)
var String timeLastEnde = AutoShading_End_last.state.toString().substring(0,10)
var String timeLastEndeM = AutoShadingM_End_last.state.toString().substring(0,10)
if (timeLastEnde == timeNow && timeLastEndeM == timeNow) {
logInfo("rules", logPrefix + "Beende, da heute bereits ein automatisches Hochfahren stattfand")
return;
}
if (!isActiveNorth && !isActiveEast && !isActiveSouth && !isActiveTerasse) {
logInfo("rules", logPrefix + "Beende, da heute noch keine automatische Verschattung stattfand")
return;
}
if (isTemperature) {
logInfo("rules", logPrefix + "Verschattung beenden, Temperaturabfall von min. ({})° erkannt", temperatureHysteresis)
Markise.sendCommand(0)
AutoShadingM_End_last.postUpdate(now.toLocalDateTime().toString())
shadingEnd.apply(gRollladen)
return;
}
if ((MultisensorXiaomiTemperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
logInfo("rules", logPrefix + "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",MultisensorXiaomiTemperature.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)
Markise.sendCommand(0)
AutoShadingM_End_last.postUpdate(new DateTimeType())
shadingEnd.apply(gRollladen)
return;
}
if ((Elevation_shutter.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 (isActiveTerasse) {
logInfo("rules", logPrefix + "Verschattung Terasse beenden")
Markise.sendCommand(0)
AutoShadingM_End_last.postUpdate(new DateTimeType())
}
if (isActiveNorth || isActiveEast || isActiveSouth ) {
logInfo("rules", logPrefix + "Verschattung Rollläden beenden")
shadingEnd.apply(gRollladen)
return;
}
end
/* ------------- Verschattung Variablen zurücksetzen wenn kein automtisches hochfahren erfolgt --------------------
*/
rule "Verschattung Variablen zurücksetzen"
when
Time cron "0 0 23 * * ?" or
Channel 'astro:sun:home:nauticDusk#event' triggered END
then
logInfo("rules", logPrefix + "Verschattung Variablen zurücksetzen")
isActiveNorth = false
isActiveEast = false
isActiveSouth = false
isActiveTerasse = false
Nordaktiv.sendCommand(OFF)
Ostaktiv.sendCommand(OFF)
Suedaktiv.sendCommand(OFF)
Markiseaktiv.sendCommand(OFF)
end
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 (isActiveNorth) {
logInfo("rules", logPrefix + "Verschattung für Rollläden NORD aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Rollläden NORD 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 (isActiveTerasse) {
logInfo("rules", logPrefix + "Verschattung für Markise (Terasse) aktiv")
} else {
logInfo("rules", logPrefix + "Verschattung für Markise (Terasse) inaktiv")
}
/* if (isActiveTerassebereitsausgefahren) {
logInfo("rules", logPrefix + "Verschattung für Markise (Terasse) heute bereits einmal automatisch ausgefahren")
} else {
logInfo("rules", logPrefix + "Verschattung für Markise (Terasse) heute noch nicht automatisch ausgefahren")
}*/
}
case "reset" : {
logInfo("rules", logPrefix + "Verschattung Variablen reset")
isActiveNorth = false
isActiveEast = false
isActiveSouth = false
isActiveTerasse = false
Nordaktiv.sendCommand(OFF)
Ostaktiv.sendCommand(OFF)
Suedaktiv.sendCommand(OFF)
Markiseaktiv.sendCommand(OFF)
//isActiveTerassebereitsausgefahren = false
}
}
Shading_Var.postUpdate(NULL)
end
rule "Test Telegram Markise ausfahren"
when
Item telegramReplyId received update Markise_ausfahren
then
val telegramAction = getActions("telegram","telegram:telegramBot:telegram")
if (telegramMessage.state.toString == "Ausfahren")
{
telegramAction.sendTelegramAnswer(telegramReplyId.state.toString, "Ok, Markise wird ausgefahren! Info: ")
var DWD1 = DWDUnwetterWarnungenOnset1.state.toString
var DWD2 = DWDUnwetterWarnungenDescription1.state.toString
telegramMessage.postUpdate(DWD1)
telegramAction.sendTelegram(DWD1)
telegramMessage.postUpdate(DWD2)
telegramAction.sendTelegram(DWD2)
Markise.sendCommand(100)
}
if (telegramMessage.state.toString == "25%")
{
telegramAction.sendTelegramAnswer(telegramReplyId.state.toString, "Ok, Markise wird auf 25% ausgefahren! Info: ")
var DWD1 = DWDUnwetterWarnungenOnset1.state.toString
var DWD2 = DWDUnwetterWarnungenDescription1.state.toString
telegramMessage.postUpdate(DWD1)
telegramAction.sendTelegram(DWD1)
telegramMessage.postUpdate(DWD2)
telegramAction.sendTelegram(DWD2)
Markise.sendCommand(75)
}
if (telegramMessage.state.toString == "Nein")
{
telegramAction.sendTelegramAnswer(telegramReplyId.state.toString, "Ok, Markise wird NICHT ausgefahren!")
}
end
rule "Tag und Nacht"
when
Item Elevation changed or System started
then
if (Elevation.state > 0|°) {
if (IsDay.state==OFF || IsDay.state==NULL || IsDay.state==UNDEF) {
logInfo("AstroRules:Tag und Nacht", "Sonnenstand > 0 Grad - Es ist Tag")
sendCommand(IsTwilight, OFF)
sendCommand(IsDay, ON)
sendCommand(IsNight, OFF)
}
}
if (Elevation.state <= 0|° && Elevation.state >= -6|°) {
if (IsDay.state==ON || IsDay.state==NULL || IsDay.state==UNDEF) {
logInfo("AstroRules:Tag und Nacht", "Sonnenstand ist zwischen 0 und -6 Grad - Es ist Abenddämmerung")
sendCommand(IsTwilight, ON)
sendCommand(IsDay, OFF)
sendCommand(IsNight, ON)
}
}
if (Elevation.state < -6|°) {
if (IsTwilight.state==ON || IsTwilight.state==NULL || IsTwilight.state==UNDEF) {
logInfo("AstroRules:Tag und Nacht", "Sonnenstand < -6 Grad - Es ist Nacht")
sendCommand(IsTwilight, OFF)
sendCommand(IsDay, OFF)
sendCommand(IsNight, ON)
}
}
end
Und hier die Rollladensteuerung Items (es fehlen die astro-, Temperatur-, Helligkeits- und Rollladen-Items, da individuell):