Autor Thema: Ist sunset fehlerhaft?  (Gelesen 730 mal)

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Ist sunset fehlerhaft?
« am: 25 August 2018, 15:43:42 »
Guten Tag, ich habe einen Widerspruch nicht auflösen können. Wenn ich das Modul Astro.pm von pah anschaue, sehe ich derzeit in Berlin
SunSet
20:11
und gleichzeitig liefert {sunset("HORIZON=0")}
20:07:09Beide Angaben sind nicht identisch. Da pahs Modul sich an den umfangreichen Rechnungen diverser Astronomiewebseiten orientiert und diese Zeit auch mit Angaben aus dem Web übereinstimmt, vermute ich, dass sunset() nicht ganz korrekt ist.

Oder habe ich was falsch eingegeben?

Anmerkung: Unter "sunset" versteht man mW in der Astronomie üblicherweise die Zeit, in der die Oberkante der Sonne auf dem in Normalnull befindlichen Horizont verschwunden ist.
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 19009
Antw:Ist sunset fehlerhaft?
« Antwort #1 am: 25 August 2018, 16:20:32 »
Zitat
Anmerkung: Unter "sunset" versteht man mW in der Astronomie üblicherweise die Zeit, in der die Oberkante der Sonne auf dem in Normalnull befindlichen Horizont verschwunden ist.
Meines Wissens ist die Definition des "astronomischen Sonnenuntergangs" 18 Grad unter Horizont, damit man die Sterne beobachten kann. Es gibt aber diverse andere Definitionen, je nach Einsatzgebiet. Die Voreinstellung fuer sunrise/sunset in FHEM ist CIVIL (die Sonne ist 6 Grad unter dem Horizont, man kann nicht mehr ohne Hilfslicht lesen), man kann es aber verstellen, siehe https://fhem.de/commandref_modular.html#SUNRISE_EL

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #2 am: 25 August 2018, 16:23:24 »
Ja klar, die verschiedenen Definitionen sind ja in der commandref schön erklärt. Aber {sunset("HORIZON=0")} sollte doch nun gerade nicht 18 Grad unter Horizont liefern sondern exakt am Horizont (oder?). Und dann frage ich mich, wieso diese Zeit von der verschieden ist, die pah mit Astro ausrechnet?
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 19009
Antw:Ist sunset fehlerhaft?
« Antwort #3 am: 25 August 2018, 16:41:01 »
Die Quellen sind offen, und Mathe gabs in der Schule :)

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #4 am: 25 August 2018, 16:43:42 »
Na ich wollte erstmal sicher gehen, dass ich nichts übersehen habe. Ich vermute, du hast eine Näherungsformel genommen, während pah die ausführliche Rechnung macht. Letztere ist genauer.

In welcher Datei ist Sunset definiert?


Gesendet von iPhone mit Tapatalk Pro
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 19009
Antw:Ist sunset fehlerhaft?
« Antwort #5 am: 25 August 2018, 17:03:06 »
99_SUNRISE_EL.pm.

Ist urspruenglich aus dem Perl Modul DateTime::Event::Sunrise entstanden (vulgo kopiert), indem ich alle Abhaengigkeiten von den benutzten Date:: Modulen entfernt habe, da ich diese nicht auf dem Fritzbox installieren konnte.

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #6 am: 25 August 2018, 17:47:22 »
Hmm, jetzt bin ich mit meinem Perl-Latein am Ende. Also ich fasse mal zusammen, was ich kapiere. Meiner Vermutung nach wird sunrise hier berechnet (obwohl die eigentliche Funktion "sunset" gar nicht in der Datei sehe):
sub
_sunrise_sunset($$$$$)
{
  my ( $d, $lon, $lat, $altit, $h ) = @_;

  my $sidtime = _revolution( _GMST0($d) + 180.0 + $lon );

  # Compute Sun's RA + Decl + distance at this moment
  my ( $sRA, $sdec, $sr ) = _sun_RA_dec($d);

  # Compute time when Sun is at south - in hours UT
  my $tsouth  = 12.0 - _rev180( $sidtime - $sRA ) / $h;

  # Compute the diurnal arc that the Sun traverses to reach
  # the specified altitude altit:
  my $cost =
    ( sind($altit) - sind($lat) * sind($sdec) ) /
    ( cosd($lat) * cosd($sdec) );

  my $t;
  if ( $cost >= 1.0 ) {
      $t = 0.0;    # Sun always below altit
  }
  elsif ( $cost <= -1.0 ) {
      $t = 12.0;    # Sun always above altit
  }
  else {
      $t = acosd($cost) / 15.0;    # The diurnal arc, hours
  }

  # Store rise and set times - in hours UT

  my $hour_rise_ut = $tsouth - $t;
  my $hour_set_ut  = $tsouth + $t;
  return ( $hour_rise_ut, $hour_set_ut );

}
wobei die entscheidende mathematische Funktion noch diese hier ist
# Sun's Right Ascension (RA), Declination (dec) and distance (r)
sub
_sun_RA_dec($)
{
  my ($d) = @_;

  my ( $r, $lon ) = _sunpos($d);

  my $x = $r * cosd($lon);
  my $y = $r * sind($lon);

  my $obl_ecl = 23.4393 - 3.563E-7 * $d;

  my $z = $y * sind($obl_ecl);
  $y = $y * cosd($obl_ecl);

  my $RA  = atan2d( $y, $x );
  my $dec = atan2d( $z, sqrt( $x * $x + $y * $y ) );

  return ( $RA, $dec, $r );
}
Neben den radial-Koordinaten ist da eine Näherungsgleichung drin. Außerdem vermute ich, dass zwischen zwei Zeitpunkten der Horizont interpoliert wird. Diese Interpolation ergibt dann den genauen Zeitpunkt.

