diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cacf2e..59e3d91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,46 @@ -### feat: new reading owmAPICode for original code (HEAD -> patch-createDecimal) +### docs: change versions and add copyright (HEAD -> patch-fixforecast) +>Fri, 11 Oct 2024 12:04:07 +0200 + +>Author: Marko Oldenburg (fhemdevelopment@cooltux.net) + +>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net) + + + + +### docs: Changelog (origin/patch-fixforecast) +>Fri, 11 Oct 2024 07:07:57 +0200 + +>Author: Marko Oldenburg (fhemdevelopment@cooltux.net) + +>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net) + +[Ticket: no] + + + +### fix: Update forecast with cachemaxage after API calls are down. special thanks to stefanru (forum) +>Fri, 11 Oct 2024 06:59:53 +0200 + +>Author: Marko Oldenburg (fhemdevelopment@cooltux.net) + +>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net) + +[Ticket: no] + + + +### test: add new CHANGELOG +>Sat, 21 Oct 2023 08:59:11 +0200 + +>Author: Marko Oldenburg (fhemdevelopment@cooltux.net) + +>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net) + + + + +### feat: new reading owmAPICode for original code >Tue, 11 Jul 2023 14:10:13 +0200 >Author: Marko Oldenburg (fhemdevelopment@cooltux.net) diff --git a/FHEM/59_Weather.pm b/FHEM/59_Weather.pm index b6ca7c5..a7af721 100755 --- a/FHEM/59_Weather.pm +++ b/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/controls_Weather.txt b/controls_Weather.txt index f54136f..74f16bc 100644 --- a/controls_Weather.txt +++ b/controls_Weather.txt @@ -1,5 +1,5 @@ -UPD 2023-01-29_16:14:48 25809 FHEM/59_Weather.pm -UPD 2023-06-06_07:31:00 34254 lib/FHEM/Core/Weather.pm +UPD 2024-10-11_12:02:22 25848 FHEM/59_Weather.pm +UPD 2024-10-11_11:59:21 34293 lib/FHEM/Core/Weather.pm UPD 2023-01-29_16:14:48 50106 lib/FHEM/APIs/Weather/DarkSkyAPI.pm UPD 2023-07-11_14:08:00 33779 lib/FHEM/APIs/Weather/OpenWeatherMapAPI.pm -UPD 2023-06-02_05:03:58 36607 lib/FHEM/APIs/Weather/wundergroundAPI.pm +UPD 2024-10-11_12:02:42 37627 lib/FHEM/APIs/Weather/wundergroundAPI.pm diff --git a/lib/FHEM/APIs/Weather/wundergroundAPI.pm b/lib/FHEM/APIs/Weather/wundergroundAPI.pm index 32a23cd..5e51e42 100644 --- a/lib/FHEM/APIs/Weather/wundergroundAPI.pm +++ b/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/lib/FHEM/Core/Weather.pm b/lib/FHEM/Core/Weather.pm index 2408121..e039981 100644 --- a/lib/FHEM/Core/Weather.pm +++ b/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.