Es gibt zwei unterschiedliche Funktionen des Astro Bindings.
Zum einen gibt es normale Channel, die z.B. die Uhrzeit enthalten, zu der am aktuellen Tag ein bestimmtes astronomisches Ereignis eintritt. Diese Channel musst Du einem passenden Item zuweisen, dann kannst Du den Status des Items innnerhalb einer Rule abfragen.
Zum anderen gibt es event Channel, die zum Eintreten des Ereignisses einen Trigger senden, mit dem dann eine Rule getriggert werden kann.
Wenn Du einen Blick auf das Astro Thing "sun" wirfst, kannst Du z.B. verschiedenste Sonnen Auf- und Untergänge finden, jeweils mit Start, Ende, Dauer und dem Range Event, welches dann zum Startzeitpunkt mit START triggert, zum Endzeitpunkt mit END.
Start und Ende ergeben sich dadurch, dass das Ereignis als Berührung des Himmelskörpers mit einer gedachten Linie definiert ist. Die Sonne ist aber kein Punkt, sondern ein Kreis (zweidimensional betrachtet), so dass es einen Zeitpunkt gibt, zu dem die Berührung beginnt, und einen Zeitpunkt, zu dem die Berührung endet.
Nehmen wir an, Du möchtest auf CivilDusk triggern, die Sonne sinkt unter -6° Höhe am Horizont. Eine Rule dazu sähe dann so aus:
Code: Alles auswählen
rule "civilDusk Trigger"
when
Channel 'astro:sun:home:civilDusk#event' triggered START
then
logInfo("astro","Bürgerliche Abenddämmerung erreicht!")
end
Die andere Variante ist, ob wir uns zum Zeitpunkt des Triggers innerhalb der Dunkelheit zwischen Abend- und Morgendämmerung befinden.
Dazu brauchen wir zwei Items:
Code: Alles auswählen
DateTime CivilDawnStart "Sonnenaufgang Bürgerl." <sunrise> { channel="astro:sun:home:civilDawn#start" }
DateTime CivilDuskStart "Sonnenuntergang bürgerl." <sunset> { channel="astro:sun:home:civilDusk#start" }
und in der Rule müssen wir uns mit der Umrechnung der Zeiten herumschlagen.
Code: Alles auswählen
rule "trigger innerhalb bürgerlicher Dämmerung"
when
Item blah received update
then
val Number cDusk = (CivilDuskStart.state as DateTimeType).calendar.timeInMillis
val Number cDawn = (CivilDawnStart.state as DateTimeType).calendar.timeInMillis
if(now.millis < cDawn || now.millis > cDusk) {
// alternativ kann man auch eine Funktion von now() verwenden
// if(now.isBefore(cDawn) || now.isAfter(cDusk)) {
logInfo("astro","Trigger innerhalb der bürgerlichen Dämmerung!")
}
end
Elegant an diesem Ansatz ist, dass man im Astrobinding auch Offsets für jeden Channel definieren kann, man kann das Ereignis also statisch um eine beliebige Zeit nach vorne oder hinten verschieben, außerdem kann man Ober- und Untergrenze definieren.
Hässlich ist, dass es wirklich keinen Spaß macht, die nötigen Konvertierungen durchzuführen, vor allem, weil an dem Datenmodell in letzter Zeit herumgeschraubt wurde. Ich bin mir nicht mal sicher, ob der oben verwendete Ausdruck nicht schon deprecated ist.
Deshalb ist hier eventuell ein einfacherer Ansatz besser, denn das Astrobinding liefert auch die Position der Sonne in Richtung und Höhenwinkel. Wie oben erwähnt ist die Bürgerliche Dämmerung ab -6°. es reicht jetzt ein Item:
Code: Alles auswählen
Number:Angle Elevation "Sonnenhöhe [%.1f°]" <sun>{ channel="astro:sun:home:position#elevation" }
In der Rule wird das jetzt so berücksichtigt:
Code: Alles auswählen
rule "trigger innerhalb bürgerlicher Dämmerung"
when
Item blah received update
then
if((Elevation.state as as QuantityType<Number>) <-6) {
logInfo("astro","Trigger innerhalb der bürgerlichen Dämmerung!")
}
end
Alternativ kannst Du auch die Einheit mit in den Vergleich nehmen:
Code: Alles auswählen
rule "trigger innerhalb bürgerlicher Dämmerung"
when
Item blah received update
then
if(Elevation.state <-6|°) {
logInfo("astro","Trigger innerhalb der bürgerlichen Dämmerung!")
}
end
Beides sollte funktionieren, der erste Ansatz ist praktischer, falls man mit dem Zahlenwert noch Berechnungen anstellen will, da ist es oft nur lästig, Einheiten mit rumzuschleppen.