pah macht das nach den astronomischen Berechnungen und die sind iterativ. Er rechnet in Astro.pm so
sub Astro_SunPosition($$$){
...
  return ( \%sunCoor );
}
und dann
########################################################################################################
#
# Astro_SunRise - Find (local) time of sunrise and sunset, and twilights
#                 JD is the Julian Date of 0h local time (midnight)
#                 Accurate to about 1-2 minutes
#                 recursive: 1 - calculate rise/set in UTC in a second run
#                 recursive: 0 - find rise/set on the current local day.
#                                This is set when doing the first call to this function
#
########################################################################################################

sub Astro_SunRise($$$$$$){
  my ($JD, $deltaT, $lon, $lat, $zone, $recursive) = @_;
 
  my $jd0UT = floor($JD-0.5)+0.5;   # JD at 0 hours UT
 
  #-- calculations for noon
  my $sunCoor1 = Astro_SunPosition($jd0UT+   $deltaT/24./3600.,undef,undef);

  #-- calculations for next day's UTC midnight
  my $sunCoor2 = Astro_SunPosition($jd0UT+1.+$deltaT/24./3600.,undef,undef);
 
  #-- rise/set time in UTC
  my ($transit,$rise,$set) = Astro_RiseSet($jd0UT, $sunCoor1->{diameter}, $sunCoor1->{parallax},
    $sunCoor1->{ra}, $sunCoor1->{dec}, $sunCoor2->{ra}, $sunCoor2->{dec}, $lon, $lat, 1,undef);
  if( $transit eq "---" ){
    Log 1,"[Astro_SunRise] no solution possible - maybe the sun never sets ?";
   return( ($transit,$rise,$set) );
  }
 
  my ($transittemp,$risetemp,$settemp);
  #-- check and adjust to have rise/set time on local calendar day
  if ( $recursive==0 ) {
    if ($zone>0) {
      #rise time was yesterday local time -> calculate rise time for next UTC day
      if ($rise >=24-$zone || $transit>=24-$zone || $set>=24-$zone) {
        ($transittemp,$risetemp,$settemp) = Astro_SunRise($JD+1, $deltaT, $lon, $lat, $zone, 1);
        $transit = $transittemp
          if ($transit>=24-$zone);
        $rise = $risetemp
          if ($rise>=24-$zone);
        $set = $settemp
          if ($set>=24-$zone);
      }
    }elsif ($zone<0) {
      #rise time was yesterday local time -> calculate rise time for previous UTC day
      if ($rise<-$zone || $transit<-zone || $set<-zone) {
        ($transittemp,$risetemp,$settemp) = Astro_SunRise($JD-1, $deltaT, $lon, $lat, $zone, 1);
      $rise = $risetemp
        if ($rise<-$zone);
      $transit = $transittemp
        if ($transit<-$zone);
      $set  = $settemp
        if ($set <-$zone);
      }
    }

    $transit = Astro_mod($transit+$zone, 24.);
    $rise    = Astro_mod($rise   +$zone, 24.);
    $set     = Astro_mod($set    +$zone, 24.);

#-- Twilight calculation
#-- civil twilight time in UTC.
my $CivilTwilightMorning;
my $CivilTwilightEvening;
($transittemp,$risetemp,$settemp) = Astro_RiseSet($jd0UT, $sunCoor1->{diameter}, $sunCoor1->{parallax},
   $sunCoor1->{ra}, $sunCoor1->{dec}, $sunCoor2->{ra}, $sunCoor2->{dec}, $lon, $lat, 1, -6.*$DEG);
if( $transittemp eq "---" ){
      Log 3,"[Astro_SunRise] no solution possible for civil twilight - maybe the sun never sets below -6 degrees?";
      $CivilTwilightMorning = "---";
      $CivilTwilightEvening = "---";
    }else{
  $CivilTwilightMorning = Astro_mod($risetemp +$zone, 24.);
  $CivilTwilightEvening = Astro_mod($settemp  +$zone, 24.);
    }
   
#-- nautical twilight time in UTC.
my $NauticTwilightMorning;
my $NauticTwilightEvening;
($transittemp,$risetemp,$settemp) = Astro_RiseSet($jd0UT, $sunCoor1->{diameter}, $sunCoor1->{parallax},
  $sunCoor1->{ra}, $sunCoor1->{dec}, $sunCoor2->{ra}, $sunCoor2->{dec}, $lon, $lat, 1, -12.*$DEG);
if( $transittemp eq "---" ){
      Log 3,"[Astro_SunRise] no solution possible for nautical twilight - maybe the sun never sets below -12 degrees?";
      $NauticTwilightMorning = "---";
      $NauticTwilightEvening = "---";
    }else{
      $NauticTwilightMorning = Astro_mod($risetemp +$zone, 24.);
  $NauticTwilightEvening = Astro_mod($settemp  +$zone, 24.);
}

#-- astronomical twilight time in UTC.
my $AstroTwilightMorning;
my $AstroTwilightEvening;
($transittemp,$risetemp,$settemp) = Astro_RiseSet($jd0UT, $sunCoor1->{diameter}, $sunCoor1->{parallax},
  $sunCoor1->{ra}, $sunCoor1->{dec}, $sunCoor2->{ra}, $sunCoor2->{dec}, $lon, $lat, 1, -18.*$DEG);
if( $transittemp eq "---" ){
      Log 3,"[Astro_SunRise] no solution possible for astronomical twilight - maybe the sun never sets below -18 degrees?";
      $AstroTwilightMorning = "---";
      $AstroTwilightEvening = "---";
    }else{
  $AstroTwilightMorning = Astro_mod($risetemp +$zone, 24.);
  $AstroTwilightEvening = Astro_mod($settemp  +$zone, 24.);
}

#-- custom twilight time in UTC
my $CustomTwilightMorning;
my $CustomTwilightEvening;
    ($transittemp,$risetemp,$settemp) = Astro_RiseSet($jd0UT, $sunCoor1->{diameter}, $sunCoor1->{parallax},
  $sunCoor1->{ra}, $sunCoor1->{dec}, $sunCoor2->{ra}, $sunCoor2->{dec}, $lon, $lat, 1, $Astro{ObsHor}*$DEG);
  if( $transittemp eq "---" ){
      Log 3,"[Astro_SunRise] no solution possible for custom twilight - maybe the sun never sets below ".$Astro{ObsHor}." degrees?";
      $CustomTwilightMorning = "---";
      $CustomTwilightEvening = "---";
    }else{
  $CustomTwilightMorning = Astro_mod($risetemp +$zone, 24.);
  $CustomTwilightEvening = Astro_mod($settemp  +$zone, 24.);
}

return( ($transit,$rise,$set,$CivilTwilightMorning,$CivilTwilightEvening,
  $NauticTwilightMorning,$NauticTwilightEvening,$AstroTwilightMorning,$AstroTwilightEvening,$CustomTwilightMorning,$CustomTwilightEvening) ); 
  }else{
    return( ($transit,$rise,$set) ); 
  }
}

