Ankündigung

Einklappen
Keine Ankündigung bisher.

ephem 3.7.6.0 in DEV vom 10.08.2016 bringt Fehler

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Mehr zum Scheduler:

    Auszug aus Item.conf
    Code:
    [Zentral]
        [[Astronomie]]
            [[[Sonne]]]
                [[[[Berechnung]]]]
                    type = bool
                    visu = yes
                    crontab = init = 1 | 30 2 * * = 1
                    enforce_updates = true
    
                [[[[Aufgang]]]]
                    type = foo
                    visu = yes
                    eval = sh.sun.rise().astimezone(sh.tzinfo())
                    eval_trigger = Zentral.Astronomie.Sonne.Berechnung
                    knx_dpt = 10
                    knx_send = 0/2/10
                    enforce_updates = true
    
                    [[[[[Azimut]]]]]
                        type = foo
                        visu = yes
                        eval = sh.env.location.sunrise.azimut.degrees()
                        eval_trigger = Zentral.Astronomie.Sonne.Berechnung
                        knx_dpt = 5
                        knx_send = 0/2/11
                        enforce_updates = true
    
                    [[[[[Elevation]]]]]
                        type = foo
                        visu = yes
                        eval = sh.env.location.sunrise.elevation.degrees()
                        eval_trigger = Zentral.Astronomie.Sonne.Berechnung
                        knx_dpt = 5
                        knx_send = 0/2/12
                        enforce_updates = true
    
                    [[[[[DaemmerungNautisch]]]]]
                        type = foo
                        visu = yes
                        eval = sh.sun.rise(-12).astimezone(sh.tzinfo())
                        eval_trigger = Zentral.Astronomie.Sonne.Berechnung
                        knx_dpt = 10
                        knx_send = 0/2/20
                        enforce_updates = true
    
                    [[[[[DaemmerungBuergerlich]]]]]
                        type = foo
                        visu = yes
                        eval = sh.sun.rise(-6).astimezone(sh.tzinfo())
                        eval_trigger = Zentral.Astronomie.Sonne.Berechnung
                        knx_dpt = 10
                        knx_send = 0/2/21
                        enforce_updates = true
    Ergebnis im Log
    2016-10-09 16:10:32 INFO item Zentral.Astronomie.Sonne.Berechnung Item Zentral.Astronomie.Sonne.Berechnung = True via Scheduler None None -- item.py:__update:374
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Azimut - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:trigger:165
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Elevation - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:trigger:5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Aufgang.Azimut - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:tri5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Aufgang.Elevation - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisc h - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- sche5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- s5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Aufgang - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:trigger:165
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Untergang.Azimut - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:t5
    2016-10-09 16:10:32 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Untergang.Elevation - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.p5
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun Offset in Grad -12 -- orb.py:rise:98
    2016-10-09 16:10:33 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Untergang.DaemmerungBuerg erlich - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber --5
    2016-10-09 16:10:33 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Untergang.DaemmerungNauti sch - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- sc5
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun Offset in Minuten 0 -- orb.py:rise:99
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun Offset in Grad -6 -- orb.py:rise:98
    2016-10-09 16:10:33 DEBUG scheduler Zentral.Astronomie.Sonne.Berechnung Triggering Zentral.Astronomie.Sonne.Untergang - by: Scheduler source: None dest: None value: {'source': 'Zentral.Astronomie.Sonne.Ber -- scheduler.py:trigger:5
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun center True -- orb.py:rise:100
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun Offset in Grad 0 -- orb.py:rise:98
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun Offset in Minuten 0 -- orb.py:rise:99
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun center True -- orb.py:rise:100
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun Offset in Minuten 0 -- orb.py:rise:99
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun Datetimeobjekt None -- orb.py:rise:101
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun Datetimeobjekt None -- orb.py:rise:101
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun center True -- orb.py:rise:100
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun Initdatum 2016/10/9 14:10:35 -- orb.py:rise:102
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun Initdatum 2016/10/9 14:10:35 -- orb.py:rise:102
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun Datetimeobjekt None -- orb.py:rise:101
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang.DaemmerungBuerg erlich Datum 2016/10/9 14:10:35 -- orb.py:set:124
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisch Sun Sonnenaufgang 2016-10-10 05:28:11.578059 -- orb.py:rise:103
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun Initdatum 2016/10/9 14:10:35 -- orb.py:rise:102
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Sun Sonnenaufgang 2016-10-10 16:32:43.317414 -- orb.py:rise:103
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang.DaemmerungBuerg erlich Sonnenuntergang 2016-10-09 17:08:23.564906 -- orb.py:set:125
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Untergang.DaemmerungBuerg erlich Item Zentral.Astronomie.Sonne.Untergang.DaemmerungBuerg erlich = 2016-10-09 19:08:23.564906+02:00 via Eval Zentral.Astronomie.Sonne.Berech4
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Aufgang Sun Sonnenaufgang 2016-10-11 05:27:39.153564 -- orb.py:rise:103
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Aufgang Item Zentral.Astronomie.Sonne.Aufgang = 2016-10-11 07:27:39.153564+02:00 via Eval Zentral.Astronomie.Sonne.Berechnung None -- item.py:__update:374
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich Item Zentral.Astronomie.Sonne.Aufgang.DaemmerungBuerger lich = 2016-10-10 18:32:43.317414+02:00 via Eval Zentral.Astronomie.Sonne.Berechnung4
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisc h Item Zentral.Astronomie.Sonne.Aufgang.DaemmerungNautisc h = 2016-10-10 07:28:11.578059+02:00 via Eval Zentral.Astronomie.Sonne.Berechnung None 4
    2016-10-09 16:10:33 DEBUG scheduler Scheduler Zentral.Astronomie.Sonne.Berechnung next time: 2016-10-10 02:30:00+02:00 -- scheduler.py:_next_time:316
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang.DaemmerungNauti sch Datum 2016/10/9 14:10:35 -- orb.py:set:124
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang.DaemmerungNauti sch Sonnenuntergang 2016-10-09 16:34:42.354025 -- orb.py:set:125
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Untergang.DaemmerungNauti sch Item Zentral.Astronomie.Sonne.Untergang.DaemmerungNauti sch = 2016-10-09 18:34:42.354025+02:00 via Eval Zentral.Astronomie.Sonne.Berechnung N4
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang Datum 2016/10/9 14:10:35 -- orb.py:set:124
    2016-10-09 16:10:33 DEBUG orb Zentral.Astronomie.Sonne.Untergang Sonnenuntergang 2016-10-09 16:36:41.918134 -- orb.py:set:125
    2016-10-09 16:10:33 INFO item Zentral.Astronomie.Sonne.Untergang Item Zentral.Astronomie.Sonne.Untergang = 2016-10-09 18:36:41.918134+02:00 via Eval Zentral.Astronomie.Sonne.Berechnung None -- item.py:__update:374
    Das Ganze macht für mich den Eindruck, als ob der Trigger zwar die Itemberechnungen nacheinander aufruft, die Berechnung im orb.py selbst dann aber aus dem Takt kommt und nicht der Reihe nach abgearbeitet wird. Denn eigentlich müsste die Logausgabe schön der Reihe nach ablaufen:

    # Debug
    self.logger.debug(" " + str(self._orb.name) + " Offset in Grad " + str(doff))
    self.logger.debug(" " + str(self._orb.name) + " Offset in Minuten " + str(moff))
    self.logger.debug(" " + str(self._orb.name) + " center " + str(center))
    self.logger.debug(" " + str(self._orb.name) + " Datetimeobjekt " + str(dt))
    self.logger.debug(" " + str(self._orb.name) + " Initdatum " + str(self._obs.date))
    self.logger.debug(" " + str(self._orb.name) + " Sonnenaufgang " + str(next_rising))
    Am Ende kommen dann zufällige Daten heraus:
    Output:

    Sonne Azimut 0 Grad
    Sonne Elevation 0 Grad

    Morgendämmerung nautisch 7:28
    Morgendämmerung bürgerlich 18:32

    Sonnenaufgang 7:27
    Sonnenaufgang Azimut 0 Grad
    Sonnenaufgang Elevation 0 Grad

    Sonnenuntergang 18:36
    Sonnenuntergang Azimut 0 Grad
    Sonnenuntergang Elevation 0 Grad

    Abenddämmerung bürgerlich 19:08
    Abenddämmerung nautisch 18:34

    Mondaufgang 15:32
    Monduntergang 0:23

    Kommentar


      #17
      Siehe weiter oben:
      Es ist vermutlich das gleiche Symptom wie beim UZSU Plugin. Dort habe ich einen Fix eingebaut, der das Sonnenobjekt erneut auf der Basis der Position erstellt. Das Problem liegt darin, das ein Sonnenobjekt gleichzeitig von mehreren Threads benutzt wird.
      Wir müssen da idealerweise ein get_sun oder get_moon implementieren, das ein unabhängiges Objekt zurückgibt. Ich hatte das schon mal für dev angefangen, bin aber zur Zeit zu sehr eingespannt. Im Code der UZSU steht da sowas:
      Code:
              # create an own sun object:
              try:
                  #longitude = self._sh.sun.long
                  #latitude = self._sh.sun.lat
                  #elevation = self._sh.sun.elevation
                  longitude = self._sh.sun._obs.long
                  latitude = self._sh.sun._obs.lat
                  elevation = self._sh.sun._obs.elev
                  uzsu_sun = lib.orb.Orb('sun', longitude, latitude, elevation)
                  self.logger.debug("Created a new sun object with latitude={}, longitude={}, elevation={}".format(latitude, longitude, elevation))
              except Exception as e:
                  self.logger.error("Error '{}' creating a new sun object. You could not use sunrise/sunset as UZSU entry.".format(e))
                  return

      Kommentar


        #18
        Hallo bmx,

        das ist mir so noch nicht klar. Die Objekte sun und moon werden nur ein Mal erstellt, das sollte aber doch eigentlich nichts ausmachen, weil dabei ja eh nur die Position des Beobachters übergeben wird. Dieses Objekt liefert übrigens nebenbei ja schon Aufgang, Untergang und Transit mit - diese Infos müssen also eigentlich nicht noch extra berechnet werden und könnten gleich als env items zur Verfügung gestellt werden.

        Was anderes ist es, wenn mit diesen Objekten "Pseudo-Auf- und Untergänge" berechnet werden sollen (z.B. Dämmerungen, UZSU...). Dann kommen ja die Funktionen (Methoden) rise() und set() ins Spiel, die das dann schon vorhandene Objekt sun und moon benutzen (weil da der Beobachterstandort mit herangezogen werden muss). Dabei verstehe ich aber nicht ganz, warum nicht mehrere Threads (was ist ein Thread in sh.py eigentlich genau) diese Funktionen sauber aufrufen können. Immerhin sind sie ja als Funkion gekapselt und liefern ja nur einen Rückgabewert. Ich greife da ja nicht direkt auf Variablen zu und am Objekt selbst wird ja nichts verändert.

        Im Grunde wäre zu überlegen, ob man nicht die "statischen" Daten (Aufgang, Untergang, Transit, Dämmerungen, Tag- / Nachtzustand, Dämmerungszustand,...) wirklich nur in der /env/location.py täglich ein einziges Mal berechnet und als festes item bereitstellt. Ich weiß da jetzt nur auf Anhieb nicht, wie man das dann elegant trotzdem mit dem knx verknüpft, ohne in der /env/location.conf rumpfuschen zu müssen.

        Die Alternative wäre noch, die env items ganz wegzulassen und dafür ein eigenes Plugin "Astronomie" zu schreiben, dass diese Berechnungen dann sauber getrennt durchführt.

        Und ich habe das nun schon richtig verstanden, dass die jetzige Berechnung von letzem/nächsten Aufgang und Untergang statt der tagesbezogenen Berechnung eher der UZSU geschuldet ist, die wissen muss, wann sie das nächste Mal was tun muss?

        Was meinst du? Ich würde dann versuchen, das Ganze in die Richtung weiterzuentwickeln - habe mich diese Wochenende ja schon etwas tiefer in Python hineingedacht.

        Viele Grüße
        Andi

        Kommentar


          #19
          Wenn es Funktionen gäbe GetSun() und GetMoon() die voneinander unabhängige Objekte liefern, wäre das sicher ein Lösungsansatz. Die könnten z.B. direkt im Core implementiert werden.

          Kommentar


            #20
            So, ich habe jetzt zumindest mal die orb.py mit Kommentaren und Logging ausstaffiert, soweit ich das Skript verstanden habe. Eine Ungereimtheit habe ich da drin noch, das ist die Stelle wo vor der Ergebnisrückgabe der Offset wieder drauf gerechnet wird:

            Code:
                # Berechnung des NÄCHSTEN Aufgangs
                def rise(self, doff=0, moff=0, center=True, dt=None):
                    # Parameter: doff (Offset in Grad), moff (Offset in Minuten), center (Berechnung True für Planetenmitte bei Dämmerungen, False für Planetenoberkante bei Auf-/Untergng), dt (Datetimeobjekt "2016-10-08 00:00:00+02:00")
            
                    # Datum/Zeit für die Ermittlung des nächsten Aufgangs festlegen
                    if dt is not None:
                        # Umrechnung der übertragenen lokalen Zeitangabe in UTC
                        self._obs.date = dt - dt.utcoffset()
                    else:
                        # Korrektur der aktuellen Zeit (wenn keine Zeit übertragen wurde), um den Offset in Mintuen (moff) plus "workaround if rise is 0.001 seconds in the past"??
                        self._obs.date = datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(minutes=moff) + dateutil.relativedelta.relativedelta(seconds=2)
            
                    # Horizont des Beobachters verschieben um den Offset in Grad (doff)
                    self._obs.horizon = str(doff)
            
                    # Berechnung Aufgang
                    if doff != 0:
                        # Berechnung Aufgangszeit mit Korrektur von Mitte auf Oberkante
                        # Das ist eigentlich nicht korrekt, da hier ALLE Offsetberechnungen korrigiert werden, dies aber nur für die typischen 6, 12, 18 Grad der Dämmerungsdefinition gilt
                        next_rising = self._obs.next_rising(self._orb, use_center=center).datetime()
                    else:
                        # Berechnung Aufgangszeit für Oberkante
                        next_rising = self._obs.next_rising(self._orb).datetime()
            
                    # Zusätzliche Verschiebung der berechneten Zeit um den Offset in Mintuen (moff)
                    # Unklar, warum hier der Offset wieder dazugerechnet wird
            [COLOR=#FF0000]        next_rising = next_rising + dateutil.relativedelta.relativedelta(minutes=moff)[/COLOR]
            
                    # Debug
                    self.logger.debug("     " + str(self._orb.name) + " Offset in Grad " + str(doff))
                    self.logger.debug("     " + str(self._orb.name) + " Offset in Minuten " + str(moff))
                    self.logger.debug("     " + str(self._orb.name) + " Planetenmitte/Oberkante " + str(center))
                    self.logger.debug("     " + str(self._orb.name) + " Datetimeobjekt " + str(dt))
                    self.logger.debug("     " + str(self._orb.name) + " Initdatum " + str(self._obs.date))
                    self.logger.debug("     " + str(self._orb.name) + " Sonnenaufgang " + str(next_rising))
            
                    # Rückgabe von Datum/Zeit in UTC oder Lokalzeit?
                    return next_rising.replace(tzinfo=tzutc())
            Kann ich hier irgendwo die ganze orb.py für Interessierte zum Download/Test auch hochladen oder nur über einen Drittanbieter sharen?

            Kommentar


              #21
              Ich finde in Bezug auf ephem-Struktur die ganze orb.py nicht optimal. Insofern sind m.E. Getter im vorhandenen System auch nicht wirklich zielführend. Ich schreibe jetzt mal eine neue Klassse und teste die aus. Hat nur den Nachteil, dass ev. Anpassungen in UZSU o.ä. dann notwendig werden würden.

              Kommentar


                #22
                Am meisten Zeit kostet mich noch Python und ein paar Ungereimtheiten in ephem selbst, aber ich komme langsam voran:

                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Parameter obsdate RAW 2016-10-13 14:41:33
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Parameter planet Sun
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Parameter offset_degrees 0
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Parameter offset_minutes 0
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Parameter obsdate 2016-10-13 14:41:33
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Beobachter Datum UTC 2016/10/13 14:41:33
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Beobachter Breitengrad 48:10:30.0
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Beobachter Längengrad 11:30:25.9
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Beobachter Höhe 530.0
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Name Sun
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun Horizont 0:00:00.0
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun aktuelle Höhe DEG 15:44:49.6
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun aktueller Azimut DEG 237:48:10.9
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun letzter Aufgang 2016-10-13 07:30:35
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun aktueller Aufgang 2016-10-13 07:30:35
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun nächster Aufgang 2016-10-14 07:32:03
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun letzter Transit 2016-10-13 13:00:06
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun aktueller Transit 2016-10-14 12:59:52
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun nächster Transit 2016-10-14 12:59:52
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun letzter Untergang 2016-10-12 18:30:47
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun aktueller Untergang 2016-10-12 18:30:47
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Planet Sun nächster Untergang 2016-10-13 18:28:50
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Letzter Neumond 2016-10-01 02:11:22
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Nächster Neumond 2016-10-30 18:38:11
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Letzter Vollmond 2016-09-16 21:05:05
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Nächster Vollmond 2016-10-16 06:23:06
                2016-10-13 16:41:33 DEBUG Zentral.Astronomie.Sonne.Constellation Mondphase 4
                Das Ganze braucht momentan nur einen Funktionsaufruf (für Sun), die Funktion gibt dann gleich alle Werte zurück
                eval = sh.astro.constellation()[11]
                , also z.B. hier den 12. Eintrag. Ich weiß allerdings noch nicht, ob das so praktisch ist, weil ja jedes Item in der Regel nur mit einem Wert beliefert wird. Aber zigmal die Funktion aufrufen, wenn ephem die Werte sowieso auf einmal liefert, ist auch nicht so sinnvoll. Vielleicht gibt es da eine Möglichkeit, die Ergebnisse gleich auf mehrere Items zu verteilen?

                Als Nächstes schau ich mir noch die Umrechnungen für "verschobene" Horizonte (=Dämmerungen) und gewollte Zeitverschiebungen (= +20m) an, dann könnte man das parallel zum vorhandenen orb.py schon nutzen. Sucht daher noch nicht nach "Constellation", das gibt es bisher nur in meiner Testklasse.

                Kommentar


                  #23
                  Hi Andi,

                  aktuelle Höhe und aktueller Azimut ändern sich regelmäßig, müssen also im gewissen Intervall neu gerechnet werden. Siehe dazu Issue 66 auf Github. Die Daten vom Neumond/Vollmond müssen eigentlich nur alle 28 Tage neu berechnet werden. Die Auf- und Untergänge müssen um den Zeitpunkt herum neu berechnet werden. Eigentlich direkt kurz nach einem Ereignis um das korrekt zu machen.
                  In Python kannst Du auch ein dict als Rückgabewert einer Funktion nutzen.

                  Wenn Du übrigens Code schreibst der später ins Rep gehen soll, wären englische Kommentare sinnvoll, dazu noch Parameter- und Funktionsbeschreibungen passend für Sphinx.

                  Gruß,
                  Bernd

                  Kommentar


                    #24
                    Hallo Bernd,

                    hier tut sich wohl die Achse München-Bermen auf :-)

                    Ich versuche mich mal an einer Zusammenfassung (den aktuellen Stand meiner Klasse habe ich unten mal gehängt - ist aber noch nicht fertig):

                    Die jetzige Klasse Orb in orb.py benutzt mehrere Methoden (rise, set, pos, light, phase), um diverse astronomische Daten zu berechnen. Beim Start von smarthome.py werden über diese Klasse nacheinander sofort zwei Instanzen sun und moon (bodies in ephem) erzeugt, die dann aber zunächst nicht weiter ausgewertet, sondern erst später über die Methoden rise() und set() gefüttert und berechnet werden.

                    Ephem denkt eigentlich anders herum. In Ephem werden alle Berechnungen für bodies (Planeten) in einem neutralen Koordinatensystem durchgeführt, es sei denn, man hat einen Beobachter definiert, der über seinen Standort das Koordinatensystem (und damit alle Berechnungen wie Aufgangszeiten usw.) an den Standort des Betrachters verschiebt. Folglich erzeuge ich beim Start von smarthome.py zunächst nur eine Instanz auf die Klasse (habe meine zur Unterscheidung Astronomy genannt), die zunächst im __init__ aus Ephem ausschließlich einen Observer (Beobachter) mit den in der smarthome.conf hinterlegten Daten erzeugt, weil dieser Oberserver die komplette Laufzeit des Programmes benötigt wird und sich der Standort nicht ändern wird und es daher auch keinerlei Interferenzen mit diversen Planetenberechnungen geben wird.

                    Erst wenn ich nun meine Methode constellation aufrufe, werden die gewünschten Planeten berechnet. Dazu kann ich der Methode den gewünschten Planet (wenn nicht, wird die Sonne verwendet) und die gewünschte Betrachtungszeit des Beobachter (wenn nicht, wird die aktuelle Zeit verwendet) übergeben. Diese Methode ist "planetenneutral", d.h. ich könnte die verfügbaren Daten damit auch für Saturn, Merkur usw. berechnen lassen. Am Ende der Methode lösche ich den erst in der Mehtode erzeugten body (Planeten) wieder, damit sich künftig keine unerwünschten Begleiteffekte mehr ergeben können.


                    Dazu noch ein paar Anmerkungen:

                    Außer zeitaktuellen (also auf den Aufruf der Methode bezogenen) Positionsdaten (Höhe, Azimut) stehen die grundlegenden Monddaten immer schon direkt in Ephem zur Verfügung, dazu braucht es nicht mal einen konkreten body. Im jetzigen Orb.py wird übrigens m.E. die Mondphase falsch berechnet (return int(round(frac * 8)), statt round() müsste da math.ceil() verwendet werden) und ich berechne bei mir den Mondumlauf aus der Zeit zwischen letztem und nächstem Neumond und nicht mit einem festen Wert (aber das sind Kleinigkeiten).

                    Für die Berechnung von Aufgangszeiten usw. sind wir hier im Forum ja schon mehrfach darüber gestolpert, welche Zeiten relevant sind. Für die Visu möchte sicher jeder die tagesaktuellen Daten sehen (das ist jetzt ja nicht der Fall), der Scheduler und auch eine UZSU wird sicher immer Informationen darüber brauchen, die relativ zum aktuell betrachteten Zeitpunkt stehen, das kann mal der letzte oder der nächste Aufgang/Untergang sein (je nachdem, ob ich das gerade vor oder nach so einem Ereignis wissen will). Daher kommt auch in der bisherigen Orb.py die Problematik, dass mit rise() und set() immer nur das nächste Ereignis berechnet wird und in der Visu nicht wirklich passt. Ich berechne jetzt einfach alle Ereignisse (letztes, aktuelles und nächstes), weil Ephem mir die neben weiteren Daten im Grunde eh frei Haus liefert (außer aktuelles). Die große Frage auch für mich dabei ist, ob ich die gesammelten Daten einfach mit einem return zurückgebe, oder dafür lauter einzelne Get-Methoden definieren muss. Berechnet werden muss eh immer alles, da jedes Mal der body benötigt wird.

                    Ich könnte zwar vermutlich mehrere bodies (Sun, Moon, Jupiter...) parallel am Leben erhalten und mit Get-Methoden einfach nur drauf zugreifen, die Inkonsistenzen und Berechnungsfehler entstehen nach meiner Vermutung aber nicht aufgrund der jetzt mehrfachen Body-Instanzen, sondern weil das übergeordnete Observer-Objekt die Beobachtungszeit verwaltet und nicht der jeweilige body. Mir ist erst nach einiger Testerei aufgefallen, dass es nicht genügt entsprechend der Doku von Ephem den body zu erzeugen (self._body = ephem.Sun(self._observer)) und damit korrekte Daten zu bekommen. Für die Auf/Untergangszeiten genügt das und die stimmen auch, bei den Positionsangaben bekommt man aber falsche Werte von Ephem (vermutlich die Untergangspositionen), obwohl man ja eine konkrete Betrachtungszeit übertragen hat. Korrekte Daten liefert Ephem erst, wenn man zusätzlich noch ein self._body.compute(self._observer) auf den body ausführt. Dann stimmt auch die Position.

                    Will man nun in regelmäßigen Abständen Informationen haben, wäre folgendes Vorgehen sinnvoll:

                    - Beim Systemstart den Beobachter platzieren und ein Mal die Berechnungen für Sonne und Mond (nur wenn die Auf/Untergangsposition gewünscht ist) durchführen.

                    - Täglich kurz nach Mitternacht (Zeitzone beachten) für den aktuellen Tag ein Mal die Berechnung für Sonne und Mond (nur wenn die Auf/Untergangsposition gewünscht ist) durchführen. Damit stehen tagesaktuelle und letzte/nächste Infos zur Verfügung.

                    - Bei Bedarf und/oder in regelmäßigen Abständen Positionsdaten neu berechnen lassen. Aufgrund der Seiteneffekte brauche ich dafür aber immer auch wieder neue bodies, stellt sich also die Frage, ob man dafür extra eine eigene Methode anbietet (die aber kaum weniger tut) oder gleich die constellation komplett ausführt.


                    @Bernd:

                    Wie komme ich bei den Item eval an einzelne dict Inhalte bzw. wie geht smarthome.py und SmartVisu dann damit um? Kann ich das in Item-Attribute verteilen o.ä.? Da fehlt mir noch komplett die Peilung.

                    Ich bin gern bereit, alle Kommentare am Schluss zu übersetzen, wenn das Ganze tatsächlich auch ins Repo gehen soll/darf. Von Sphinx habe ich keine Ahnung, passe das aber ebenfalls gerne an, wenn ihr mich da auf den richtigen Pfad setzt.

                    Offen:

                    DIe Erweiterung der Berechnungen auf Gradoffset und Minutenoffset muss ich noch sauber einbauen.

                    Und zum Schluss die jetzige Klasse:

                    Code:
                    #!/usr/bin/env python3
                    #
                    # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                    #########################################################################
                    # Copyright 2016 2016 awknx                    https://knx-user-forum.de/
                    #########################################################################
                    #  This file is part of SmartHomeNG        https://github.com/smarthomeNG
                    #
                    #  SmartHome.py is free software: you can redistribute it and/or modify
                    #  it under the terms of the GNU General Public License as published by
                    #  the Free Software Foundation, either version 3 of the License, or
                    #  (at your option) any later version.
                    #
                    #  SmartHome.py is distributed in the hope that it will be useful,
                    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
                    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                    #  GNU General Public License for more details.
                    #
                    #  You should have received a copy of the GNU General Public License
                    #  along with SmartHome.py.  If not, see <http://www.gnu.org/licenses/>.
                    ##########################################################################
                    
                    
                    # Berechnung astronomischer Daten für Sonne, Mond und ggf. weitere Planeten
                    
                    
                    import logging
                    import datetime
                    import math
                    import dateutil.relativedelta
                    from dateutil.tz import tzoffset
                    
                    try:
                        import ephem
                    except ImportError as e:
                        ephem = None
                    
                    
                    
                    class Astronomy():
                    
                        def __init__(self, tzinfo, lon, lat, elev=0):
                            self.logger = logging.getLogger(__name__)
                            if ephem is None:
                                self.logger.warning("Could not find/use ephem!")
                                return
                            else:
                                self.logger.info("Ephem " + str(ephem.__version__))
                    
                            # Objekt Observer _obs bezieht Berechnung auf die aktuelle Position des Beobachters
                            # Positionsangabe als Grad in Dezimalschreibweise (N+, S-, E+, W-)
                            # Attribute: date (now()), epoch (2000), lat (0), lon (0), elevation (0), temp (25°C), pressure (1010mBar)
                            self._tzinfo = tzinfo
                            self._observer = ephem.Observer()
                            self._observer.lat = str(lat)
                            self._observer.lon = str(lon)
                            if elev:
                                self._observer.elevation = int(elev)
                    
                    
                                # Debug
                    #        self.logger.debug("Init Planet " + str(self._planet))
                    #        self.logger.debug("Init Beobachter Datum UTC" + str(self._observer.date))
                    #        self.logger.debug("Init Beobachter Breitengrad " + str(self._observer.lat))
                    #        self.logger.debug("Init Beobachter Längengrad " + str(self._observer.lon))
                    #        self.logger.debug("Init Beobachter Höhe " + str(self._observer.elevation))
                    
                    
                        # Datenberechnung Planet
                        def constellation(self, planet='Sun', offset_degrees=0, offset_minutes=0, obsdate=None):
                            # Parameter: offset_degrees (Offset in Grad), offset_minutes (Offset in Minuten), obsdate (Datetimeobjekt "2016-10-08 00:00:00+02:00")
                    
                            self._planet = planet
                    
                            # Datum/Zeit des Beobachters für die weiteren Berechnungen festlegen
                            if not obsdate:
                                # Verwendung der aktuellen Zeit
                                obsdate = datetime.datetime.utcnow().replace(microsecond=0)
                            else:
                                # Verwendung und Umrechnung der vorgegebenen lokalen Zeitangabe in UTC
                                # Das haut noch nicht hin, ich komme irgenwie nicht richtig an die Zeitdifferenz zur Lokalzeit ran
                                #obsdate = obsdate - tzoffset.utcoffset(obsdate)
                                obsdate = obsdate
                    
                            #timeshift = tzoffset.utcoffset(obsdate)
                            # Debug
                            #self.logger.debug("     Global Timezone " + str(self._sh.tzinfo()))
                            self.logger.debug("     Parameter obsdate RAW " + str(obsdate))
                            #self.logger.debug("     Timeshift " + str(timeshift))
                    
                    
                            # Horizont des Beobachters verschieben um den Offset in Grad (offset_degrees)
                            self._observer.horizon = str(offset_degrees)
                    
                            # Betrachtungszeitpunkt des Beobachters verschieben um den Offset in Minuten (offset_minutes)
                            obsdate += dateutil.relativedelta.relativedelta(minutes=offset_minutes)
                    
                            # Korrigiertes Datum an den Observer übergeben
                            self._observer.date = obsdate
                    
                            # Planet erzeugen
                            if planet == 'Sun':
                                self._body = ephem.Sun(self._observer)
                            elif planet == 'Moon':
                                self._body = ephem.Moon(self._observer)
                    
                            #Grundberechnungen
                            previous_rising = self._observer.previous_rising(self._body)
                            next_rising = self._observer.next_rising(self._body)
                            previous_transit = self._observer.previous_transit(self._body)
                            next_transit = self._observer.next_transit(self._body)
                            previous_setting = self._observer.previous_setting(self._body)
                            next_setting = self._observer.next_setting(self._body)
                    
                            # Zusatzberechnungen
                            actual_date = ephem.now()
                            # Astronomische Morgendämmerung
                            # Nautische Morgendämmerung
                            # Bürgerliche Morgendämmerung
                            # Aktueller Aufgang
                            if (previous_rising.datetime().day < actual_date.datetime().day):
                                # Vor heutigem Aufgang
                                actual_rising = next_rising
                            else:
                                # Nach heutigem Aufgang
                                actual_rising = previous_rising
                            # Aktueller Transit
                            if (next_transit.datetime().day < actual_date.datetime().day):
                                # Vor heutigem Transit
                                actual_transit = previous_transit
                            else:
                                # Vor heutigem Aufgang
                                actual_transit = next_transit
                            # Aktueller Untergang
                            if (next_setting.datetime().day >= actual_date.datetime().day):
                                # Nach heutigem Untergang
                                actual_setting = previous_setting
                            else:
                                # Vor heutigem Untergang
                                actual_setting = next_setting
                            # Bürgerliche Abenddämmerung
                            # Nautische Abenddämmerung
                            # Astronomische Abenddämmerung
                    
                            # Positionsberechnungen
                            # Aktuelle Positionen werden nicht korrekt berechnet, wenn nach der Instanzierung nicht eine Neuberechnung ausgelöst wird
                            self._body.compute(self._observer)
                    
                            # Höhenwinkel über dem Horizont
                            actual_position_altitude_deg = self._body.alt
                            # Azimutwinkel vom Nordpunkt
                            actual_position_azimut_deg = self._body.az
                    
                            # Mondberechnungen
                            previous_new_moon = ephem.previous_new_moon(self._observer.date)
                            next_new_moon = ephem.next_new_moon(self._observer.date)
                            previous_full_moon = ephem.previous_full_moon(self._observer.date)
                            next_full_moon = ephem.next_full_moon(self._observer.date)
                            moonrun_complete = next_new_moon - previous_new_moon
                            moonrun_partial = (actual_date - previous_new_moon) / moonrun_complete
                            moonphase = int(math.ceil(moonrun_partial * 8))
                    
                            # Konvertierung der Ephem Datumsangaben in Python und Lokalisierung
                            previous_rising = ephem.localtime(previous_rising).replace(microsecond=0)
                            actual_rising = ephem.localtime(actual_rising).replace(microsecond=0)
                            next_rising = ephem.localtime(next_rising).replace(microsecond=0)
                            previous_transit = ephem.localtime(previous_transit).replace(microsecond=0)
                            actual_transit = ephem.localtime(actual_transit).replace(microsecond=0)
                            next_transit = ephem.localtime(next_transit).replace(microsecond=0)
                            previous_setting = ephem.localtime(previous_setting).replace(microsecond=0)
                            actual_setting = ephem.localtime(actual_setting).replace(microsecond=0)
                            next_setting = ephem.localtime(next_setting).replace(microsecond=0)
                            previous_new_moon = ephem.localtime(previous_new_moon).replace(microsecond=0)
                            next_new_moon = ephem.localtime(next_new_moon).replace(microsecond=0)
                            previous_full_moon = ephem.localtime(previous_full_moon).replace(microsecond=0)
                            next_full_moon = ephem.localtime(next_full_moon).replace(microsecond=0)
                    
                            # Debug
                            self.logger.debug("     Parameter planet " + str(planet))
                            self.logger.debug("     Parameter offset_degrees " + str(offset_degrees))
                            self.logger.debug("     Parameter offset_minutes " + str(offset_minutes))
                            self.logger.debug("     Parameter obsdate " + str(obsdate))
                            self.logger.debug("     Beobachter Datum UTC " + str(self._observer.date))
                            self.logger.debug("     Beobachter Breitengrad " + str(self._observer.lat))
                            self.logger.debug("     Beobachter Längengrad " + str(self._observer.lon))
                            self.logger.debug("     Beobachter Höhe " + str(self._observer.elevation))
                            self.logger.debug("     Planet Name " + str(self._body.name))
                            self.logger.debug("     Planet " + str(self._body.name) + " Horizont " + str(self._observer.horizon))
                            self.logger.debug("     Planet " + str(self._body.name) + " aktuelle Höhe DEG " + str(actual_position_altitude_deg))
                            self.logger.debug("     Planet " + str(self._body.name) + " aktueller Azimut DEG " + str(actual_position_azimut_deg))
                            self.logger.debug("     Planet " + str(self._body.name) + " letzter Aufgang " + str(previous_rising))
                            self.logger.debug("     Planet " + str(self._body.name) + " aktueller Aufgang " + str(actual_rising))
                            self.logger.debug("     Planet " + str(self._body.name) + " nächster Aufgang " + str(next_rising))
                            self.logger.debug("     Planet " + str(self._body.name) + " letzter Transit " + str(previous_transit))
                            self.logger.debug("     Planet " + str(self._body.name) + " aktueller Transit " + str(actual_transit))
                            self.logger.debug("     Planet " + str(self._body.name) + " nächster Transit " + str(next_transit))
                            self.logger.debug("     Planet " + str(self._body.name) + " letzter Untergang " + str(previous_setting))
                            self.logger.debug("     Planet " + str(self._body.name) + " aktueller Untergang " + str(actual_setting))
                            self.logger.debug("     Planet " + str(self._body.name) + " nächster Untergang " + str(next_setting))
                            self.logger.debug("     Letzter Neumond " + str(previous_new_moon))
                            self.logger.debug("     Nächster Neumond " + str(next_new_moon))
                            self.logger.debug("     Letzter Vollmond " + str(previous_full_moon))
                            self.logger.debug("     Nächster Vollmond " + str(next_full_moon))
                            self.logger.debug("     Mondphase " + str(moonphase))
                    
                            # Planeteninstanz löschen
                            del self._body
                    
                            # Rückgabe von Datum/Zeit in UTC oder Lokalzeit (jetzt Lokalzeit)?
                            return (actual_position_altitude_deg, actual_position_azimut_deg, previous_rising, actual_rising, next_rising, previous_transit, actual_transit, next_transit, previous_setting, actual_setting, next_setting, previous_new_moon, next_new_moon, previous_full_moon, next_full_moon)
                    Zuletzt geändert von awknx; 14.10.2016, 11:42.

                    Kommentar


                      #25
                      awknx danke schon mal für die mühen. ich denke das ziel sollte ein sauberer PR für das repo sein, den jeder kommentieren / ansehen kann. ich bin auf jeden fall dafür das sauberer zu ziehen, fände aber gut, wenn jeder der hier beitragenden die chance hat, seine meinung abzugeben. daher nicht wundern wenn der PR dann erstmal einige zeit liegt. ich biete mich gerne auch als tester an - wohne ja ebenfalls im münchner umland, kann daher ggf. auch direkt mal feedback geben

                      Kommentar


                        #26
                        Wie funktioniert das mit dem PR (ich vermute mal Pull Request auf Github) - schreibe ich da nur meinen Kram rein bzw. was muss ich da liefern, damit an den entsprechenden Stellen das Ganze letzlich eingebaut wird?

                        Kommentar


                          #27
                          Da ist eher der psilo der Richtige Ansprechpartner. Interessant wäre es mal die Zeit zu stoppen, die die Berechnung benötigt. Für den Rest muß ich mir noch mal Gedanken machen. Derzeit haben wir eine (interne) Logik, die die Werte berechnet und an die Items übergibt.

                          Kommentar


                            #28
                            Du meinst mit der internen Logik aber nicht die location.conf und loaction.py und den timergesteuerten Scheduleraufruf, der auch im genannten Issue aufgeführt ist, oder doch?

                            Ich werde mal schauen, dass ich die fehlenden Teile kurzfristig fertig bekomme, dann kann ja wer Lust hat, mal testen (funktioniert dann ja mit wenigen Eingriffen parallel zum jetzigen System).

                            Kommentar


                              #29
                              Doch, genau die. Es wäre sinnvoll das in dem Zug mit zu überarbeiten. Auch in Hinblick auf den Sonnenstand wäre es gut da eine Art Genauigkeit angeben zu können. Beispielsweise: Wenn der Winkel sich im 1° geändert hat, soll sich das Item auf den aktuellen Wert einstellen.

                              Kommentar


                                #30
                                Ja klar, die beiden Dateien müssen dann auch angepasst werden - genau da drin müsste ich aber noch wissen, wie den Inhalt eines dict auf mehrere Items verteilen kann (also eine Abfrage und alle Ergebnisse gleich an die jeweiligen Items übergeben). Hast du mal einen Tip wer bzw. warum man den Sonnenstand so eng verfolgen will/muss? Oder gehts da eher um eine Visualisierung des Sonnenverlaufs vom Aufgang bis zum Untergang mit Darstellung der momentanen Position? Gradweise Überwachung ist im Grunde eine zeitgetaktete Positionsermittlung, weil die die Erde ja eine konstante Drehgeschwindigkeit hat.

                                Ich habe meine Klasse jetzt auch schon so angepasst, dass ich einen boolschen Parameter übergebe, mit dem beim Funktionsaufruf gesteuert werden kann, ob eine Komplettberechnung (Init, Täglich) oder nur eine Positionsberechnung (wann auch immer) erfolgen soll.

                                Ich muss die kommende Woche mit dem Thema pausieren, danach mache ich wieder weiter :-)
                                Zuletzt geändert von awknx; 15.10.2016, 14:07.

                                Kommentar

                                Lädt...
                                X