Hi Udo,
Mega. Funktioniert.
Bei mir läuft alles auf OH3
Danke
Jalousien nach Sonnenstand
-
- Beiträge: 7
- Registriert: 9. Jun 2020 23:18
Re: Jalousien nach Sonnenstand
Hallo zusammen, ich habe mir diese Rule mal "geklaut" und ein wenig angepasst. Aber es passiert nichts wenn die Werte erreicht werden.
Aktuell sind die Items bei folgenden Werten:
Höhenwinkel 15-65
47.97 °
Azimut SüdOst 77-180
166.81 °
Azimut SüdWest 160-270
166.81 °
Strahlung Min 150
500.80 W/m²
Wolken Max 80
46 %
Sonnenschutz_Aktiv:
ON
Als die Azimut auf 163 gesprungen sind, haben sich die Rollos im Süd/West Bereich aber nicht runterbewegt.
Die Rule:
Vielen Dank schon mal für eure Hilfe
Aktuell sind die Items bei folgenden Werten:
Höhenwinkel 15-65
47.97 °
Azimut SüdOst 77-180
166.81 °
Azimut SüdWest 160-270
166.81 °
Strahlung Min 150
500.80 W/m²
Wolken Max 80
46 %
Sonnenschutz_Aktiv:
ON
Als die Azimut auf 163 gesprungen sind, haben sich die Rollos im Süd/West Bereich aber nicht runterbewegt.
Die Rule:
Code: Alles auswählen
val nElevationMinSuedOst = 15 //15
val nElevationMaxSuedOst = 65 //65
val nElevationMinSuedWest = 15 //15
val nElevationMaxSuedWest = 65 //65
val nAzimutMin_SuedOst = 77 //140
val nAzimutMaxSuedOst = 180 //260
val nAzimutMin_SuedWest = 162 //140
val nAzimutMaxSuedWest = 270 //260
val nIntensityMin = 150 //150
val nCloudynessMax = 80 //80
var Timer tSchatten = null
rule "Beschattung SüdOst"
when
Item Astro_Lokale_Sonnendaten_Hohenwinkel changed
then
if(Sonnenschutz_Aktiv.state != ON)
return;
// if(!(LokaleSonnendaten_DiffuseStrahlung.state instanceof Number)) {
// logWarn("shade","DiffuseStrahlung! Abbruch!")
// return;
if(!(Astro_Lokale_Sonnendaten_Hohenwinkel.state instanceof Number)) {
logWarn("shade","Elevation ungültig! Abbruch!")
return;
}
if(!(Astro_Lokale_Sonnendaten_Azimut.state instanceof Number)) {
logWarn("shade","Azimut ungültig! Abbruch!")
return;
}
val nElevation = (Astro_Lokale_Sonnendaten_Hohenwinkel.state as Number).floatValue
val nAzimut = (Astro_Lokale_Sonnendaten_Azimut.state as Number).floatValue
var nIntens = 100
if(Astro_Lokale_Sonnendaten_Direkte_Strahlung.state instanceof Number)
nIntens = (Astro_Lokale_Sonnendaten_Direkte_Strahlung.state as DecimalType).intValue
var nCloud = 0
if(LocalWeatherAndForecast_Bewolkung.state instanceof Number)
nCloud = (LocalWeatherAndForecast_Bewolkung.state as Number).intValue
if(nElevation < nElevationMinSuedOst || nElevation > nElevationMaxSuedOst || nAzimut < nAzimutMin_SuedOst || nAzimut > nAzimutMaxSuedOst || nIntens < nIntensityMin || nCloud > nCloudynessMax) {
logInfo("shade","Jalousien Süd/Ost Beschattung aus!")
gRollos_SuedOst.sendCommand(UP) // Rollläden hochfahren
} else {
logInfo("shade","Jalousien Süd/ Ost Beschattung an!")
gRollos_SuedOst.sendCommand(DOWN) // Rollläden herunterfahren
}
end
rule "Beschattung SüdWest"
when
Item Astro_Lokale_Sonnendaten_Hohenwinkel changed
then
if(Sonnenschutz_Aktiv.state != ON)
return;
// if(!(LokaleSonnendaten_DiffuseStrahlung.state instanceof Number)) {
// logWarn("shade","DiffuseStrahlung! Abbruch!")
// return;
if(!(Astro_Lokale_Sonnendaten_Hohenwinkel.state instanceof Number)) {
logWarn("shade","Elevation ungültig! Abbruch!")
return;
}
if(!(Astro_Lokale_Sonnendaten_Azimut.state instanceof Number)) {
logWarn("shade","Azimut ungültig! Abbruch!")
return;
}
val nElevation = (Astro_Lokale_Sonnendaten_Hohenwinkel.state as Number).floatValue
val nAzimut = (Astro_Lokale_Sonnendaten_Azimut.state as Number).floatValue
var nIntens = 100
if(Astro_Lokale_Sonnendaten_Direkte_Strahlung.state instanceof Number)
nIntens = (Astro_Lokale_Sonnendaten_Direkte_Strahlung.state as DecimalType).intValue
var nCloud = 0
if(LocalWeatherAndForecast_Bewolkung.state instanceof Number)
nCloud = (LocalWeatherAndForecast_Bewolkung.state as Number).intValue
if(nElevation < nElevationMinSuedWest || nElevation > nElevationMaxSuedWest || nAzimut < nAzimutMin_SuedWest || nAzimut > nAzimutMaxSuedWest || nIntens < nIntensityMin || nCloud > nCloudynessMax) {
logInfo("shade","Jalousien Süd/West Beschattung aus!")
gRollos_SuedWest.sendCommand(UP) // Rollläden hochfahren
} else {
logInfo("shade","Jalousien Süd/West Beschattung an!")
gRollos_SuedWest.sendCommand(DOWN) // Rollläden herunterfahren
}
end
- udo1toni
- Beiträge: 15243
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Jalousien nach Sonnenstand
Frage: Funktioniert die Steuerung über die Gruppen überhaupt? Wie sind die Gruppen exakt definiert?
Gegeben, dass die Gruppen korrekt definiert sind
einige Tipps:
Tipp 1: beide Rules nutzen den identischen Trigger. Es ist also sinnvoll, beide Rules zu einer Rule zusammenzufassen. Da ein Gutteil der ermittelten Daten auch noch identisch ist, ist das ohnehin eine gute Option.
Tipp 2: Du verwendest DecimalType als Datentyp. Number wäre hier besser (ohne dass das einen direkten Einfluss haben sollte...)
Tipp 3: Es ist notwendig, hier die Messwerte mitzuloggen, um möglichen Problemen bei der Typwandlung auf die Spur zu kommen.
Entsprechend eine erweiterte Fassung der Rule:
Damit Du logDebug() Meldungen überhaupt zu Gesicht bekommst, musst Du das Logging noch auf DEBUG schalten, das geht z.B. über die Karaf Konsole:
Eine andere Option wäre, die Bedingungen hintereinander abzuarbeiten:
Die Beschattung wird zunächst als aktiv angesehen (in den Boolean Variablen bSuedOst und bSuedWest). Trifft eine der Bedingungnen zu, so wird die betreffende Variable auf false gesetzt.
Nachdem alle Vergleiche stattgefunden haben, wird abhängig von den Variablen der Befehl zum Schließen bzw. Öffnen erteilt.
Es wäre hier allerdings gut, die Rollläden nur bei Bedarf anzusteuern. Dazu muss aber die Rückmeldung korrekt funktionieren. Ein weiterer Punkt wäre dann noch, ob Du tatsächlich die Rollläden komplett schließen willst.
Da meine Rollläden absolute Positionierung beherrschen und ihre Position auch aktiv zurückmelden, läuft das bei mir etwas anders, so im Groben:
Die Rule sucht also anhand des Itemnamens den Sollwert aus einer der beiden HashMaps hmShade bzw. hmOpen und prüft, ob der Rollladen diese Position hat. Ist das nicht der Fall, wird der Rollladen auf die Sollposition gefahren.
Meine Rule macht das anhand anderer Abhängigkeiten, aber im Groben sollte das bei Dir auch so funktionieren, vorausgesetzt, Deine Rollläden unterstützen direkte Positionsfahrten.
Gegeben, dass die Gruppen korrekt definiert sind
Code: Alles auswählen
Group:Rollershutter gRollos_SuedOst
Group:Rollershutter gRollos_SuedWest
Tipp 1: beide Rules nutzen den identischen Trigger. Es ist also sinnvoll, beide Rules zu einer Rule zusammenzufassen. Da ein Gutteil der ermittelten Daten auch noch identisch ist, ist das ohnehin eine gute Option.
Tipp 2: Du verwendest DecimalType als Datentyp. Number wäre hier besser (ohne dass das einen direkten Einfluss haben sollte...)
Tipp 3: Es ist notwendig, hier die Messwerte mitzuloggen, um möglichen Problemen bei der Typwandlung auf die Spur zu kommen.
Entsprechend eine erweiterte Fassung der Rule:
Code: Alles auswählen
val nElevationMinSuedOst = 15 // 15
val nElevationMaxSuedOst = 65 // 65
val nElevationMinSuedWest = 15 // 15
val nElevationMaxSuedWest = 65 // 65
val nAzimutMin_SuedOst = 77 // 140
val nAzimutMaxSuedOst = 180 // 260
val nAzimutMin_SuedWest = 162 // 140
val nAzimutMaxSuedWest = 270 // 260
val nIntensityMin = 150 // 150
val nCloudynessMax = 80 // 80
var Timer tSchatten = null
rule "Beschattung SüdOst und SüdWest"
when
Item Astro_Lokale_Sonnendaten_Hohenwinkel changed
then
if(Sonnenschutz_Aktiv.state != ON)
return;
// if(!(LokaleSonnendaten_DiffuseStrahlung.state instanceof Number)) {
// logWarn("shade","DiffuseStrahlung! Abbruch!")
// return;
if(!(Astro_Lokale_Sonnendaten_Hohenwinkel.state instanceof Number)) {
logWarn("shade","Elevation ungültig! Abbruch!")
return;
}
if(!(Astro_Lokale_Sonnendaten_Azimut.state instanceof Number)) {
logWarn("shade","Azimut ungültig! Abbruch!")
return;
}
val nElevation = (Astro_Lokale_Sonnendaten_Hohenwinkel.state as Number).floatValue
val nAzimut = (Astro_Lokale_Sonnendaten_Azimut.state as Number).floatValue
var nIntens = 100
if(Astro_Lokale_Sonnendaten_Direkte_Strahlung.state instanceof Number)
nIntens = (Astro_Lokale_Sonnendaten_Direkte_Strahlung.state as Number).intValue
var nCloud = 0
if(LocalWeatherAndForecast_Bewolkung.state instanceof Number)
nCloud = (LocalWeatherAndForecast_Bewolkung.state as Number).intValue
logDebug("shade", " Intensität : {} (Minimum {})", nIntens, nIntensityMin)
logDebug("shade", " Wolken : {} (Maximum {})", nCloud, nCloudynessMax)
logDebug("shade", "Elevation Süd-Ost : {} (Minimum {}, Maximum {})", nElevation, nElevationMinSuedOst, nElevationMaxSuedOst)
logDebug("shade", "Elevation Süd-West: {} (Minimum {}, Maximum {})", nElevation, nElevationMinSuedWest, nElevationMaxSuedWest)
logDebug("shade", " Azimut Süd-Ost : {} (Minimum {}, Maximum {})", nAzimut, nCloudynessMax, nAzimutMin_SuedOst, nAzimutMaxSuedOst)
logDebug("shade", " Azimut Süd-West: {} (Minimum {}, Maximum {})", nAzimut, nCloudynessMax, nAzimutMin_SuedWest, nAzimutMaxSuedWest)
if(nElevation < nElevationMinSuedOst || nElevation > nElevationMaxSuedOst || nAzimut < nAzimutMin_SuedOst || nAzimut > nAzimutMaxSuedOst || nIntens < nIntensityMin || nCloud > nCloudynessMax) {
logInfo("shade","Jalousien Süd/Ost Beschattung aus!")
gRollos_SuedOst.sendCommand(UP) // Rollläden hochfahren
} else {
logInfo("shade","Jalousien Süd/ Ost Beschattung an!")
gRollos_SuedOst.sendCommand(DOWN) // Rollläden herunterfahren
}
if(nElevation < nElevationMinSuedWest || nElevation > nElevationMaxSuedWest || nAzimut < nAzimutMin_SuedWest || nAzimut > nAzimutMaxSuedWest || nIntens < nIntensityMin || nCloud > nCloudynessMax) {
logInfo("shade","Jalousien Süd/West Beschattung aus!")
gRollos_SuedWest.sendCommand(UP) // Rollläden hochfahren
} else {
logInfo("shade","Jalousien Süd/West Beschattung an!")
gRollos_SuedWest.sendCommand(DOWN) // Rollläden herunterfahren
}
end
Code: Alles auswählen
log:set DEBUG org.openhab.core.model.script.shade
Code: Alles auswählen
val nElevationMinSuedOst = 15 // 15
val nElevationMaxSuedOst = 65 // 65
val nElevationMinSuedWest = 15 // 15
val nElevationMaxSuedWest = 65 // 65
val nAzimutMin_SuedOst = 77 // 140
val nAzimutMaxSuedOst = 180 // 260
val nAzimutMin_SuedWest = 162 // 140
val nAzimutMaxSuedWest = 270 // 260
val nIntensityMin = 150 // 150
val nCloudynessMax = 80 // 80
var Timer tSchatten = null
rule "Beschattung SüdOst und SüdWest"
when
Item Astro_Lokale_Sonnendaten_Hohenwinkel changed
then
if(Sonnenschutz_Aktiv.state != ON)
return;
// if(!(LokaleSonnendaten_DiffuseStrahlung.state instanceof Number)) {
// logWarn("shade","DiffuseStrahlung! Abbruch!")
// return;
if(!(Astro_Lokale_Sonnendaten_Hohenwinkel.state instanceof Number)) {
logWarn("shade","Elevation ungültig! Abbruch!")
return;
}
if(!(Astro_Lokale_Sonnendaten_Azimut.state instanceof Number)) {
logWarn("shade","Azimut ungültig! Abbruch!")
return;
}
val nElevation = (Astro_Lokale_Sonnendaten_Hohenwinkel.state as Number).floatValue
val nAzimut = (Astro_Lokale_Sonnendaten_Azimut.state as Number).floatValue
var nIntens = 100
if(Astro_Lokale_Sonnendaten_Direkte_Strahlung.state instanceof Number)
nIntens = (Astro_Lokale_Sonnendaten_Direkte_Strahlung.state as Number).intValue
var nCloud = 0
if(LocalWeatherAndForecast_Bewolkung.state instanceof Number)
nCloud = (LocalWeatherAndForecast_Bewolkung.state as Number).intValue
var Boolean bSuedWest = true
var Boolean bSuedOst = true
if(nCloud > nCloudynessMax) {
logInfo("shade","Bewölkung {} überschreitet Maximum {}, Beschattung aus!", nCloud, nCloudynessMax)
bSuedWest = false
bSuedOst = false
}
if(nIntens < nIntensityMin) {
logInfo("shade","Intensität {} unterschreitet Minimum {}, Beschattung aus!", nIntens, nIntensityMin)
bSuedWest = false
bSuedOst = false
}
if(nElevation < nElevationMinSuedOst) {
logInfo("shade","Elevation {} unterhalb Minimum Süd-Ost {}, Beschattung Süd-Ost aus!", nElevation, nElevationMinSuedOst)
bSuedOst = false
}
if(nElevation < nElevationMinSuedWest) {
logInfo("shade","Elevation {} unterhalb Minimum Süd-West {}, Beschattung Süd-West aus!", nElevation, nElevationMinSuedWest)
bSuedWest = false
}
if(nElevation > nElevationMaxSuedOst) {
logInfo("shade","Elevation {} oberhalb Maximum Süd-Ost {}, Beschattung Süd-Ost aus!", nElevation, nElevationMaxSuedOst)
bSuedOst = false
}
if(nElevation > nElevationMaxSuedWest) {
logInfo("shade","Elevation {} oberhalb Maximum Süd-West {}, Beschattung Süd-West aus!", nElevation, nElevationMaxSuedWest)
bSuedWest = false
}
if(nAzimut > nAzimutMaxSuedOst) {
logInfo("shade","Azimut {} oberhalb Maximum Süd-Ost {}, Beschattung Süd-Ost aus!", nAzimut > nAzimutMaxSuedOst)
bSuedOst = false
}
if(nAzimut > nAzimutMaxSuedWest) {
logInfo("shade","Azimut {} oberhalb Maximum Süd-West {}, Beschattung Süd-West aus!", nAzimut > nAzimutMaxSuedWest)
bSuedWest = false
}
if(nAzimut < nAzimutMin_SuedOst) {
logInfo("shade","Azimut {} unterhalb Minimum Süd-Ost {}, Beschattung Süd-Ost aus!", nAzimut > nAzimutMin_SuedOst)
bSuedWest = false
}
if(nAzimut < nAzimutMin_SuedWest) {
logInfo("shade","Azimut {} unterhalb Minimum Süd-West {}, Beschattung Süd-West aus!", nAzimut > nAzimutMin_SuedWest)
bSuedWest = false
}
if(!bSuedOst) {
// logInfo("shade","Jalousien Süd/Ost Beschattung aus!")
gRollos_SuedOst.sendCommand(UP) // Rollläden hochfahren
} else {
// logInfo("shade","Jalousien Süd/ Ost Beschattung an!")
gRollos_SuedOst.sendCommand(DOWN) // Rollläden herunterfahren
}
if(!bSuedWest) {
// logInfo("shade","Jalousien Süd/West Beschattung aus!")
gRollos_SuedWest.sendCommand(UP) // Rollläden hochfahren
} else {
// logInfo("shade","Jalousien Süd/West Beschattung an!")
gRollos_SuedWest.sendCommand(DOWN) // Rollläden herunterfahren
}
end
Nachdem alle Vergleiche stattgefunden haben, wird abhängig von den Variablen der Befehl zum Schließen bzw. Öffnen erteilt.
Es wäre hier allerdings gut, die Rollläden nur bei Bedarf anzusteuern. Dazu muss aber die Rückmeldung korrekt funktionieren. Ein weiterer Punkt wäre dann noch, ob Du tatsächlich die Rollläden komplett schließen willst.
Da meine Rollläden absolute Positionierung beherrschen und ihre Position auch aktiv zurückmelden, läuft das bei mir etwas anders, so im Groben:
Code: Alles auswählen
import java.util.HashMap
val HashMap<String,Number> hmShade = newHashMap( "Rollladen_1" -> 25, "Rollladen_2" -> 43, "RollKueche" -> 17)
val HashMap<String,Number> hmOpen = newHashMap( "Rollladen_1" -> 0, "Rollladen_2" -> 0, "RollKueche" -> 0)
rule "Schatten"
when
Item Elevation changed
then
// Auswertung der Grenzwerte und Entscheidung, ob Beschattung für die jeweilige Seite aktiv sein soll
... // Code wie oben
// ab hier Steuerung der einzelnen Rollläden auf ihre Sollposition
gRollos_SuedWest.members.forEach[r|
var soll = if(bSuedWest) hmShade.get(r.name) else hmOpen.get(r.name)
if((r.state as Number) != soll)
r.sendCommand(soll)
]
gRollos_SuedOst.members.forEach[r|
var soll = if(bSuedOst) hmShade.get(r.name) else hmOpen.get(r.name)
if((r.state as Number) != soll)
r.sendCommand(soll)
]
end
Meine Rule macht das anhand anderer Abhängigkeiten, aber im Groben sollte das bei Dir auch so funktionieren, vorausgesetzt, Deine Rollläden unterstützen direkte Positionsfahrten.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet