Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
Benutzeravatar
Cyrelian
Beiträge: 601
Registriert: 24. Sep 2015 17:55
Answers: 4

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von Cyrelian »

Hi,

hier der letzte Stand, verfeinert mit euren Ideen ;) .

ITEMS:

Code: Alles auswählen

/* -------------  Rollladensteuerung --------------------
 */

// -------------  Manuell --------------------
Switch		ManualShading				"Manuelle Verschattung an/aus"																(gInitializeOff)
String		Shading_Var				"Verschattungsvariablen"												<time>				(gShading)

// -------------  Automatic --------------------
Switch		AutoShading			"Automatische Verschattung"																	(gShading,gInitializeOn)
Switch		AutoShading_end			"Rollladen automatisch öffnen"																(gShading,gInitializeOn)
Number		AutoShading_Temp_min		"Temperatur größer [%d °C]"												<temperature>		(gShading)
Number		AutoShading_Temp_raise		"Temperatur zum hochfahren der Rollladen [%d °C]"						<temperature>		(gShading)
Number		AutoShading_Temp_diff		"Temperaturunterschied der letzten Stunde [- %d °C]"					<temperature>		(gShading)
Number		AutoShading_Cloudiness_max	"Bewölkung weniger als [%d Prozent]"									<sun_clouds>		(gShading)
Number		AutoShading_Cloudiness_Hyst	"Durchschn. Bewölkung der letzten Stunde größer gleich [%d Prozent]"	<sun_clouds>		(gShading)
Number		AutoShading_Rain_min		"Mindestregenmenge der letzten Stunde größer gleich [%.2f mm/h]"		<sun_clouds>		(gShading)
Number		AutoShading_Azimuth_east	"Sonnenrichtung / Azimuth (Ost) größer gleich [%d °]"					<compass>			(gShading)
Number		AutoShading_Azimuth_south	"Sonnenrichtung / Azimuth (Süd) größer gleich [%d °]"					<compass>			(gShading)
Number		AutoShading_Azimuth_west	"Sonnenrichtung / Azimuth (West) größer gleich [%d °]"					<compass>			(gShading)
Number		AutoShading_Elevation_end	"Sonnenhöhe / Elevation kleiner gleich [%d °]"							<niveau>			(gShading)
DateTime	AutoShading_Start_last		"Letzte Ausführung (Rollladen ab) [%1$td.%1$tm %1$tH:%1$tM Uhr]"		<time>				(gShading)
DateTime	AutoShading_End_last		"Letzte Ausführung (Rollladen hoch) [%1$td.%1$tm %1$tH:%1$tM Uhr]"		<time>				(gShading)
DateTime	AutoShadingM_Start_last		"Letzte Ausführung (Markisen ausfahren) [%1$td.%1$tm %1$tH:%1$tM Uhr]"	<time>				(gShading)
DateTime	AutoShadingM_End_last		"Letzte Ausführung (Markiesen einfahren) [%1$td.%1$tm %1$tH:%1$tM Uhr]"	<time>				(gShading)
RULES:

Code: Alles auswählen

import java.util.Map

var Boolean message = true

val String filename = "shutter.rules"

// Values und Variablen für die Verschattung

