From eeae8a47865d84d00dabca97ead1f8978ec9be65 Mon Sep 17 00:00:00 2001 From: LeonGaultier Date: Fri, 11 Oct 2024 17:51:30 +0000 Subject: [PATCH] 59_Weather: fix forcast intervall, safe token count git-svn-id: https://svn.fhem.de/fhem/trunk@29223 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/59_Weather.pm | 5 +- fhem/lib/FHEM/APIs/Weather/wundergroundAPI.pm | 163 ++++++++++-------- fhem/lib/FHEM/Core/Weather.pm | 3 +- 4 files changed, 100 insertions(+), 72 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 7c7d598a8..bb92b520d 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it + - bugfix: 59_Weather: fix forcast intervall, safe token count - feature: 74_AutomowerConnect: new setter for synchronizing mower timestamp - bufgix: 72_FRITZBOX: kleinere Fehler bei zu alten FritzOS Versionen - feature: 72_FRITZBOX: Neue Readings box_pwr_... diff --git a/fhem/FHEM/59_Weather.pm b/fhem/FHEM/59_Weather.pm index b6ca7c5eb..a7af721d5 100755 --- a/fhem/FHEM/59_Weather.pm +++ b/fhem/FHEM/59_Weather.pm @@ -2,12 +2,13 @@ ############################################################################## # # 59_Weather.pm -# (c) 2009-2023 Copyright by Dr. Boris Neubert +# (c) 2009-2024 Copyright by Dr. Boris Neubert # e-mail: omega at online dot de # # Contributors: # - Marko Oldenburg (CoolTux) # - Lippie +# - stefanru (wundergroundAPI) # # # This file is part of fhem. @@ -543,7 +544,7 @@ __END__ ], "release_status": "stable", "license": "GPL_2", - "version": "v2.2.22", + "version": "v2.2.30", "author": [ "Marko Oldenburg " ], diff --git a/fhem/lib/FHEM/APIs/Weather/wundergroundAPI.pm b/fhem/lib/FHEM/APIs/Weather/wundergroundAPI.pm index 32a23cd40..5e51e427b 100644 --- a/fhem/lib/FHEM/APIs/Weather/wundergroundAPI.pm +++ b/fhem/lib/FHEM/APIs/Weather/wundergroundAPI.pm @@ -15,9 +15,9 @@ return "$@" if ($@); return $ret if ($ret); $::packages{wundergroundAPI}{META} = $META; -use version 0.77; our $VERSION = $META->{version}; +use version 0.80; our $VERSION = $META->{version}; -# use Data::Dumper; +use Data::Dumper; # try to use JSON::MaybeXS wrapper # for chance of better performance + open code @@ -103,10 +103,11 @@ sub new { ? $argsRef->{apikey} : 'none' ), - lang => $argsRef->{language}, - lat => ( split( ',', $argsRef->{location} ) )[0], - long => ( split( ',', $argsRef->{location} ) )[1], - fetchTime => 0, + lang => $argsRef->{language}, + lat => ( split( ',', $argsRef->{location} ) )[0], + long => ( split( ',', $argsRef->{location} ) )[1], + fetchTime => 0, + forecastFetchTime => 0, }; $self->{cachemaxage} = ( @@ -210,29 +211,66 @@ sub _RetrieveDataFromWU { return 0 unless ( __PACKAGE__ eq caller(0) ); my $self = shift; - - # retrieve data from cache - if ( ( time() - $self->{fetchTime} ) < $self->{cachemaxage} - and $self->{cached}->{lat} == $self->{lat} - and $self->{cached}->{long} == $self->{long} ) - { - return _CallWeatherCallbackFn($self); - } + my $paramRef; + my $options; $self->{cached}->{lat} = $self->{lat} unless ( $self->{cached}->{lat} == $self->{lat} ); $self->{cached}->{long} = $self->{long} unless ( $self->{cached}->{long} == $self->{long} ); - my $paramRef = { - timeout => 15, - self => $self, - callback => ( - $self->{stationId} - ? \&_RetrieveDataFromPWS - : \&_RetrieveDataFinished - ), - }; + # retrieve forecast data from cache + if ( ( time() - $self->{forecastFetchTime} ) < $self->{cachemaxage} + and $self->{cached}->{lat} == $self->{lat} + and $self->{cached}->{long} == $self->{long} ) + { + # old: return _CallWeatherCallbackFn($self); + # Do not just return but get PWS data without forecast + $paramRef = { + timeout => 15, + self => $self, + callback => \&_RetrieveDataFinished, + }; + + #Build station URL + $options = 'stationId=' . $self->{stationId}; + $options .= '&format=json'; + $options .= '&units=' . $self->{units}; + $options .= '&numericPrecision=decimal'; + $options .= '&apiKey=' . $self->{key}; + + $paramRef->{url} = $URL . 'v2/pws/observations/current?' . $options; + } + else { + # Get the complete data station and forecast + $paramRef = { + timeout => 15, + self => $self, + callback => ( + $self->{stationId} + ? \&_RetrieveDataFromPWS + : \&_RetrieveDataFinished + ), + }; + + # Build forecast URL + $options = 'geocode=' . $self->{lat} . ',' . $self->{long}; + $options .= '&format=json'; + $options .= '&units=' . $self->{units}; + $options .= '&language=' + . ( + $self->{lang} eq 'en' + ? 'en-US' + : $self->{lang} . '-' . uc( $self->{lang} ) + ); + $options .= '&apiKey=' . $self->{key}; + + $paramRef->{url} = + $URL + . 'v3/wx/forecast/daily/' + . $self->{days} . 'day' . '?' + . $options; + } if ( $self->{lat} eq 'error' or $self->{long} eq 'error' @@ -250,23 +288,6 @@ sub _RetrieveDataFromWU { if ( $self->{key} eq 'none' ); } else { - my $options = 'geocode=' . $self->{lat} . ',' . $self->{long}; - $options .= '&format=json'; - $options .= '&units=' . $self->{units}; - $options .= '&language=' - . ( - $self->{lang} eq 'en' - ? 'en-US' - : $self->{lang} . '-' . uc( $self->{lang} ) - ); - $options .= '&apiKey=' . $self->{key}; - - $paramRef->{url} = - $URL - . 'v3/wx/forecast/daily/' - . $self->{days} . 'day' . '?' - . $options; - if ( lc( $self->{key} ) eq 'demo' ) { _RetrieveDataFinished( $paramRef, undef, 'DEMODATA' . $DEMODATA ); } @@ -352,10 +373,20 @@ sub _RetrieveDataFinished { $self->{cached}{status} = 'ok'; $self->{cached}{validity} = 'up-to-date'; $self->{fetchTime} = time(); + + #print Dumper $response; ## for debugging + #print Dumper $data; ## for debugging + #if (exists( $response->{daily} )) { + if ( $response =~ /{"daily":/ ) { + $self->{forecastFetchTime} = time(); + } _ProcessingRetrieveData( $self, $response ); } else { $self->{fetchTime} = time() if ( not defined( $self->{fetchTime} ) ); + $self->{forecastFetchTime} = time() + if ( not defined( $self->{forecastFetchTime} ) ); + _ErrorHandling( $self, $err ); _ProcessingRetrieveData( $self, $response ); } @@ -389,12 +420,15 @@ sub _ProcessingRetrieveData { # 'Code: ' . $data->{code} . ' Error: ' . $data->{error} ); # } else { - # print Dumper $response; ## für Debugging - # print Dumper $data; ## für Debugging + # print Dumper $response; ## for debugging + # print Dumper $data; ## for debugging $self->{cached}{current_date_time} = _strftimeWrapper( "%a, %e %b %Y %H:%M", localtime( $self->{fetchTime} ) ); + $self->{cached}{current_forecast_date_time} = + _strftimeWrapper( "%a, %e %b %Y %H:%M", + localtime( $self->{forecastFetchTime} ) ); # $self->{cached}{timezone} = $data->{timezone}; $self->{cached}{license}{text} = @@ -423,34 +457,22 @@ sub _ProcessingRetrieveData { ); $self->{cached}{current} = { - 'dewPoint' => - int( sprintf( "%.1f", $data->{$unit}{dewpt} ) + 0.5 ), - 'heatIndex' => $data->{$unit}{heatIndex}, + 'dewPoint' => sprintf( "%.1f", $data->{$unit}{dewpt} ), + 'heatIndex' => $data->{$unit}{heatIndex}, 'precipRate' => $data->{$unit}{precipRate}, 'precipTotal' => $data->{$unit}{precipTotal}, - 'pressure' => int( - sprintf( "%.1f", $data->{$unit}{pressure} ) + 0.5 - ), + 'pressure' => + sprintf( "%.1f", $data->{$unit}{pressure} ), 'temperature' => - int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ), - 'temp_c' => - int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ), - 'wind_chill' => int( - sprintf( "%.1f", ( $data->{$unit}{windChill} ) ) + - 0.5 - ), - 'windGust' => int( - sprintf( "%.1f", ( $data->{$unit}{windGust} ) ) + - 0.5 - ), - 'wind' => int( - sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) + - 0.5 - ), - 'wind_speed' => int( - sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) + - 0.5 - ), + sprintf( "%.1f", $data->{$unit}{temp} ), + 'temp_c' => sprintf( "%.1f", $data->{$unit}{temp} ), + 'wind_chill' => + sprintf( "%.1f", $data->{$unit}{windChill} ), + 'windGust' => + sprintf( "%.1f", $data->{$unit}{windGust} ), + 'wind' => sprintf( "%.1f", $data->{$unit}{windSpeed} ), + 'wind_speed' => + sprintf( "%.1f", $data->{$unit}{windSpeed} ), 'wind_direction' => $data->{winddir}, 'solarRadiation' => $data->{solarRadiation}, 'uvIndex' => $data->{uv}, @@ -742,7 +764,7 @@ sub _CallWeatherCallbackFn { my $self = shift; - # ## Aufruf der callbackFn + ## Aufruf der callbackFn return FHEM::Core::Weather::RetrieveCallbackFn( $self->{devName} ); } @@ -754,6 +776,9 @@ sub _ErrorHandling { $self->{cached}{current_date_time} = _strftimeWrapper( "%a, %e %b %Y %H:%M", localtime( $self->{fetchTime} ) ); + $self->{cached}{current_forecast_date_time} = + _strftimeWrapper( "%a, %e %b %Y %H:%M", + localtime( $self->{forecastFetchTime} ) ); $self->{cached}{status} = $err; $self->{cached}{validity} = 'stale'; @@ -815,7 +840,7 @@ sub _strftimeWrapper { "abstract": "Wetter API für Weather Underground" } }, - "version": "v1.2.0", + "version": "v1.3.0", "author": [ "Julian Pawlowski " ], diff --git a/fhem/lib/FHEM/Core/Weather.pm b/fhem/lib/FHEM/Core/Weather.pm index 2408121ed..e03998155 100644 --- a/fhem/lib/FHEM/Core/Weather.pm +++ b/fhem/lib/FHEM/Core/Weather.pm @@ -2,12 +2,13 @@ ############################################################################## # # 59_Weather.pm -# (c) 2009-2023 Copyright by Dr. Boris Neubert +# (c) 2009-2024 Copyright by Dr. Boris Neubert # e-mail: omega at online dot de # # Contributors: # - Marko Oldenburg (CoolTux) # - Lippie +# - stefanru (wundergroundAPI) # # # This file is part of fhem.