Jetzt frage ich mich:  Besteht denn eine einfache Möglichkeit, dass die Berechnungen von pah einfach die Grundlage für sunset bilden? Oder kann man durch Änderung des Funktionsaufrufs die Astro-Funktion einfach verwenden? Also statt "sunset()" verwendet man "Astro_SunRise($$$$$$)" oder was auch immer?
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #7 am: 25 August 2018, 22:06:02 »
Lesen müste man:

... kann man in jedem eigenen Modul auch ein
require "95_Astro.pm";an den Anfang setzen. Und sogar ohne Definition eines Astro-Devices auf die somit bekannten Routinen zugreifen. Etwa per
Astro_Get( IRGENDEINE HASH REFERENZ,"dummy","text", "SunRise","2019-12-24");um den Sonnenaufgang an Heiligabend 2019 zu bekommen.
Man muss nur noch den aktuellen Tag einsetzen und hat alles für ein korrektes sunset().

Ich bin ja Programmierlaie: Ich hätte das gern als Ersatz für das ungenauere Sunset. Was muss ich da tun?Erstmal probieren, ob ich das hinkriege...
« Letzte Änderung: 25 August 2018, 22:40:40 von andies »
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline betateilchen

  • Developer
  • Hero Member
  • ****
  • Beiträge: 15048
  • s/fhem\.cfg/configDB/g
