dev #66
							
								
								
									
										12
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,4 +1,14 @@ | |||||||
| ### feat: new reading owmAPICode for original code (HEAD -> patch-createDecimal) | ### test: add new CHANGELOG (HEAD -> patch-createDecimal) | ||||||
|  | >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 (origin/patch-createDecimal) | ||||||
| >Tue, 11 Jul 2023 14:10:13 +0200 | >Tue, 11 Jul 2023 14:10:13 +0200 | ||||||
|  |  | ||||||
| >Author: Marko Oldenburg (fhemdevelopment@cooltux.net) | >Author: Marko Oldenburg (fhemdevelopment@cooltux.net) | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| UPD 2023-01-29_16:14:48 25809 FHEM/59_Weather.pm | 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_06:52:17 34293 lib/FHEM/Core/Weather.pm | ||||||
| UPD 2023-01-29_16:14:48 50106 lib/FHEM/APIs/Weather/DarkSkyAPI.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-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_06:49:47 37627 lib/FHEM/APIs/Weather/wundergroundAPI.pm | ||||||
|   | |||||||
| @@ -15,9 +15,9 @@ return "$@" if ($@); | |||||||
| return $ret if ($ret); | return $ret if ($ret); | ||||||
| $::packages{wundergroundAPI}{META} = $META; | $::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 | # try to use JSON::MaybeXS wrapper | ||||||
| #   for chance of better performance + open code | #   for chance of better performance + open code | ||||||
| @@ -103,10 +103,11 @@ sub new { | |||||||
|             ? $argsRef->{apikey} |             ? $argsRef->{apikey} | ||||||
|             : 'none' |             : 'none' | ||||||
|         ), |         ), | ||||||
|         lang      => $argsRef->{language}, |         lang              => $argsRef->{language}, | ||||||
|         lat       => ( split( ',', $argsRef->{location} ) )[0], |         lat               => ( split( ',', $argsRef->{location} ) )[0], | ||||||
|         long      => ( split( ',', $argsRef->{location} ) )[1], |         long              => ( split( ',', $argsRef->{location} ) )[1], | ||||||
|         fetchTime => 0, |         fetchTime         => 0, | ||||||
|  |         forecastFetchTime => 0, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     $self->{cachemaxage} = ( |     $self->{cachemaxage} = ( | ||||||
| @@ -210,29 +211,66 @@ sub _RetrieveDataFromWU { | |||||||
|     return 0 unless ( __PACKAGE__ eq caller(0) ); |     return 0 unless ( __PACKAGE__ eq caller(0) ); | ||||||
|  |  | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  |     my $paramRef; | ||||||
|     # retrieve data from cache |     my $options; | ||||||
|     if (    ( time() - $self->{fetchTime} ) < $self->{cachemaxage} |  | ||||||
|         and $self->{cached}->{lat} == $self->{lat} |  | ||||||
|         and $self->{cached}->{long} == $self->{long} ) |  | ||||||
|     { |  | ||||||
|         return _CallWeatherCallbackFn($self); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $self->{cached}->{lat} = $self->{lat} |     $self->{cached}->{lat} = $self->{lat} | ||||||
|       unless ( $self->{cached}->{lat} == $self->{lat} ); |       unless ( $self->{cached}->{lat} == $self->{lat} ); | ||||||
|     $self->{cached}->{long} = $self->{long} |     $self->{cached}->{long} = $self->{long} | ||||||
|       unless ( $self->{cached}->{long} == $self->{long} ); |       unless ( $self->{cached}->{long} == $self->{long} ); | ||||||
|  |  | ||||||
|     my $paramRef = { |     # retrieve forecast data from cache | ||||||
|         timeout  => 15, |     if (    ( time() - $self->{forecastFetchTime} ) < $self->{cachemaxage} | ||||||
|         self     => $self, |         and $self->{cached}->{lat} == $self->{lat} | ||||||
|         callback => ( |         and $self->{cached}->{long} == $self->{long} ) | ||||||
|             $self->{stationId} |     { | ||||||
|             ? \&_RetrieveDataFromPWS |         # old: return _CallWeatherCallbackFn($self); | ||||||
|             : \&_RetrieveDataFinished |         # 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' |     if (   $self->{lat} eq 'error' | ||||||
|         or $self->{long} eq 'error' |         or $self->{long} eq 'error' | ||||||
| @@ -250,23 +288,6 @@ sub _RetrieveDataFromWU { | |||||||
|           if ( $self->{key} eq 'none' ); |           if ( $self->{key} eq 'none' ); | ||||||
|     } |     } | ||||||
|     else { |     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' ) { |         if ( lc( $self->{key} ) eq 'demo' ) { | ||||||
|             _RetrieveDataFinished( $paramRef, undef, 'DEMODATA' . $DEMODATA ); |             _RetrieveDataFinished( $paramRef, undef, 'DEMODATA' . $DEMODATA ); | ||||||
|         } |         } | ||||||
| @@ -352,10 +373,20 @@ sub _RetrieveDataFinished { | |||||||
|         $self->{cached}{status}   = 'ok'; |         $self->{cached}{status}   = 'ok'; | ||||||
|         $self->{cached}{validity} = 'up-to-date'; |         $self->{cached}{validity} = 'up-to-date'; | ||||||
|         $self->{fetchTime}        = time(); |         $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 ); |         _ProcessingRetrieveData( $self, $response ); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         $self->{fetchTime} = time() if ( not defined( $self->{fetchTime} ) ); |         $self->{fetchTime} = time() if ( not defined( $self->{fetchTime} ) ); | ||||||
|  |         $self->{forecastFetchTime} = time() | ||||||
|  |           if ( not defined( $self->{forecastFetchTime} ) ); | ||||||
|  |  | ||||||
|         _ErrorHandling( $self, $err ); |         _ErrorHandling( $self, $err ); | ||||||
|         _ProcessingRetrieveData( $self, $response ); |         _ProcessingRetrieveData( $self, $response ); | ||||||
|     } |     } | ||||||
| @@ -389,12 +420,15 @@ sub _ProcessingRetrieveData { | |||||||
|             #         'Code: ' . $data->{code} . ' Error: ' . $data->{error} ); |             #         'Code: ' . $data->{code} . ' Error: ' . $data->{error} ); | ||||||
|             # } |             # } | ||||||
|             else { |             else { | ||||||
|                 # print Dumper $response;    ## für Debugging |                 # print Dumper $response; ## for debugging | ||||||
|                 # print Dumper $data;    ## für Debugging |                 # print Dumper $data;     ## for debugging | ||||||
|  |  | ||||||
|                 $self->{cached}{current_date_time} = |                 $self->{cached}{current_date_time} = | ||||||
|                   _strftimeWrapper( "%a, %e %b %Y %H:%M", |                   _strftimeWrapper( "%a, %e %b %Y %H:%M", | ||||||
|                     localtime( $self->{fetchTime} ) ); |                     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}{timezone} = $data->{timezone}; | ||||||
|                 $self->{cached}{license}{text} = |                 $self->{cached}{license}{text} = | ||||||
| @@ -423,34 +457,22 @@ sub _ProcessingRetrieveData { | |||||||
|                     ); |                     ); | ||||||
|  |  | ||||||
|                     $self->{cached}{current} = { |                     $self->{cached}{current} = { | ||||||
|                         'dewPoint' => |                         'dewPoint'  => sprintf( "%.1f", $data->{$unit}{dewpt} ), | ||||||
|                           int( sprintf( "%.1f", $data->{$unit}{dewpt} ) + 0.5 ), |                         'heatIndex' => $data->{$unit}{heatIndex}, | ||||||
|                         'heatIndex'   => $data->{$unit}{heatIndex}, |  | ||||||
|                         'precipRate'  => $data->{$unit}{precipRate}, |                         'precipRate'  => $data->{$unit}{precipRate}, | ||||||
|                         'precipTotal' => $data->{$unit}{precipTotal}, |                         'precipTotal' => $data->{$unit}{precipTotal}, | ||||||
|                         'pressure'    => int( |                         'pressure'    => | ||||||
|                             sprintf( "%.1f", $data->{$unit}{pressure} ) + 0.5 |                           sprintf( "%.1f", $data->{$unit}{pressure} ), | ||||||
|                         ), |  | ||||||
|                         'temperature' => |                         'temperature' => | ||||||
|                           int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ), |                           sprintf( "%.1f", $data->{$unit}{temp} ), | ||||||
|                         'temp_c' => |                         'temp_c'     => sprintf( "%.1f", $data->{$unit}{temp} ), | ||||||
|                           int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ), |                         'wind_chill' => | ||||||
|                         'wind_chill' => int( |                           sprintf( "%.1f", $data->{$unit}{windChill} ), | ||||||
|                             sprintf( "%.1f", ( $data->{$unit}{windChill} ) ) + |                         'windGust' => | ||||||
|                               0.5 |                           sprintf( "%.1f", $data->{$unit}{windGust} ), | ||||||
|                         ), |                         'wind' => sprintf( "%.1f", $data->{$unit}{windSpeed} ), | ||||||
|                         'windGust' => int( |                         'wind_speed' => | ||||||
|                             sprintf( "%.1f", ( $data->{$unit}{windGust} ) ) + |                           sprintf( "%.1f", $data->{$unit}{windSpeed} ), | ||||||
|                               0.5 |  | ||||||
|                         ), |  | ||||||
|                         'wind' => int( |  | ||||||
|                             sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) + |  | ||||||
|                               0.5 |  | ||||||
|                         ), |  | ||||||
|                         'wind_speed' => int( |  | ||||||
|                             sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) + |  | ||||||
|                               0.5 |  | ||||||
|                         ), |  | ||||||
|                         'wind_direction' => $data->{winddir}, |                         'wind_direction' => $data->{winddir}, | ||||||
|                         'solarRadiation' => $data->{solarRadiation}, |                         'solarRadiation' => $data->{solarRadiation}, | ||||||
|                         'uvIndex'        => $data->{uv}, |                         'uvIndex'        => $data->{uv}, | ||||||
| @@ -742,7 +764,7 @@ sub _CallWeatherCallbackFn { | |||||||
|  |  | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  |  | ||||||
|     #     ## Aufruf der callbackFn |     ## Aufruf der callbackFn | ||||||
|     return FHEM::Core::Weather::RetrieveCallbackFn( $self->{devName} ); |     return FHEM::Core::Weather::RetrieveCallbackFn( $self->{devName} ); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -754,6 +776,9 @@ sub _ErrorHandling { | |||||||
|  |  | ||||||
|     $self->{cached}{current_date_time} = |     $self->{cached}{current_date_time} = | ||||||
|       _strftimeWrapper( "%a, %e %b %Y %H:%M", localtime( $self->{fetchTime} ) ); |       _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}{status}   = $err; | ||||||
|     $self->{cached}{validity} = 'stale'; |     $self->{cached}{validity} = 'stale'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #       Contributors: | #       Contributors: | ||||||
| #         - Marko Oldenburg (CoolTux) | #         - Marko Oldenburg (CoolTux) | ||||||
| #         - Lippie | #         - Lippie | ||||||
|  | #         - stefanru (wundergroundAPI) | ||||||
| # | # | ||||||
| # | # | ||||||
| #     This file is part of fhem. | #     This file is part of fhem. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user