//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 = 20   
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 isActiveWest = false
var Boolean isActiveEast = false
var Boolean isActiveSouth = false
var Boolean isActiveBalkon = 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 ( 
                "KuecheRollladenTuer" -> 58,
                "SchlafzimmerRollladenTuer" -> 100,
                "BadezimmerRollladen" -> 55,
                "WohnzimmerRollladenEsstisch" -> 65,
                "WohnzimmerRollladenTuer" -> 68,
                "WohnzimmerRollladenBalkon" -> 100,
                "GaesteWCRollladen_Slider" -> 100,
                "BueroRollladen" -> 100
                )
                // Rollladen werden geschlossen
                logInfo("rules", logPrefix + "Grenzwert 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)
                        //Pushnachricht versenden
                        sendPushoverMessage(pushoverBuilder("Verschattung für " + blind.name.toString + " aktiviert, schließen auf " + targetHights.get(blind.name.toString()).toString() + " %"))
                    } 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(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,
                    "WohnzimmerRollladenTuer" -> 68,
                    "WohnzimmerRollladenBalkon" -> 100,
                    "GaesteWCRollladen_Slider" -> 100,
                    "BueroRollladen" -> 100
                     )
                    // 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 + "Oeffne Rollladen: " + blind.name.toString())
                            blind.sendCommand(UP)
                            //Pushnachricht versenden                        
                            sendPushoverMessage(pushoverBuilder("Verschattung für (" + blind.name.toString() + ") beendet, Rollladen wird geöffnet."))
                        } 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(now.toString())
                    
                    //Variablen zurücksetzen
                    isActiveWest = false
                    isActiveEast = false
                    isActiveSouth = 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 / 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(now.minusDays(1).toString())
    }

    //Markisenautomatik
        if (!isActiveBalkon) {
        //Azimuth ist größer als 181° (WEST)
            if ((Azimuth.state as Number) > (closingAzimuth_west)) {
                if ((BalkonTemperatursensor_Temperature.state as Number).floatValue > (AutoShading_Temp_min.state as Number) && (OW_localCurrentCloudiness.state as Number).floatValue < (AutoShading_Cloudiness_max.state as Number)) { 
                    logInfo("rules", logPrefix + "Markise Balkon")
                    gBalkonRollladen.sendCommand(UP)
                    AutoShadingM_Start_last.postUpdate(now.toString())
                    isActiveBalkon = true;      
                }
            }    
        } else {
            logInfo("rules", logPrefix + "Verschattung für Balkon bereits aktiviert")
        }

    //Rollladenautomatik
    if (gPresence.state != OFF) {                                                                           
        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_west.state == NULL)    AutoShading_Azimuth_west.postUpdate(closingAzimuth_west)
    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 ((OW_localCurrentTemperature.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, OW_localCurrentTemperature.state)
            return;
    }

    if ((OW_localCurrentCloudiness.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) { 
            logInfo("rules", logPrefix + "Verschattung (Rollläden) wird nicht ausgeführt, Aktuelle Bewoelkung ({}) ueberschreitet den eingestellten Grenzwert von ({})", OW_localCurrentCloudiness.state, AutoShading_Cloudiness_max.state)
            return;
    }

    if ((Elevation.state as Number) <= (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 181° (WEST)
    if (!isActiveWest) { 
        if ((Azimuth.state as Number).floatValue > (closingAzimuth_west)) {
            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")
        }
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 = (OW_localCurrentRainVolume.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
    logInfo("rules", logPrefix + "Rain " + isRainLastHour)
    
    val Boolean isCloudLastHour = (OW_localCurrentCloudiness.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
    logInfo("rules", logPrefix + "Clouds " + isCloudLastHour )
    
    val Boolean isTemperature = ((gTemperaturesOut.state as Number).intValue < (gTemperaturesOut.minimumSince(now.minusHours(1), "influxdb").state as DecimalType -(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(now.minusDays(1).toString())
            AutoShadingM_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)
    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 (!isActiveWest && !isActiveEast && !isActiveSouth && !isActiveBalkon) {
        logInfo("rules", logPrefix + "Beende, da heute noch keine automatische Verschattung stattfand")
        return;
    }

    if (isTemperature) {
        logInfo("rules", logPrefix + "Verschattung beenden, Temperaturabfall von min. ({})° erkannt", temperatureHysteresis)
        gBalkonRollladen.sendCommand(DOWN)
        AutoShadingM_End_last.postUpdate(now.toString())
        shadingEnd.apply(gRollladen)
        return;
    }

    if ((gTemperaturesOut.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
        logInfo("rules", logPrefix + "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",gTemperaturesOut.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)
        gBalkonRollladen.sendCommand(DOWN)
        AutoShadingM_End_last.postUpdate(now.toString())
        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 (isActiveBalkon) {
        logInfo("rules", logPrefix + "Verschattung Balkon beenden")
        gBalkonRollladen.sendCommand(DOWN)
        AutoShadingM_End_last.postUpdate(now.toString())
    }

    if (isActiveWest || 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")
        isActiveWest = false
        isActiveEast = false
        isActiveSouth = false
        isActiveBalkon = false
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 (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
SITEMAP:

Code: Alles auswählen

			Frame item=gRollladen label="Rollladensteuerung"{
				Switch	item=gRollladen label="Alle Rollläden" mappings=[UP="▲", STOP="X", DOWN="▼"]					
				Text 	item=gShading label="Automatische Verschattung" icon="rollershutter" {
					Frame label="Verschattung aktivieren/deaktivieren" {
							Switch		item=AutoShading mappings=[ON="An", OFF="Aus"]
							Switch 		item=AutoShading_end mappings=[ON="An", OFF="Aus"]
							Switch 		item=Shading_Var mappings=[queryState="Query STATE", reset="Reset"]
						}
					Frame label="Verschattung starten, wenn..." {
							Setpoint 	item=AutoShading_Temp_min minValue=18 maxValue=40 step=1
							Text		item=gTemperaturesOut valuecolor=[>27="red",>20="orange",>10="purple",>5="green",<=5="blue"]
							Setpoint	item=AutoShading_Cloudiness_max minValue=0 maxValue=100 step=5
							Text 		item=gCloudiness
							//Text		item=AutoShading_Azimuth_east	//minValue=45 maxValue=110 step=5
							//Text		item=AutoShading_Azimuth_south	//minValue=111 maxValue=180 step=5
							//Text	 	item=AutoShading_Azimuth_west 	//minValue=181 maxValue=340 step=5
							Default 	item=Azimuth
							Text		item=AutoShading_Start_last
							Text		item=AutoShadingM_Start_last
						}
					Frame label="Verschattung beenden, wenn..." {
							Setpoint 	item=AutoShading_Elevation_end minValue=-20 maxValue=60 step=1
							Setpoint	item=AutoShading_Temp_raise minValue=15 maxValue=30 step=1
							Text		item=AutoShading_Temp_diff
							Text		item=AutoShading_Cloudiness_Hyst
							Text		item=AutoShading_Rain_min
							Default 	item=Elevation
							Text		item=AutoShading_End_last
							Text		item=AutoShadingM_End_last	
						}
					Frame label="Statistik" {
							Webview icon=none url="http://192.168.x.x:8080/static/chartTemperatureDay.html" height=28
						}
				}
				Switch	item=ShutterControll mappings=[ON="Auto", OFF="Manuell"]
				Switch	item=ManualShading mappings=[ON="An", OFF="Aus"]	
			}
CYA
Cyrelian

cupra6
Beiträge: 35
Registriert: 4. Jan 2019 22:09

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von cupra6 »

Heisst die Rule Datei eigentlich : shutter.rules ?
Ich frage wegen diesem Eintrag in der RULE Datei:

val String filename = "shutter.rules"


Dann würde ich gerne wissen, wofür es das Item ShutterControll gibt und die Gruppe gShading ?

Benutzeravatar
Cyrelian
Beiträge: 601
Registriert: 24. Sep 2015 17:55
Answers: 4

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von Cyrelian »

cupra6 hat geschrieben: 22. Jul 2020 17:13 Heisst die Rule Datei eigentlich : shutter.rules ?
Ich frage wegen diesem Eintrag in der RULE Datei:

val String filename = "shutter.rules"


Dann würde ich gerne wissen, wofür es das Item ShutterControll gibt und die Gruppe gShading ?
Hi,

ja, die Datei selbst heißt shutter.rules.
Das val String filename = "shutter.rules" habe ich für das logging benutzt, damit ich wusste aus welchem rule file die Meldung kommt, da ich Anfangs diverse Rules pro file hatte, ist aber mittlerweile obsolet.

ShutterControll: Damit wird die automatische Verschattung aktiviert/deaktiviert
gShading: Die Gruppe ist eher zum organiesieren der ITEMS wie die oben in den POST unter ITEMS sehen kannst. Da sind alle ITEMS drin die etwas mit der Verschattung zu tun haben.

CU
Cyrelian

HansDampf
Beiträge: 34
Registriert: 23. Jul 2020 15:01
Answers: 1

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von HansDampf »

udo1toni hat geschrieben: 15. Jul 2020 15:14 Ja, das mit dem return false; ist mir auch durchgerutscht. Das ist in der Tat Quatsch. Mach einfach das false weg, so dass nur return; übrig bleibt.

Ansonsten sind halt noch weitere Fehler in der Rule drin.
myGroup wird innerhalb einer Bedingung definiert, somit ist myGroup anschließend (außerhalb der Bedingung) nicht mehr definiert.
Außerdem wird versucht, der Konstanten einfach ein Item zuzuweisen. So geht das aber nicht.
Das korrekte Vorgehen ist, das passende Item aus einer Liste von Items herauszusuchen. Am einfachsten machst Du das, indem Du die vier Group Items
gRollladenX in einer Gruppe zusammenfasst:

Code: Alles auswählen

Group gGroups
Group gRollladenNorth (gGroups)
Group gRollladenEast (gGroups)
Group gRollladenSouth (gGroups)
Group gRollladenWest (gGroups)
Nun kannst Du über gGroups zugreifen. Nur der Teil des Codes, in dem die richtige Gruppe für die Beschattung bestimmt wird:

Code: Alles auswählen

    var String strGroup = ""
    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")
                strGroup = "gRollladenNorth"
                isActiveNorth = true
            }
        }
        case nAz > closingAzimuth_west : { // hinreichend, da 1. Bedingung nicht zutrifft
                if(!isActiveWest) {
                logInfo ("shading", "Verschattung für Rollläden WEST")
                strGroup = "gRollladenWest"
                isActiveWest = true
            }
        }
        case nAz > closingAzimuth_south : {// hinreichend, da 2. Bedingung nicht zutrifft
            if(!isActiveSouth) {
                logInfo ("shading", "Verschattung für Rollläden SÜD")
                strGroup = "gRollladenSouth"
                isActiveSouth = true
            }
        }
        case nAz > closingAzimuth_east : {// hinreichend, da 3. Bedingung nicht zutrifft
            if(!isActiveEast){
                logInfo ("shading", "Verschattung für Rollläden OST")
                strGroup = "gRollladenEast"
                isActiveEast = true
            }
        }
    }
    if(strGroup == "") { // myGroup ist leer bzw. nicht definiert
        logInfo ("shading", "Verschattung bereits aktiv oder außerhalb des Verschattungsbereichs")
        return;
    }
    val myGroup = gGroups.members.filter[i|i.name == strGroup].head
Der Trick besteht hier zum einen darin, den Namen des Gruppenitems in einer String Variablen zu speichern.
Anschließend wird die String Variable geprüft und gegebenenfalls wird das Objekt myGroup passend gefüllt.
habe das ganze mal für mich übernommen. Leider funktioniert es nicht weil folgende Ausgabe kommt:
2020-07-23 11:16:13.643 [INFO ] [lipse.smarthome.model.script.shading] - Rain false
2020-07-23 11:16:13.657 [INFO ] [lipse.smarthome.model.script.shading] - Aktuelle Bewoelkung 46 % % ueberschreitet den eingestellten Grenzwert von 40 %
2020-07-23 11:16:13.669 [INFO ] [lipse.smarthome.model.script.shading] - Home_Current_Cloudiness false
2020-07-23 11:16:13.693 [INFO ] [lipse.smarthome.model.script.shading] - Temperatur false
2020-07-23 11:16:13.721 [INFO ] [lipse.smarthome.model.script.shading] - Beende, da heute noch keine automatische Verschattung stattfand

Letzte Ausführung war am:
Letzte Ausführung (Rollladen ab) 22.07 10:01 Uhr

Es ändert sich danach nichts mehr. Die Abfrage scheint nicht zu passen oder die Variable ist nicht vergeben.

Anbei die Rules:

Code: Alles auswählen

import java.util.Map

// Values und Variablen für die Verschattung

//val Number blindClosed = 100
//val Number blindOpen = 0
//val Number blindTranslucent = 35

var Number closingAzimuth_east = 86
var Number closingAzimuth_south = 132
var Number closingAzimuth_west = 206
var Number closingAzimuth_north = 290

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

var String strGroup = ""

val Map<String, Number> targetHights = newHashMap ( 
    "EG_Arbeitszimmer_Ost" -> 70,
    "EG_Arbeitszimmer_Sued" -> 70,
    "EG_Jalousie_Essen_Tuere_West" -> 65,
    "EG_Jalousie_Schiebetuere_rechts_Sued" -> 65,
    "EG_Jalousie_Schiebetuere_Sued" -> 65,
    "EG_Fenster_West" -> 70,
    "EG_Tuere_Kueche" -> 70,
    "OG_Ankleide" -> 70,
    "OG_Elternschlafen_West" -> 100,
    "OG_Elternschlafen_Sued" -> 100,
    "OG_Kinderbad" -> 100,
    "OG_Amelie_Sued" -> 100,
    "OG_Amelie_Ost" -> 100,
    "OG_Emil_Ost" -> 100,
    "KG_Hobbyraum_Abstellraum" -> 99
)

// Variablen ob verschattet wurde, prüfen
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 (isActiveNorth) {
                            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
                    isActiveNorth = false
                }
        }
        Shading_Var.postUpdate(NULL) 
end


/* -------------  Verschattung FUNKTIONEN --------------------
*/
//-------------  Verschattung starten --------------------

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 (Tag_Nacht.state != OFF) {                                                                        // 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 ((Home_Current_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, Home_Current_Temperature.state)
        return;
    }
    if ((Home_Current_Cloudiness.state as Number).floatValue > (AutoShading_Cloudiness_max.state as Number)) { 
        logInfo ("shading", "Aktuelle Bewoelkung {} % ueberschreitet den eingestellten Grenzwert von {} %", Home_Current_Cloudiness.state, AutoShading_Cloudiness_max.state)
        return;
    }
    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;
    }
    
    val nAz = Azimuth.state as Number.floatValue

    //Azimuth ist größer als 290° (NORD)
    strGroup = ""
    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")
                strGroup = "gRollladenNorth"
                isActiveNorth = true
            }
        }
        case nAz > closingAzimuth_west : { // hinreichend, da 1. Bedingung nicht zutrifft
                if(!isActiveWest) {
                logInfo ("shading", "Verschattung für Rollläden WEST")
                strGroup = "gRollladenWest"
                isActiveWest = true
            }
        }
        case nAz > closingAzimuth_south : {// hinreichend, da 2. Bedingung nicht zutrifft
            if(!isActiveSouth) {
                logInfo ("shading", "Verschattung für Rollläden SÜD")
                strGroup = "gRollladenSouth"
                isActiveSouth = true
            }
        }
        case nAz > closingAzimuth_east : {// hinreichend, da 3. Bedingung nicht zutrifft
            if(!isActiveEast){
                logInfo ("shading", "Verschattung für Rollläden OST")
                strGroup = "gRollladenEast"
                isActiveEast = true
            }
        }
    }
    if(strGroup == "") { // myGroup ist leer bzw. nicht definiert
        logInfo ("shading", "Verschattung bereits aktiv oder außerhalb des Verschattungsbereichs")
        return;
    }
    val myGroup = gGroups.members.filter[i|i.name == strGroup].head
    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 (Tag_Nacht.state != OFF) {                                                                        // 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 = (Home_Current_RainVolume.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
    logInfo("shading", "Rain " + isRainLastHour)
    val boolean isCloudLastHour = (Home_Current_Cloudiness.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
    logInfo("shading", "Home_Current_Cloudiness " + isCloudLastHour )
    val boolean isTemperature = ((Home_Current_Temperature.state as Number).intValue < (Home_Current_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 ((Home_Current_Temperature.state as Number).floatValue > (AutoShading_Temp_raise.state as Number)) {
        logInfo("shading", "Beende, aktuelle Temperatur ({})° ueberschreitet den eingestellten Grenzwert zum hochfahren von ({})°",Home_Current_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
Für Hilfe wäre ich sehr dankbar. Danke euch für die Erstellung der Verschattung!

asd
Beiträge: 4
Registriert: 17. Jul 2020 16:04

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von asd »

Hallo,

danke für den aktuellen Code. Dazu habe ich habe einige grundsätzliche Verständnisfragen.

Warum gibt es AutoShading und ShutterControll? Wo ist genau der Unterschied?
Was hat es mit der Shading_Var "Verschattungsvariablen" auf sich?

Warum gibt es Cloudiness doppelt?
- Number gCloudiness -> Bedeutet g group? Wenn ja, welche items befinden sich in der Gruppe?
- Number OW_localCurrentCloudiness -> OW scheint OpenWeather zu bedeuten.

Warum gibt es Temperature doppelt?
- Number gTemperaturesOut -> Hier scheint es sich um eine Aussentempertur zu handeln.
- Number OW_localCurrentTemperature -> Das kann eigentlich auch nur eine Aussentemperature sein.

Switch gPresence -> Welche items befinden sich in der Gruppe?

Ist der Gruppenaufbau so korrekt?

Group gRollladen
Group gRollladenNorth "Rollläden Nord" (gRollladen) -> Hat die gRolladenNorth eigentlich einen Sinn? Im Norden gibt es keine Sonne.
Group gRollladenEast "Rollläden Ost" (gRollladen) -> Hier werden vermutlich die einzelnen Rollläden bzw. Raffstores für die einzelnen Richtungen zugeordnet.
Group gRollladenSouth "Rollläden Süd" (gRollladen)
Group gRollladenWest "Rollläden West" (gRollladen)

Was macht der folgende Code / Struktur genau?

val Map<String, Number> targetHights = newHashMap (
"KuecheRollladenTuer" -> 58,
"SchlafzimmerRollladenTuer" -> 100,
"BadezimmerRollladen" -> 55,
"WohnzimmerRollladenEsstisch" -> 65,
"WohnzimmerRollladenTuer" -> 68,
"WohnzimmerRollladenBalkon" -> 100,
"GaesteWCRollladen_Slider" -> 100,
"BueroRollladen" -> 100 )

Warum gibt es so viele unterschiedliche targetHights? Vermutlich ein Prozentwert. Wie ist targetHights definiert? % Geschlossen oder % Offen?

Hier werden vermutlich die Boolean Wert in der Influxdb persistiert. Gibt es dazu eine Strategie Definition?

- val Boolean isRainLastHour = (OW_localCurrentRainVolume.maximumSince(now.minusHours(1), "influxdb").state >= (minPrecip))
- val Boolean isCloudLastHour = (OW_localCurrentCloudiness.averageSince(now.minusHours(1), "influxdb")as Number >= (cloudHysteresis))
- val Boolean isTemperature = ((gTemperaturesOut.state as Number).intValue < (gTemperaturesOut.minimumSince(now.minusHours(1), "influxdb").state ....

Danke für eure Hilfe.

lg asd

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von udo1toni »

Ohne den Code selbst einzusetzen...

Mit AutoShading wird die gesamte Funktion bei Bedarf deaktiviert, es ist also der Hauptschalter der Funktion.

ShutterControl... finde ich in der Rule gar nicht.

gCloudiness ... finde ich ebenfalls nicht. Reden wir vom gleichen Code?

gTemperaturesOut sind die Außentemperaturen der Außenfühler (wage ich mal zu behaupten)

OW_localCurrentTemperature und OW_localCurrentCloudiness sind logischerweise die von openWeather gelieferten Daten.

gPresence... darin enthalten sind halt alle Items, die Präsenz melden, wie auch immer das realisiert ist. z.B. könnten das Items sein, die anzeigen, ob Handys im LAN eingebucht sind (wird gern als Indikator für Anwesenheit genutzt). Letztlich musst Du selbst entscheiden, was Du da rein packen musst.

Ein Haus hat gewöhnlich vier Seiten. Dabei kann die Sonne in unseren Breiten nicht direkt aus Norden scheinen, andererseits sind die wenigsten Häuser exakt in die vier Himmelsrichtungen ausgerichtet. Außerdem kann auch die Nordseite eines Hauses durchaus (schräg) Sonnenlicht abbekommen, selbst in unseren Breiten. Vermutlich wäre es sinnvoller, die Seiten als 1,2,3 und 4 zu bezeichnen, schon vor dem Hintergrund der meist nicht exakten Ausrichtung.

ie Hasmap targetHights ist eine Zuordnung String zu Number. Der String ist der Name des Items, die Zahl ist die Zielhöhe des Bahangs. Somit kann jeder Rollladen/Jalousie/Vorhang/Was-auch-immer eine individuelle Position einnehmen, wenn die Beschattung aktiviert wird. in openHAB ist der Rollladen korrekt definiert ;) (Der Rollladen ist das exakte Gegenteil eines Dimmers - der Dimmer macht zu 100% hell, kann aber bei 0% nicht dunkler machen; der Rollladen macht zu 100% dunkel, kann aber bei 0% nicht heller machen.)
Die konkreten Behanghöhen musst Du natürlich selbst definieren. :)

Die val Boolean ... sind Konstanten, die an dieser Stelle definiert werden. Dazu wird die influxdb Persistence ausgelesen. Natürlich müssen alle Items, die über Persistence ausgelesen werden sollen, vorher persistiert worden sein. Für influxdb ist eine everyChange Strategie ausreichend.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Cyrelian
Beiträge: 601
Registriert: 24. Sep 2015 17:55
Answers: 4

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von Cyrelian »

Hi,

Udo hat recht, Du hast hier verschiedene "Codes" miteinander vermischt. Udo hats aber bereits schon super erklärt.
Am besten baust Du erstmal deine ITEMS und Rules und postest sie dann, dann können wir auch gezielter helfen ;)

CY
Cyrelian

cupra6
Beiträge: 35
Registriert: 4. Jan 2019 22:09

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von cupra6 »

Ich glaube was "asd" meinte, sind z.B. der ShutterControll Switch in der SITEMAP, und nicht in den .RULES

Switch item=ShutterControll mappings=[ON="Auto", OFF="Manuell"]
Switch item=ManualShading mappings=[ON="An", OFF="Aus"]

Wenn dieser Switch schon existiert: Switch item=AutoShading mappings=[ON="An", OFF="Aus"]

Warum gibt es noch den "ShutterControll" zusätzlich?



Genau so wie "asd", auch hier frage ich mich, was bewirkt bzw. was passiert wenn man den "Shading_Var" mit den 2 Optionen: QUERY STATE und RESET drückt?


Ein paar Zusatzwünsche würde ich gerne noch einbauen:
1. Ich möchte, dass die Verschattung auch dann passiert, wenn die Rollos ganz runtergefahren sind, z.B. 100%.

Dies wird in dieser Zeile festgelegt:

if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue)

Würde es reichen, wenn ich diese Zeile so abändern würde:

if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue || (blind.state as Number) > targetHights.get(blind.name.toString()).intValue)



Desweiteren möchte ich, dass wenn die Verschattung beendet wird, nicht alle Rollos auf einmal hochfahren, sondern das Ganze auch mit Azimuth gesteuert wird, pro Hausseite z.B. so:

var Number openingAzimuth_south = 220
var Number openingAzimuth_east = 140

Sehr interessant ist dies für mich für die OST und Süd Seite, gerade dann wenn die Sonne genau um die Ecke ist und z.B. die OST-Seite nicht mehr trifft, das Tageslicht wieder reinkommt.

Wie müsste der Code erweitert werden?


@asd

Die gRollladenNorth ist etwas, was von mir kam, denn so wie Udo bereits erklärt hat,
gibt es Häuser, die nicht 100% mit den Seiten zu den jeweiligen Himmelsrichtungen zeigen.
Unser Haus z.B. ist ein wenig gegen den Uhrzeiger gedreht, dies hat zu Folge, dass die Sonne
alle 4 Hauswände ein bisschen früher erreicht, wie beim Jemanden, dessen Haus 100% zu den Himmelsrichtungen ausgerichtet ist.
Aus diesem Grund wird auch meine "NORD"-Seite etwas mehr von der Sonne getroffen, besonders im Sommer.

Benutzeravatar
Cyrelian
Beiträge: 601
Registriert: 24. Sep 2015 17:55
Answers: 4

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von Cyrelian »

Hi,

also... die drei ITEMS ShutterControll, ManualShading und AutoShading dienen unterschiedlichen Zwecken.

AutoShading: ist für die automatische Verschattung(runter und rauf) zuständig.

ManualShading: damit kann ich wenn ich "anwesend" bin, die Rollläden auf die Positionen der Verschattung(targetHights) fahren. Da die automatische Verschattung wenn ich "anwesend" bin deaktiviert ist.

ShutterControll: übernimmt die allgemeine Rollladebsteuerung, also z.B. Wochentags oder am Wochenende oder im Urlaub.

Shading_Var: wird in der rule "Verschattung Variablen update" verwendet um zu schauen, ob die Boolean´s TRUE oder FALSE sind z.B. isActiveWest und gibt das dann im Log aus. Man das von "aussen (RESTAPI)" sonst nicht sehen ob sie TRUE oder FALSE sind. Der Reset setzt diese einfach wieder auf FALSE.
1. Ich möchte, dass die Verschattung auch dann passiert, wenn die Rollos ganz runtergefahren sind, z.B. 100%.

Dies wird in dieser Zeile festgelegt:

if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue)

Würde es reichen, wenn ich diese Zeile so abändern würde:

if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue || (blind.state as Number) > targetHights.get(blind.name.toString()).intValue)
Ja, das würde reichen, aber warum? Die Rollläden sind doch schon unten oder?
Desweiteren möchte ich, dass wenn die Verschattung beendet wird, nicht alle Rollos auf einmal hochfahren, sondern das Ganze auch mit Azimuth gesteuert wird, pro Hausseite z.B. so:

var Number openingAzimuth_south = 220
var Number openingAzimuth_east = 140

Sehr interessant ist dies für mich für die OST und Süd Seite, gerade dann wenn die Sonne genau um die Ecke ist und z.B. die OST-Seite nicht mehr trifft, das Tageslicht wieder reinkommt.

Wie müsste der Code erweitert werden?
Ich würde 2 Werte definieren
var Number openingAzimuth_south1 = 220
var Number openingAzimuth_south2 = 235
Damit die Rule nur anspringt wenn der Wert dazwischen liegt.

Könnte so aussehen

Code: Alles auswählen

        if ((Azimuth.state as Number).floatValue > (openingAzimuth_south1) && (Azimuth.state as Number).floatValue < (openingAzimuth_south2)) {
            logInfo("rules", logPrefix + "Verschattung für Rollläden SÜD")
            shadingEnd.apply(gRollladenSouth)
            return;
Ich hatte das auch mal so. Funktioniert einwandfrei. Habs nur wieder rausgenommen, da ich die Rollläden, wenn es wirklich heiß ist, als "Wärmeschutz" benutze ;)

CYA
Cyrelian

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen

Beitrag von udo1toni »

cupra6 hat geschrieben: 24. Jul 2020 23:46 if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue)

Würde es reichen, wenn ich diese Zeile so abändern würde:

if ((blind.state as Number) < targetHights.get(blind.name.toString()).intValue || (blind.state as Number) > targetHights.get(blind.name.toString()).intValue)
Es geht auch kürzer:

Code: Alles auswählen

if ((blind.state as Number) != targetHights.get(blind.name.toString()).intValue)
Allerdings funktioniert das nicht mit allen Antrieben bzw. Steuersystemen, es gibt nämlich durchaus Systeme, da gibt man den Befehl auf 60 zu fahren, und der Laden fährt auf 61 oder 59. Das sollte man also unbedingt prüfen. Falls man diese Problem hat, kann man so testen:

Code: Alles auswählen

if (Math::abs((blind.state as Number) - targetHights.get(blind.name.toString()).intValue) > 1)
Das prüft dann auf eine Abweichung größer 1
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten