59_Weather.pm - Vorschläge

Begonnen von betateilchen, 12 Januar 2019, 20:34:24

Vorheriges Thema - Nächstes Thema

holle75

Eine Frage von hier: https://forum.fhem.de/index.php/topic,95823.msg918120.html#msg918120

Ich hätte eine Bitte. Irgendwo wird das von DarkSky gelieferte "_time" in "_pubDate"  (mit den lustigen Umlautproblemen die trotz aller aufgezeigten Fixversuche bei mir immer noch bestehen) gewandelt und ausgeliefert. Damit ich meinen Plot fertig bekomme, und Perl eher Codekopieren statt verstehen bei mir ist, die Frage, wie ich _pubDate in ein logProxy verständliches Format bekomme. Zb -> 2010-05-22 13:43:17

Ich suche seit Stunden/Tagen, aber genau dieses Format wie im Moment _pubDate wird scheinbar internetweit recht selten verwandt.

_pubDate bekomme ich mit meinem Wissensstand nicht formatiert. Bei original DarkSky hatte ich bisher $timestamp mit _time generiert:

($hdmsec, $hdmmin, $hdmhour, $hdmmday, $hdmmon, $hdmyear, $hdmwday, $hdmyday, $hdmisdst) = localtime(ReadingsVal($device, "hfc".$h."_time",undef));

# necessary conversion of $mon and $year
$hdmmon += 1;
$hdmyear += 1900;
   
$timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $hdmyear, $hdmmon, $hdmmday, $hdmhour, $hdmmin, $hdmsec);


oder ihr liefert als ExtraWert _time wieder mit? Wobei ich nicht weiß, ob andere etwas davon hätten.

Danke und Gruß
H.

mi.ke

Zitat von: holle75 am 14 März 2019, 11:40:55
Ich hätte eine Bitte. Irgendwo wird das von DarkSky gelieferte "_time" in "_pubDate"  (mit den lustigen Umlautproblemen die trotz aller aufgezeigten Fixversuche bei mir immer noch bestehen) gewandelt und ausgeliefert.

Es scheint aber anders zu sein, denn "pubDate" wird nicht von der API geliefert, sondern ist lediglich die Zeit, wann "set $NAME update" readings bekommt. Ich hab mir einfach ein userreading pubDateTs {time()} gemacht, dass exakt identisch ist. Dies verwende ich dann in diversen notifys.

Im "alten" Weathermodul war, sowit ich weiss, das "pubDate" die Zeit, wann die Info vom Dienst bereitgestellt wurde.
Das wäre mir ehrlich gesagt auch lieber.

Die "lustigen Umlautproblemen" waren doch eigentlich gefixt, oder? (zumindst ist es mir eben erst wieder aufgefallen)

Cheers
mi.ke
FHEM 5.9 | RPi4 + 5 x RPi(Z) + FB7590 + FB 6890 LTE via LAN und WAN (VPN) verbunden.
2 x CUL868 + 3 x RFXTRX(e) + 6 x HMwLanGW + 4 x z2tGw + 5 x LGW + 2 x IRBlast + CO2 +++
FS20, FHT, FMS, Elro(mod), CM160, Revolt, LGTV, STV, AVR, withings, HM-sec-*, HM-CC-RT-DN, AMAD, PCA301, arlo, Aqara

holle75

Moinsen Mi.ke, ich kenne die Wertbenennungen nur von der DarkSky API direkt über HTTPMOD und weiß nicht genau wie was in WEATHER benannt oder konvertiert wird. Wenn ich die Readings vergleiche, kam ich auf _time als Equivalent zu konvertiertem _pubDate. Das kann auch falsch sein.

Was ich eigentlich suche, ist die Zeit für die das entsprechende Hourly-Reading gilt :) ... hfcxx_pubDate .... und das im logproxy verständlichem Format.

Und ich glaube, auch bei fcxx_pubDate ist es das, nicht die Update-Zeit

Bei mir mit vorgestrigem Update hat es die Umlautprobleme. Ein locale (und die anderen checks) gibt mir aber de zurück.


CoolTux


GET https://api.darksky.net/forecast/0123456789abcdef9876543210fedcba/42.3601,-71.0589
     
      {
          "latitude": 42.3601,
          "longitude": -71.0589,
          "timezone": "America/New_York",
          "currently": {
              "time": 1509993277,
              "summary": "Drizzle",
              "icon": "rain",
              "nearestStormDistance": 0,
              "precipIntensity": 0.0089,
              "precipIntensityError": 0.0046,
              "precipProbability": 0.9,
              "precipType": "rain",
              "temperature": 66.1,
              "apparentTemperature": 66.31,
              "dewPoint": 60.77,
              "humidity": 0.83,
              "pressure": 1010.34,
              "windSpeed": 5.59,
              "windGust": 12.03,
              "windBearing": 246,
              "cloudCover": 0.7,
              "uvIndex": 1,
              "visibility": 9.84,
              "ozone": 267.44
          },


pubDate ist nichts weiter wie "currently": { "time": 1509993277,    halt in ein humanreadable format gebracht.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

holle75

Über HTTPMOD als JSON abgeftragt liefert die DarkSky API

2019-03-14 13:17:27   hourly_data_01_apparentTemperature 12.79
     2019-03-14 13:17:27   hourly_data_01_cloudCover 0.01
     2019-03-14 13:17:27   hourly_data_01_dewPoint -5.12
     2019-03-14 13:17:27   hourly_data_01_humidity 0.28
     2019-03-14 13:17:27   hourly_data_01_icon clear-day
     2019-03-14 13:17:27   hourly_data_01_ozone 385.6
     2019-03-14 13:17:27   hourly_data_01_precipIntensity 0
     2019-03-14 13:17:27   hourly_data_01_precipProbability 0
     2019-03-14 01:17:27   hourly_data_01_precipType rain
     2019-03-14 13:17:27   hourly_data_01_pressure 1015.02
     2019-03-14 13:17:27   hourly_data_01_summary Clear
     2019-03-14 13:17:27   hourly_data_01_temperature 12.79
     2019-03-14 13:17:27   hourly_data_01_time 1552564800
     2019-03-14 13:17:27   hourly_data_01_uvIndex 4
     2019-03-14 13:17:27   hourly_data_01_visibility 9.88
     2019-03-14 13:17:27   hourly_data_01_windBearing 335
     2019-03-14 13:17:27   hourly_data_01_windGust 15.13
     2019-03-14 13:17:27   hourly_data_01_windSpeed 9.06


Das meine ich. _time/pubDate ist die Zeit für die die entsprechenden Day/Hourly-Readings gelten.... ist auch fortlaufend hochzählend passen zur hourly_data_xx.

.... und wie bekomme ich den Wert jetzt aus dem humanreadable Reading pubDate von WEATHER wieder in so ein Format ... 2010-05-22 13:43:17 ....  gewandelt?

mi.ke

Zitat von: CoolTux am 14 März 2019, 13:50:29
pubDate ist nichts weiter wie "currently": { "time": 1509993277,    halt in ein humanreadable format gebracht.

Wäre es vielleicht eine Idee, es zu lösen, wie Du es beim UWZ-Modul gemacht hast?

Dort ist die Zeitangabe als Reading in time() und per Attribut humanreadable=1 werden zusätzliche Readings erzeugt (_Date _Time).

Hätte den Vorteil, dass die Zeit in "epoch" vorliegt und der User es sich formatieren kann wie er will.
Wer möchte kann sich auch ohne Kenntnis die "humanreadable" anzeigen lassen.
FHEM 5.9 | RPi4 + 5 x RPi(Z) + FB7590 + FB 6890 LTE via LAN und WAN (VPN) verbunden.
2 x CUL868 + 3 x RFXTRX(e) + 6 x HMwLanGW + 4 x z2tGw + 5 x LGW + 2 x IRBlast + CO2 +++
FS20, FHT, FMS, Elro(mod), CM160, Revolt, LGTV, STV, AVR, withings, HM-sec-*, HM-CC-RT-DN, AMAD, PCA301, arlo, Aqara

CoolTux

Das kann man machen wenn es sich um ein Frontend Modul handeln würde. Aber DarkSkyAPI ist ein Backend Modul mit einer festen API Beschreibung. Man kann mit Boris mal darüber reden wie man sowas am besten ändern kann. Dann muß die Darstellung aber eben vom Weather Modul geregelt werden. Zu mindest was pubDate an geht.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

ab77

Hallo zusammen,

letztens habe ich auf DarkSky umgestellt, allerdings fehlte mir dann ein LogProxy für das Chart-Widget.
Da ich nirgends eine fertige LogProxy-Funktion finden konnte, habe ich mich mal ans Werk gemacht und was gebastelt.
Meine Lösung ist nicht so universell wie die für ProPlanta, aber sie tut was ich wollte: Sie liefert die 49 Stundenwerte des angegebenen Readings, die unter hcf1 bis hfc49 zu finden sind.

Aufruf:
Func:logProxy_darkskyHours(\\x22<device>\\x22,\\x22<reading>\\x22)
wobei <device> halt der Name des device ist und <reading> der Namensteil des Readings hinter dem ,,hfc_". Z.B.:
Func:logProxy_darkskyHours(\\x22wetter\\x22,\\x22temperature\\x22)
Die Funktion kann beim Chart-Widget direkt in die Definition von data-columnspec eingesetzt werden.

WICHTIG:
die Datum/Zeit-Angaben, die das DarkSkyApi unter PubDate liefert, konnte ich so nicht verarbeiten. Wer dieses LogProxy verwenden will, muss das Modul DarkSkyApi.pm deshalb leider folgendermassen patchen:
An drei Stellen ist der Anfang der jeweiligen Zeile
'pubDate' => strftimeWrapper("%a, %e %b %Y %H:%M", .....
zu ersetzen durch:
'pubDate' => strftimeWrapper("%d.%m.%Y %H:%M", .....
Mir ist klar, dass das Patchen nicht optimal ist, aber vielleicht fällt ja jemandem etwas besseres hierzu ein.

Noch ein paar Worte zum Code:
Ich benutze Perl nur, wenn ich muss. Ich freue mich also über Anmerkungen oder Korrekturen zum Code.

sub logProxy_darkskyHours($$) {
my ($device, $hfcName) = @_;
   
return undef if(!$device);
   
my ($h,$fcDay,$mday,$mon,$year);
my $timestamp;
my $reading;
my $value;
my $ret = "";

for (my $hfc=0;$hfc<=49;$hfc++){
$reading="hfc".$hfc."_".$hfcName;
$value = ReadingsVal($device,$reading,undef);
$reading="hfc".$hfc."_pubDate";
($mday,$mon,$year,$h) = split('\.| |:',ReadingsVal($device,$reading,undef));
$timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $year, $mon, $mday, $h, 0, 0);
$ret .= "$timestamp $value\n";
    }
return ($ret);
}




holle75

Bei mir sieht das für einen svg-Plot so aus:

############## hdm WetterDarkSkyModule Wetter Plot funktion ##################################
sub logProxy_WetterDarkSkyModule2Plot($$$$;$$) {
my ($device, $fcValue, $from, $to, $fcHour, $expMode) = @_;
    my $regex;
    my @rl;
my $hdmreading;
my $hdmtime;
   
return undef if(!$device);
if ($fcValue =~ s/_$//)
{
$regex = "^hfc[\\d]+_".$fcValue."\$";
}   
    $fcHour = 12 if(!defined $fcHour);
    $expMode = "point" if(!defined $expMode);
#Log3 undef,2, "regex: ".$regex;
if( defined($defs{$device}) ) {
if( $defs{$device}{TYPE} eq "Weather" ) {
            @rl = sort{
                my ($an) = ($a =~ m/hfc(\d+)_.*/);
                my ($bn) = ($b =~ m/hfc(\d+)_.*/);
                $an <=> $bn or $a cmp $b;
                }( grep /${regex}/,keys %{$defs{$device}{READINGS}} );
return undef if( !@rl );
} else {
Log3 undef, 2, "logProxy_WetterDarkSkyModule2Plot: $device is not a Weather device";
return undef;
}
}
#Log3 undef,2, Dumper(@rl);
my $fromsec = SVG_time_to_sec($from);
my $tosec   = SVG_time_to_sec($to);
my $sec = $fromsec;
my ($h,$hdmsec,$hdmmin,$hdmhour,$hdmmday,$hdmmon,$hdmyear,$hdmwday,$hdmyday,$hdmisdst);
my $timestamp;
   
my $reading;
my $value;
my $prev_value;
my $min = 999999;
my $max = -999999;
my $ret = "";

# while not end of plot range reached
while(($sec < $tosec) && @rl) {
#remember previous value for start of plot range
$prev_value = $value;

$reading = shift @rl;
        ($h) = $reading =~ m/^hfc(\d+).*/;
$value = ReadingsVal($device,$reading,undef);


use Date::Parse;
$hdmreading = ReadingsVal($device, "hfc".$h."_pubDate",undef);
$hdmreading =~ s/^....//; #Wochentag weg
$hdmreading =~ s/ä/a/; #März
$hdmreading =~ s/i/y/; #Mai
$hdmreading =~ s/k/c/; #Oktober
$hdmreading =~ s/z/c/; #Dezember
$hdmtime = str2time($hdmreading);


#Log3 undef,2, "hdmreading: ".$hdmreading;
#Log3 undef,2, "hdmtime: ".$hdmtime;


#($hdmsec, $hdmmin, $hdmhour, $hdmmday, $hdmmon, $hdmyear, $hdmwday, $hdmyday, $hdmisdst) = localtime(ReadingsVal($device, "hfc".$h."_time",undef));
($hdmsec, $hdmmin, $hdmhour, $hdmmday, $hdmmon, $hdmyear, $hdmwday, $hdmyday, $hdmisdst) = localtime($hdmtime);






# necessary conversion of $mon and $year
$hdmmon += 1;
$hdmyear += 1900;
   
$timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $hdmyear, $hdmmon, $hdmmday, $hdmhour, $hdmmin, $hdmsec);
#Log3 undef,2, "timestamp: ".$timestamp;
$sec = SVG_time_to_sec($timestamp);
       
# skip all values before start of plot range
next if( SVG_time_to_sec($timestamp) < $fromsec );

# add first value at start of plot range
if( !$ret && $prev_value ) {
$min = $prev_value if( $prev_value < $min );
$max = $prev_value if( $prev_value > $max );
$ret .= "$from $prev_value\n";
}

# done if after end of plot range
last if($sec > $tosec);

$min = $value if( $value < $min );
$max = $value if( $value > $max );

# add actual controll point
$ret .= "$timestamp $value\n";

#Log 3, "$timestamp $value -0- $reading";
}
    if(($sec < $tosec) && !@rl && ($expMode eq "day")) {
    $timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $hdmyear, $hdmmon, $hdmmday, 23, 59, 59);
    if(SVG_time_to_sec($timestamp) < $tosec) {
        $ret .= "$timestamp $value\n";
        }
        else {
$ret .= "$to $value\n";
        }
    }
    elsif(($sec > $tosec) && ($expMode eq "day")) {
        $value = $prev_value + ($value - $prev_value)*(86400 + ($tosec - $sec))/86400;
        $ret .= "$to $value\n";
    }
return ($ret,$min,$max,$prev_value);
}
############## end hdm WetterDarkSkyModule Wetter Plot funktion ##################################


aber auch nur zusamengeschustert und mit viel Hilfe hier aus dem Forum umgesetzt.

Spannend der Part:

use Date::Parse;
$hdmreading = ReadingsVal($device, "hfc".$h."_pubDate",undef);
$hdmreading =~ s/^....//; #Wochentag weg
$hdmreading =~ s/ä/a/; #März
$hdmreading =~ s/i/y/; #Mai
$hdmreading =~ s/k/c/; #Oktober
$hdmreading =~ s/z/c/; #Dezember
$hdmtime = str2time($hdmreading);


das modifiziert den Timestamp in nutzbar ohne in der Modul.pm was basteln zu müssen.