Antw:Ist sunset fehlerhaft?
« Antwort #8 am: 25 August 2018, 22:56:06 »
ich geh mal Popcorn holen...
-----------------------
Unaufgeforderte Anfragen per email werden von mir nicht beantwortet. Dafür ist das Forum da.
-----------------------
Nächster Hamburg-Stammtisch: 14.12.2018 - 18:30 Uhr

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #9 am: 25 August 2018, 22:57:14 »
Also mir beim Programmieren zuzusehen gehört in Genre Horrorfilm.


Gesendet von iPad mit Tapatalk Pro
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #10 am: 26 August 2018, 10:53:40 »
Also ich gebe nach mehreren Stunden auf, betateilchen kann sein Popcorn wieder einpacken.

Mir fehlen einfach zu viele Perl-Kenntnisse, das geht doch weiter als meine Möglichkeiten. Ich muss für fast jeden Schritt etwas nachlesen und das dauert einfach zu lange. Ich finde Astro_Get und verstehe auch, dass man einen hash übergibt sowie durch das "text" dafür sorgt, dass eine Textausgabe erfolgt. Wird kein Datum eingegeben, dann holt sich Astro_Get das aktuelle Datum. Das ist schon mal super und damit hätte man die Klassiker wie sunset, sunrise sowie die typischen Angaben von REAL, CIVIL, NAUTIC, ASTRONOMIC, weil die auch in Astro berechnet wurden. Die könnte man sofort holen.

Mir ist aber zum Beispiel nicht klar was ich tun soll, wenn jemand einen speziellen HORIZON eingibt. Das muss ja dann an Astro_Get übergeben werden, damit Astro_Compute alles richtig macht. Ich vermute mal, das müsste in den $hash - nur ist ja kein spezielles device angegeben?

Ich habe für mich jetzt einen workaround und nutze sunset via Astro (ReadingsVal("Astro","Sunset",""), das reicht mir nun.

- ENDE -
« Letzte Änderung: 26 August 2018, 11:08:39 von andies »
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #11 am: 28 August 2018, 07:19:47 »
Abspann "Übergangslösung"

Zeitberechnung in DOIF geht auch mit den Werten aus Astro. Lediglich
{sunset()}ersetzen durch
{my $dummy;;Astro_Get($dummy,"dummy","text", "SunSet")}
Also z.B.
define di_light DOIF ([({my $dummy;;Astro_Get($dummy,"dummy","text", "SunSet")}-600)])(set lamp on)
HORIZON=irgendwas geht damit nicht.
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline Prof. Dr. Peter Henning

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5741
Antw:Ist sunset fehlerhaft?
« Antwort #12 am: 13 September 2018, 15:59:14 »
Jetzt will ich mal einen schmutzigen Trick ins Spiel bringen - ohne dass ich ihn selber ausprobiert hätte. Die Funktion Astro_Get bekommt im ersten Argument eine hash-Referenz übergeben. Und holt sich die Attribute aus diesem hash - das muss also kein hash eines Astro-Devices sein.

Es müsste also folgendes gehen:

1.) Ein beliebiges Device (sagen wir mit Namen "Bla") bekommt ein User Attribute mit Namen "horizon", dessen Wert  der gewünschte Horizontwinkel ist.

2.) Der Funktionsaufruf müsste dann lauten
 
{Astro_Get($defs{"Bla"},"Bla","text", "CustomTwilightEvening")}
und den Sonnenuntergang für diesen Horizontwinkel liefern.

LG

pah

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #13 am: 13 September 2018, 16:18:04 »
Klappt
Internals:
   CFGFN     
   NAME       Bla
   NR         805
   STATE      ???
   TYPE       dummy
Attributes:
   horizon    -8.5
   userattr   horizon
und der Befehl liefert
20:19im Einklang mit den jüdischen Speiseregeln ;-)

Dan würde es sich doch lohnen, das fehlerhafte und (nach meinem Verständnis auch unnötige) SUNRISE_EL.pm durch diesen Trick zu ersetzen? Oder gibt's dann wieder Popcorn?
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Offline andies

  • Hero Member
  • *****
  • Beiträge: 1441
Antw:Ist sunset fehlerhaft?
« Antwort #14 am: 15 September 2018, 11:30:50 »
1.) Ein beliebiges Device (sagen wir mit Namen "Bla") bekommt ein User Attribute mit Namen "horizon", dessen Wert  der gewünschte Horizontwinkel ist
Warum nicht Bla=global?

Ich werde das mal rudolfkoenig vorschlagen, in dem anderen Thread.


Gesendet von iPhone mit Tapatalk Pro
FHEM 5.8 auf RaspPi3 (Raspbian:  4.14.34-v7+ ); Perl: v5.20.2
SIGNALduino (433 MHz) und HM-UART (868 MHz)
wenige Brennenstuhl-IT, gaanz viele Sonoffs, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

 

decade-submarginal