add daily and hourly support code for WOM, fix bug Readingvalue HASH
This commit is contained in:
		
							
								
								
									
										137
									
								
								59_Weather.pm
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								59_Weather.pm
									
									
									
									
									
								
							| @@ -170,19 +170,19 @@ sub degrees_to_direction($@) { | |||||||
| #     ); | #     ); | ||||||
| #  | #  | ||||||
| #     # this needs to be finalized to use the APIOPTIONS | #     # this needs to be finalized to use the APIOPTIONS | ||||||
| #     my $maxage= $hash->{fhem}{allowCache} ? 600 : 0; # use cached data if allowed | #     my $maxage= $hash->{fhem}->{allowCache} ? 600 : 0; # use cached data if allowed | ||||||
| #     $hash->{fhem}{allowCache}= 1; | #     $hash->{fhem}->{allowCache}= 1; | ||||||
| #     YahooWeatherAPI_RetrieveDataWithCache($maxage, \%args); | #     YahooWeatherAPI_RetrieveDataWithCache($maxage, \%args); | ||||||
| #      | #      | ||||||
| #      | #      | ||||||
| #     $hash->{fhem}{api}->setRetrieveData; | #     $hash->{fhem}->{api}->setRetrieveData; | ||||||
| # } | # } | ||||||
|  |  | ||||||
| sub Weather_ReturnWithError($$) { | sub Weather_ReturnWithError($$) { | ||||||
|     my ($hash, $responseRef)= @_; |     my ($hash, $responseRef)= @_; | ||||||
|     my $name= $hash->{NAME}; |     my $name= $hash->{NAME}; | ||||||
|  |  | ||||||
| #     $hash->{fhem}{allowCache}= 0; # do not use cache on next try | #     $hash->{fhem}->{allowCache}= 0; # do not use cache on next try | ||||||
| #  | #  | ||||||
| #     Log3 $hash, 3, "$name: $err"; | #     Log3 $hash, 3, "$name: $err"; | ||||||
| #     readingsBeginUpdate($hash); | #     readingsBeginUpdate($hash); | ||||||
| @@ -191,13 +191,13 @@ sub Weather_ReturnWithError($$) { | |||||||
| #     readingsBulkUpdate($hash, "pubDateRemote", $pubDate) if(defined($pubDate)); | #     readingsBulkUpdate($hash, "pubDateRemote", $pubDate) if(defined($pubDate)); | ||||||
| #     readingsBulkUpdate($hash, "validity", "stale"); | #     readingsBulkUpdate($hash, "validity", "stale"); | ||||||
| #     readingsEndUpdate($hash, $doTrigger); | #     readingsEndUpdate($hash, $doTrigger); | ||||||
|  |     print 'In der Return with Error Funktion' . "\n"; | ||||||
|  |  | ||||||
|     readingsBeginUpdate($hash); |     readingsBeginUpdate($hash); | ||||||
|     readingsBulkUpdate($hash, 'lastError', $responseRef->{status}); |     readingsBulkUpdate($hash, 'lastError', $responseRef->{status}); | ||||||
|      |      | ||||||
|     foreach my $r (keys %{$responseRef} ) { |     foreach my $r (keys %{$responseRef} ) { | ||||||
|         readingsBulkUpdate($hash, $r, $responseRef->{$r}) if ($r ne 'status'); |         readingsBulkUpdate($hash, $r, $responseRef->{$r}) if ($r ne 'status' or ($r ne 'current' and ref($r) ne 'HASH') ); | ||||||
|     } |     } | ||||||
|     readingsBulkUpdate($hash, 'state', 'API Maintainer: ' . $responseRef->{apiMaintainer} .  ' ErrorMsg: ' . $responseRef->{status}); |     readingsBulkUpdate($hash, 'state', 'API Maintainer: ' . $responseRef->{apiMaintainer} .  ' ErrorMsg: ' . $responseRef->{status}); | ||||||
|     readingsEndUpdate($hash, 1); |     readingsEndUpdate($hash, 1); | ||||||
| @@ -228,7 +228,7 @@ sub Weather_ReturnWithError($$) { | |||||||
| #     my ($pubDateComment, $pubDate, $pubDateTs)= YahooWeatherAPI_pubDate($data); | #     my ($pubDateComment, $pubDate, $pubDateTs)= YahooWeatherAPI_pubDate($data); | ||||||
| #     return Weather_ReturnWithError($hash, $doTrigger, $pubDateComment, $pubDate, $pubDateComment) | #     return Weather_ReturnWithError($hash, $doTrigger, $pubDateComment, $pubDate, $pubDateComment) | ||||||
| #         unless(defined($pubDateTs)); | #         unless(defined($pubDateTs)); | ||||||
| #     my $ts= defined($hash->{READINGS}{pubDateTs}) ? $hash->{READINGS}{pubDateTs}{VAL} : 0; | #     my $ts= defined($hash->{READINGS}->{pubDateTs}) ? $hash->{READINGS}->{pubDateTs}->{VAL} : 0; | ||||||
| #     return Weather_ReturnWithError($hash, $doTrigger, "stale data received", $pubDate, $pubDateComment) | #     return Weather_ReturnWithError($hash, $doTrigger, "stale data received", $pubDate, $pubDateComment) | ||||||
| #         if($ts> $pubDateTs); | #         if($ts> $pubDateTs); | ||||||
| #  | #  | ||||||
| @@ -245,11 +245,11 @@ sub Weather_ReturnWithError($$) { | |||||||
| #     readingsBeginUpdate($hash); | #     readingsBeginUpdate($hash); | ||||||
| #  | #  | ||||||
| #     # delete some unused readings | #     # delete some unused readings | ||||||
| #     delete($hash->{READINGS}{temp_f}) if(defined($hash->{READINGS}{temp_f})); | #     delete($hash->{READINGS}->{temp_f}) if(defined($hash->{READINGS}->{temp_f})); | ||||||
| #     delete($hash->{READINGS}{unit_distance}) if(defined($hash->{READINGS}{unit_distance})); | #     delete($hash->{READINGS}->{unit_distance}) if(defined($hash->{READINGS}->{unit_distance})); | ||||||
| #     delete($hash->{READINGS}{unit_speed}) if(defined($hash->{READINGS}{unit_speed})); | #     delete($hash->{READINGS}->{unit_speed}) if(defined($hash->{READINGS}->{unit_speed})); | ||||||
| #     delete($hash->{READINGS}{unit_pressuree}) if(defined($hash->{READINGS}{unit_pressuree})); | #     delete($hash->{READINGS}->{unit_pressuree}) if(defined($hash->{READINGS}->{unit_pressuree})); | ||||||
| #     delete($hash->{READINGS}{unit_temperature}) if(defined($hash->{READINGS}{unit_temperature})); | #     delete($hash->{READINGS}->{unit_temperature}) if(defined($hash->{READINGS}->{unit_temperature})); | ||||||
| #  | #  | ||||||
| #     # convert to metric units as far as required | #     # convert to metric units as far as required | ||||||
| #     my $isConverted= YahooWeatherAPI_ConvertChannelData($data); | #     my $isConverted= YahooWeatherAPI_ConvertChannelData($data); | ||||||
| @@ -267,42 +267,42 @@ sub Weather_ReturnWithError($$) { | |||||||
| #     readingsBulkUpdate($hash, "description", $data->{description}); | #     readingsBulkUpdate($hash, "description", $data->{description}); | ||||||
| #  | #  | ||||||
| #     # location | #     # location | ||||||
| #     readingsBulkUpdate($hash, "city", $data->{location}{city}); | #     readingsBulkUpdate($hash, "city", $data->{location}->{city}); | ||||||
| #     readingsBulkUpdate($hash, "region", $data->{location}{region}); | #     readingsBulkUpdate($hash, "region", $data->{location}->{region}); | ||||||
| #     readingsBulkUpdate($hash, "country", $data->{location}{country}); | #     readingsBulkUpdate($hash, "country", $data->{location}->{country}); | ||||||
| #     readingsBulkUpdate($hash, "lat", $item->{lat}); | #     readingsBulkUpdate($hash, "lat", $item->{lat}); | ||||||
| #     readingsBulkUpdate($hash, "long", $item->{long}); | #     readingsBulkUpdate($hash, "long", $item->{long}); | ||||||
| #  | #  | ||||||
| #     # wind | #     # wind | ||||||
| #     my $windspeed= int($data->{wind}{speed}+0.5); | #     my $windspeed= int($data->{wind}->{speed}+0.5); | ||||||
| #     readingsBulkUpdate($hash, "wind", $windspeed); | #     readingsBulkUpdate($hash, "wind", $windspeed); | ||||||
| #     readingsBulkUpdate($hash, "wind_speed", $windspeed); | #     readingsBulkUpdate($hash, "wind_speed", $windspeed); | ||||||
| #     readingsBulkUpdate($hash, "wind_chill", $data->{wind}{chill}); | #     readingsBulkUpdate($hash, "wind_chill", $data->{wind}->{chill}); | ||||||
| #     my $winddir= $data->{wind}{direction}; | #     my $winddir= $data->{wind}->{direction}; | ||||||
| #     readingsBulkUpdate($hash, "wind_direction", $winddir); | #     readingsBulkUpdate($hash, "wind_direction", $winddir); | ||||||
| #     my $wdir= degrees_to_direction($winddir, @directions_txt_i18n); | #     my $wdir= degrees_to_direction($winddir, @directions_txt_i18n); | ||||||
| #     readingsBulkUpdate($hash, "wind_condition", "Wind: $wdir $windspeed km/h"); | #     readingsBulkUpdate($hash, "wind_condition", "Wind: $wdir $windspeed km/h"); | ||||||
| #  | #  | ||||||
| #     # atmosphere | #     # atmosphere | ||||||
| #     my $humidity= $data->{atmosphere}{humidity}; | #     my $humidity= $data->{atmosphere}->{humidity}; | ||||||
| #     readingsBulkUpdate($hash, "humidity", $humidity); | #     readingsBulkUpdate($hash, "humidity", $humidity); | ||||||
| #     my $pressure= $data->{atmosphere}{pressure}; | #     my $pressure= $data->{atmosphere}->{pressure}; | ||||||
| #     readingsBulkUpdate($hash, "pressure", $pressure); | #     readingsBulkUpdate($hash, "pressure", $pressure); | ||||||
| #     readingsBulkUpdate($hash, "visibility", int($data->{atmosphere}{visibility}+0.5)); | #     readingsBulkUpdate($hash, "visibility", int($data->{atmosphere}->{visibility}+0.5)); | ||||||
| #     my $pressure_trend= $data->{atmosphere}{rising}; | #     my $pressure_trend= $data->{atmosphere}->{rising}; | ||||||
| #     readingsBulkUpdate($hash, "pressure_trend", $pressure_trend); | #     readingsBulkUpdate($hash, "pressure_trend", $pressure_trend); | ||||||
| #     readingsBulkUpdate($hash, "pressure_trend_txt", $pressure_trend_txt_i18n{$pressure_trend}); | #     readingsBulkUpdate($hash, "pressure_trend_txt", $pressure_trend_txt_i18n{$pressure_trend}); | ||||||
| #     readingsBulkUpdate($hash, "pressure_trend_sym", $pressure_trend_sym{$pressure_trend}); | #     readingsBulkUpdate($hash, "pressure_trend_sym", $pressure_trend_sym{$pressure_trend}); | ||||||
| #  | #  | ||||||
| #     # condition | #     # condition | ||||||
| #     my $date= $item->{condition}{date}; | #     my $date= $item->{condition}->{date}; | ||||||
| #     readingsBulkUpdate($hash, "current_date_time", $date); | #     readingsBulkUpdate($hash, "current_date_time", $date); | ||||||
| #     readingsBulkUpdate($hash, "day_of_week", $wdays_txt_i18n{substr($date,0,3)}); | #     readingsBulkUpdate($hash, "day_of_week", $wdays_txt_i18n{substr($date,0,3)}); | ||||||
| #     my $code= $item->{condition}{code}; | #     my $code= $item->{condition}->{code}; | ||||||
| #     readingsBulkUpdate($hash, "code", $code); | #     readingsBulkUpdate($hash, "code", $code); | ||||||
| #     readingsBulkUpdate($hash, "condition", $YahooCodes_i18n[$code]); | #     readingsBulkUpdate($hash, "condition", $YahooCodes_i18n[$code]); | ||||||
| #     readingsBulkUpdate($hash, "icon",  $iconlist[$code]); | #     readingsBulkUpdate($hash, "icon",  $iconlist[$code]); | ||||||
| #     my $temp= $item->{condition}{temp}; | #     my $temp= $item->{condition}->{temp}; | ||||||
| #     readingsBulkUpdate($hash, "temp_c", $temp); | #     readingsBulkUpdate($hash, "temp_c", $temp); | ||||||
| #     readingsBulkUpdate($hash, "temperature", $temp); | #     readingsBulkUpdate($hash, "temperature", $temp); | ||||||
| #  | #  | ||||||
| @@ -338,7 +338,7 @@ sub Weather_RetrieveCallbackFn($) { | |||||||
|  |  | ||||||
|     my $name = shift; |     my $name = shift; | ||||||
|     my $hash = $defs{$name}; |     my $hash = $defs{$name}; | ||||||
|     my $responseRef = $hash->{fhem}{api}->getWeather; |     my $responseRef = $hash->{fhem}->{api}->getWeather; | ||||||
|      |      | ||||||
|     if ( $responseRef->{status} eq 'ok' ) { |     if ( $responseRef->{status} eq 'ok' ) { | ||||||
|         Weather_WriteReadings($hash,$responseRef); |         Weather_WriteReadings($hash,$responseRef); | ||||||
| @@ -354,51 +354,52 @@ sub Weather_WriteReadings($$) { | |||||||
|     readingsBeginUpdate($hash); |     readingsBeginUpdate($hash); | ||||||
|  |  | ||||||
|     # delete some unused readings |     # delete some unused readings | ||||||
|     delete($hash->{READINGS}{temp_f}) if(defined($hash->{READINGS}{temp_f})); |     delete($hash->{READINGS}->{temp_f}) if(defined($hash->{READINGS}->{temp_f})); | ||||||
|     delete($hash->{READINGS}{unit_distance}) if(defined($hash->{READINGS}{unit_distance})); |     delete($hash->{READINGS}->{unit_distance}) if(defined($hash->{READINGS}->{unit_distance})); | ||||||
|     delete($hash->{READINGS}{unit_speed}) if(defined($hash->{READINGS}{unit_speed})); |     delete($hash->{READINGS}->{unit_speed}) if(defined($hash->{READINGS}->{unit_speed})); | ||||||
|     delete($hash->{READINGS}{unit_pressuree}) if(defined($hash->{READINGS}{unit_pressuree})); |     delete($hash->{READINGS}->{unit_pressuree}) if(defined($hash->{READINGS}->{unit_pressuree})); | ||||||
|     delete($hash->{READINGS}{unit_temperature}) if(defined($hash->{READINGS}{unit_temperature})); |     delete($hash->{READINGS}->{unit_temperature}) if(defined($hash->{READINGS}->{unit_temperature})); | ||||||
|      |      | ||||||
|     # housekeeping information |     # housekeeping information | ||||||
|     readingsBulkUpdate($hash, 'lastError', ''); |     readingsBulkUpdate($hash, 'lastError', ''); | ||||||
|     foreach my $r (keys %{$dataRef} ) {         |     foreach my $r (keys %{$dataRef} ) {         | ||||||
|         readingsBulkUpdate($hash, $r, $dataRef->{$r}) if ($r ne 'status' and $r ne 'current' and $r ne 'forcast'); |         readingsBulkUpdate($hash, $r, $dataRef->{$r}) | ||||||
|  |           if ( ref($dataRef->{$r}) ne 'HASH' ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     readingsBulkUpdate($hash, "validity", "up-to-date"); |     readingsBulkUpdate($hash, "validity", "up-to-date"); | ||||||
|  |  | ||||||
|  |  | ||||||
|     # current |     # current | ||||||
|     if ( ref( $dataRef->{current} ) eq 'HASH' ) { |     if ( defined($dataRef->{current}) and ref( $dataRef->{current} ) eq 'HASH' ) { | ||||||
|         while( my ($r,$v) = each %{$dataRef->{current}} ) { |         while( my ($r,$v) = each %{$dataRef->{current}} ) { | ||||||
|             readingsBulkUpdate($hash, $r, $v); |             readingsBulkUpdate($hash, $r, $v); | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         readingsBulkUpdate($hash, 'icon',  $iconlist[$dataRef->{current}{code}]); |         readingsBulkUpdate($hash, 'icon',  $iconlist[$dataRef->{current}->{code}]); | ||||||
|         if (  defined($dataRef->{current}{wind_direction}) |         if (  defined($dataRef->{current}->{wind_direction}) | ||||||
|         and defined($dataRef->{current}{wind_speed} ) ) |         and defined($dataRef->{current}->{wind_speed} ) ) | ||||||
|         { |         { | ||||||
|             my $wdir= degrees_to_direction($dataRef->{current}{wind_direction}, @directions_txt_i18n); |             my $wdir= degrees_to_direction($dataRef->{current}->{wind_direction}, @directions_txt_i18n); | ||||||
|             readingsBulkUpdate($hash, 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{current}{wind_speed} . ' km/h'); |             readingsBulkUpdate($hash, 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{current}->{wind_speed} . ' km/h'); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     # forecast |     # forecast | ||||||
|     if ( ref( $dataRef->{forcast} ) eq 'HASH' ) { |     if ( defined($dataRef->{forecast}) and ref( $dataRef->{forecast} ) eq 'HASH' ) { | ||||||
|         ## Forcast for hourly |         ## Forecast for hourly | ||||||
|         if (  ref( $dataRef->{forcast}{hourly} ) eq "ARRAY" |         if (  defined($dataRef->{forecast}->{hourly}) and ref( $dataRef->{forecast}->{hourly} ) eq "ARRAY" | ||||||
|         and scalar( @{ $dataRef->{forcast}{daily} } ) > 0 ) |         and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0 ) | ||||||
|         { |         { | ||||||
|          |          | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         ## Forcast for Daily |         ## Forecast for Daily | ||||||
|         if (  ref( $dataRef->{forcast}{daily} ) eq "ARRAY" |         if (  defined($dataRef->{forecast}->{daily}) and ref( $dataRef->{forecast}->{daily} ) eq "ARRAY" | ||||||
|         and scalar( @{ $dataRef->{forcast}{daily} } ) > 0 ) |         and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0 ) | ||||||
|         { |         { | ||||||
|             my $i= 0; |             my $i= 0; | ||||||
|             foreach my $fc (@{$dataRef->{forcast}{daily}}) { |             foreach my $fc (@{$dataRef->{forecast}->{daily}}) { | ||||||
|                 $i++; |                 $i++; | ||||||
|                 my $f= "fc" . $i ."_"; |                 my $f= "fc" . $i ."_"; | ||||||
|                  |                  | ||||||
| @@ -406,22 +407,22 @@ sub Weather_WriteReadings($$) { | |||||||
|                     readingsBulkUpdate($hash, $f.$r, $v); |                     readingsBulkUpdate($hash, $f.$r, $v); | ||||||
|                 } |                 } | ||||||
|         #         readingsBulkUpdate($hash, $f . "day_of_week", $wdays_txt_i18n{$fc->{day}}); |         #         readingsBulkUpdate($hash, $f . "day_of_week", $wdays_txt_i18n{$fc->{day}}); | ||||||
|                 readingsBulkUpdate($hash, $f . 'icon',  $iconlist[$dataRef->{forcast}{daily}[$i-1]{code}]); |                 readingsBulkUpdate($hash, $f . 'icon',  $iconlist[$dataRef->{forecast}->{daily}[$i-1]{code}]); | ||||||
|                 if (  defined($dataRef->{forcast}{daily}[$i-1]{wind_direction}) |                 if (  defined($dataRef->{forecast}->{daily}[$i-1]{wind_direction}) | ||||||
|                 and defined($dataRef->{forcast}{daily}[$i-1]{wind_speed}) ) |                 and defined($dataRef->{forecast}->{daily}[$i-1]{wind_speed}) ) | ||||||
|                 { |                 { | ||||||
|                     my $wdir= degrees_to_direction($dataRef->{forcast}{daily}[$i-1]{wind_direction}, @directions_txt_i18n); |                     my $wdir= degrees_to_direction($dataRef->{forecast}->{daily}[$i-1]{wind_direction}, @directions_txt_i18n); | ||||||
|                     readingsBulkUpdate($hash, $f . 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{forcast}{daily}[$i-1]{wind_speed} . ' km/h'); |                     readingsBulkUpdate($hash, $f . 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{forecast}->{daily}[$i-1]{wind_speed} . ' km/h'); | ||||||
|                 } |                 } | ||||||
|         #         readingsBulkUpdate($hash, $f . 'day_of_week', $wdays_txt_i18n{substr($dataRef->{forcast}[$i-1]{date},0,3)}); |         #         readingsBulkUpdate($hash, $f . 'day_of_week', $wdays_txt_i18n{substr($dataRef->{forecast}[$i-1]{date},0,3)}); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     my $val= 'T:' . $dataRef->{current}{temperature} . '°C' |     my $val= 'T:' . $dataRef->{current}->{temperature} . '°C' | ||||||
|             .' ' . substr($status_items_txt_i18n{1}, 0, 1) . ':' . $dataRef->{current}{humidity} . '%' |             .' ' . substr($status_items_txt_i18n{1}, 0, 1) . ':' . $dataRef->{current}->{humidity} . '%' | ||||||
|             .' ' . substr($status_items_txt_i18n{0}, 0, 1) . ':' . $dataRef->{current}{wind} . 'km/h' |             .' ' . substr($status_items_txt_i18n{0}, 0, 1) . ':' . $dataRef->{current}->{wind} . 'km/h' | ||||||
|             .' P:' . $dataRef->{current}{pressure} . 'mbar'; |             .' P:' . $dataRef->{current}->{pressure} . 'mbar'; | ||||||
|              |              | ||||||
|     Log3 $hash, 4, "$name: $val"; |     Log3 $hash, 4, "$name: $val"; | ||||||
|     readingsBulkUpdate($hash, 'state', $val); |     readingsBulkUpdate($hash, 'state', $val); | ||||||
| @@ -439,7 +440,7 @@ sub Weather_GetUpdate($) { | |||||||
|     my ($hash) = @_; |     my ($hash) = @_; | ||||||
|     my $name = $hash->{NAME}; |     my $name = $hash->{NAME}; | ||||||
|  |  | ||||||
|     if($attr{$name} && $attr{$name}{disable}) { |     if($attr{$name} && $attr{$name}->{disable}) { | ||||||
|       Log3 $hash, 5, "Weather $name: retrieval of weather data is disabled by attribute."; |       Log3 $hash, 5, "Weather $name: retrieval of weather data is disabled by attribute."; | ||||||
|       readingsBeginUpdate($hash); |       readingsBeginUpdate($hash); | ||||||
|       readingsBulkUpdate($hash, "pubDateComment", "disabled by attribute"); |       readingsBulkUpdate($hash, "pubDateComment", "disabled by attribute"); | ||||||
| @@ -448,7 +449,7 @@ sub Weather_GetUpdate($) { | |||||||
|       Weather_RearmTimer($hash, gettimeofday()+$hash->{INTERVAL}); |       Weather_RearmTimer($hash, gettimeofday()+$hash->{INTERVAL}); | ||||||
|     } else { |     } else { | ||||||
| #       Weather_RetrieveData($name, 0); | #       Weather_RetrieveData($name, 0); | ||||||
|       $hash->{fhem}{api}->setRetrieveData; |       $hash->{fhem}->{api}->setRetrieveData; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 1; |     return 1; | ||||||
| @@ -464,8 +465,8 @@ sub Weather_Get($@) { | |||||||
|   my $reading= $a[1]; |   my $reading= $a[1]; | ||||||
|   my $value; |   my $value; | ||||||
|  |  | ||||||
|   if(defined($hash->{READINGS}{$reading})) { |   if(defined($hash->{READINGS}->{$reading})) { | ||||||
|         $value= $hash->{READINGS}{$reading}{VAL}; |         $value= $hash->{READINGS}->{$reading}->{VAL}; | ||||||
|   } else { |   } else { | ||||||
|         my $rt= ""; |         my $rt= ""; | ||||||
|         if(defined($hash->{READINGS})) { |         if(defined($hash->{READINGS})) { | ||||||
| @@ -515,7 +516,7 @@ sub Weather_Notify($$) { | |||||||
|   return if($dev->{NAME} ne "global"); |   return if($dev->{NAME} ne "global"); | ||||||
|   return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}})); |   return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}})); | ||||||
|  |  | ||||||
|   # return if($attr{$name} && $attr{$name}{disable}); |   # return if($attr{$name} && $attr{$name}->{disable}); | ||||||
|  |  | ||||||
|   # update weather after initialization or change of configuration |   # update weather after initialization or change of configuration | ||||||
|   # wait 10 to 29 seconds to avoid congestion due to concurrent activities |   # wait 10 to 29 seconds to avoid congestion due to concurrent activities | ||||||
| @@ -586,7 +587,7 @@ sub Weather_Define($$) { | |||||||
|   return "$name: cannot load API $api: $@" if($@); |   return "$name: cannot load API $api: $@" if($@); | ||||||
|  |  | ||||||
|   $hash->{NOTIFYDEV} = "global"; |   $hash->{NOTIFYDEV} = "global"; | ||||||
|   $hash->{fhem}{interfaces}= "temperature;humidity;wind"; |   $hash->{fhem}->{interfaces}= "temperature;humidity;wind"; | ||||||
|   $hash->{LOCATION}     = ( defined($location) ? $location : AttrVal( 'global', 'latitude',  'error' ).','.AttrVal( 'global', 'longitude', 'error' ) ); |   $hash->{LOCATION}     = ( defined($location) ? $location : AttrVal( 'global', 'latitude',  'error' ).','.AttrVal( 'global', 'longitude', 'error' ) ); | ||||||
|   $hash->{INTERVAL}     = $interval; |   $hash->{INTERVAL}     = $interval; | ||||||
|   $hash->{LANG}         = ( defined($lang) ? $lang : lc(AttrVal('global','language','de')) ); |   $hash->{LANG}         = ( defined($lang) ? $lang : lc(AttrVal('global','language','de')) ); | ||||||
| @@ -594,16 +595,16 @@ sub Weather_Define($$) { | |||||||
|   $hash->{APIKEY}       = $apikey; |   $hash->{APIKEY}       = $apikey; | ||||||
|   $hash->{APIOPTIONS}   = $apioptions; |   $hash->{APIOPTIONS}   = $apioptions; | ||||||
|   #$hash->{UNITS}        = "c"; # hardcoded to use degrees centigrade (Celsius) |   #$hash->{UNITS}        = "c"; # hardcoded to use degrees centigrade (Celsius) | ||||||
|   $hash->{READINGS}{current_date_time}{TIME}= TimeNow(); |   $hash->{READINGS}->{current_date_time}->{TIME}= TimeNow(); | ||||||
|   $hash->{READINGS}{current_date_time}{VAL}= "none"; |   $hash->{READINGS}->{current_date_time}->{VAL}= "none"; | ||||||
|  |  | ||||||
|   $hash->{fhem}{allowCache}= 1; |   $hash->{fhem}->{allowCache}= 1; | ||||||
|    |    | ||||||
|   readingsSingleUpdate($hash,'state','Initialized',1); |   readingsSingleUpdate($hash,'state','Initialized',1); | ||||||
|   Weather_LanguageInitialize($hash->{LANG}); |   Weather_LanguageInitialize($hash->{LANG}); | ||||||
|  |  | ||||||
|   my $apistring = $api . '::Weather'; |   my $apistring = $api . '::Weather'; | ||||||
|   $hash->{fhem}{api} = $apistring->new( { devName => $hash->{NAME}, apikey => $hash->{APIKEY}, location => $hash->{LOCATION}, cachemaxage => 600, language => $hash->{LANG} } ); |   $hash->{fhem}->{api} = $apistring->new( { devName => $hash->{NAME}, apikey => $hash->{APIKEY}, location => $hash->{LOCATION}, cachemaxage => 600, language => $hash->{LANG} } ); | ||||||
|    |    | ||||||
|   Weather_GetUpdate($hash) if($init_done); |   Weather_GetUpdate($hash) if($init_done); | ||||||
|  |  | ||||||
| @@ -650,7 +651,7 @@ WeatherAsHtmlV($;$) | |||||||
|   $d = "<none>" if(!$d); |   $d = "<none>" if(!$d); | ||||||
|   $items = 10 if( !$items ); |   $items = 10 if( !$items ); | ||||||
|   return "$d is not a Weather instance<br>" |   return "$d is not a Weather instance<br>" | ||||||
|         if(!$defs{$d} || $defs{$d}{TYPE} ne "Weather"); |         if(!$defs{$d} || $defs{$d}->{TYPE} ne "Weather"); | ||||||
|  |  | ||||||
|   my $width= int(ICONSCALE*ICONWIDTH); |   my $width= int(ICONSCALE*ICONWIDTH); | ||||||
|  |  | ||||||
| @@ -690,7 +691,7 @@ WeatherAsHtmlH($;$) | |||||||
|   $d = "<none>" if(!$d); |   $d = "<none>" if(!$d); | ||||||
|   $items = 10 if( !$items ); |   $items = 10 if( !$items ); | ||||||
|   return "$d is not a Weather instance<br>" |   return "$d is not a Weather instance<br>" | ||||||
|         if(!$defs{$d} || $defs{$d}{TYPE} ne "Weather"); |         if(!$defs{$d} || $defs{$d}->{TYPE} ne "Weather"); | ||||||
|  |  | ||||||
|   my $width= int(ICONSCALE*ICONWIDTH); |   my $width= int(ICONSCALE*ICONWIDTH); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ sub new { | |||||||
|         fetchTime   => 0, |         fetchTime   => 0, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     $self->{cached} = _CreateForcastRef($self); |     $self->{cached} = _CreateForecastRef($self); | ||||||
|  |  | ||||||
|     bless $self, $class; |     bless $self, $class; | ||||||
|     return $self; |     return $self; | ||||||
| @@ -190,7 +190,7 @@ sub _ProcessingRetrieveData($$) { | |||||||
|             $self->{cached}->{current_date_time} = strftime( |             $self->{cached}->{current_date_time} = strftime( | ||||||
|                 "%a,%e %b %Y %H:%M %p", |                 "%a,%e %b %Y %H:%M %p", | ||||||
|                 localtime( $self->{fetchTime} ) |                 localtime( $self->{fetchTime} ) | ||||||
|               ), |               ); | ||||||
|             $self->{cached}->{timezone} = $data->{timezone}; |             $self->{cached}->{timezone} = $data->{timezone}; | ||||||
|             $self->{cached}->{license} = $data->{flags}->{'meteoalarm-license'}; |             $self->{cached}->{license} = $data->{flags}->{'meteoalarm-license'}; | ||||||
|             $self->{cached}->{current} = { |             $self->{cached}->{current} = { | ||||||
| @@ -229,13 +229,13 @@ sub _ProcessingRetrieveData($$) { | |||||||
|                 'precipIntensity' => $data->{currently}->{precipIntensity}, |                 'precipIntensity' => $data->{currently}->{precipIntensity}, | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             my $i = 0; |  | ||||||
|             if ( ref( $data->{daily}->{data} ) eq "ARRAY" |             if ( ref( $data->{daily}->{data} ) eq "ARRAY" | ||||||
|                 and scalar( @{ $data->{daily}->{data} } ) > 0 ) |                 and scalar( @{ $data->{daily}->{data} } ) > 0 ) | ||||||
|             { |             { | ||||||
|  |                 my $i = 0; | ||||||
|                 foreach ( @{ $data->{daily}->{data} } ) { |                 foreach ( @{ $data->{daily}->{data} } ) { | ||||||
|                     push( |                     push( | ||||||
|                         @{ $self->{cached}->{forcast}->{daily} }, |                         @{ $self->{cached}->{forecast}->{daily} }, | ||||||
|                         { |                         { | ||||||
|                             'date' => strftime( |                             'date' => strftime( | ||||||
|                                 "%a, %d.%m.%Y", |                                 "%a, %d.%m.%Y", | ||||||
| @@ -449,10 +449,10 @@ sub _ErrorHandling($$) { | |||||||
|     $self->{cached}->{validity} = 'stale'; |     $self->{cached}->{validity} = 'stale'; | ||||||
| } | } | ||||||
|  |  | ||||||
| sub _CreateForcastRef($) { | sub _CreateForecastRef($) { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  |  | ||||||
|     my $forcastRef = ( |     my $forecastRef = ( | ||||||
|         { |         { | ||||||
|             lat  => $self->{lat}, |             lat  => $self->{lat}, | ||||||
|             long => $self->{long}, |             long => $self->{long}, | ||||||
| @@ -461,7 +461,7 @@ sub _CreateForcastRef($) { | |||||||
|         } |         } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     return $forcastRef; |     return $forecastRef; | ||||||
| } | } | ||||||
|  |  | ||||||
| ############################################################################## | ############################################################################## | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ | |||||||
|  |  | ||||||
| ### Beispielaufruf | ### Beispielaufruf | ||||||
| # https://api.openweathermap.org/data/2.5/weather?lat=[lat]&lon=[long]&APPID=[API]   Current | # https://api.openweathermap.org/data/2.5/weather?lat=[lat]&lon=[long]&APPID=[API]   Current | ||||||
| # https://api.openweathermap.org/data/2.5/forcast?lat=[lat]&lon=[long]&APPID=[API]   Forcast | # https://api.openweathermap.org/data/2.5/forecast?lat=[lat]&lon=[long]&APPID=[API]   Forecast | ||||||
| # https://openweathermap.org/weather-conditions     Icons und Conditions ID's | # https://openweathermap.org/weather-conditions     Icons und Conditions ID's | ||||||
|  |  | ||||||
| package OpenWeatherMapAPI::Weather; | package OpenWeatherMapAPI::Weather; | ||||||
| @@ -50,7 +50,7 @@ use Data::Dumper;    # for Debug only | |||||||
| ## API URL | ## API URL | ||||||
| use constant URL => 'https://api.openweathermap.org/data/2.5/'; | use constant URL => 'https://api.openweathermap.org/data/2.5/'; | ||||||
| ## URL . 'weather?' for current data | ## URL . 'weather?' for current data | ||||||
| ## URL . 'forcast?' for forcast data | ## URL . 'forecast?' for forecast data | ||||||
|  |  | ||||||
| my %codes = ( | my %codes = ( | ||||||
|     200 => 45, |     200 => 45, | ||||||
| @@ -124,7 +124,7 @@ sub new { | |||||||
|         endpoint    => 'none', |         endpoint    => 'none', | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     $self->{cached} = _CreateForcastRef($self); |     $self->{cached} = _CreateForecastRef($self); | ||||||
|  |  | ||||||
|     bless $self, $class; |     bless $self, $class; | ||||||
|     return $self; |     return $self; | ||||||
| @@ -160,14 +160,17 @@ sub _RetrieveDataFromOpenWeatherMap($) { | |||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  |  | ||||||
|     # retrieve data from cache |     # retrieve data from cache | ||||||
|     if ( ( time() - $self->{fetchTime} ) < $self->{cachemaxage} ) { |     if( $self->{endpoint} eq 'none' ) { | ||||||
|  |         if ( ( time() - $self->{fetchTime} ) < $self->{cachemaxage} ) | ||||||
|  |         { | ||||||
|             return _CallWeatherCallbackFn($self); |             return _CallWeatherCallbackFn($self); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     my $paramRef = { |     my $paramRef = { | ||||||
|         timeout  => 15, |         timeout  => 15, | ||||||
|         self     => $self, |         self     => $self, | ||||||
|         endpoint => ( $self->{endpoint} eq 'none' ? 'weather' : 'forcast' ), |         endpoint => ( $self->{endpoint} eq 'none' ? 'weather' : 'forecast' ), | ||||||
|         callback => \&_RetrieveDataFinished, |         callback => \&_RetrieveDataFinished, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -221,8 +224,6 @@ sub _RetrieveDataFinished($$$) { | |||||||
|         _ErrorHandling( $self, $err ); |         _ErrorHandling( $self, $err ); | ||||||
|         _ProcessingRetrieveData( $self, $response ); |         _ProcessingRetrieveData( $self, $response ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $self->{endpoint} = $paramRef->{endpoint}; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| sub _ProcessingRetrieveData($$) { | sub _ProcessingRetrieveData($$) { | ||||||
| @@ -231,24 +232,22 @@ sub _ProcessingRetrieveData($$) { | |||||||
|     if ( $self->{cached}->{status} eq 'ok' and defined($response) ) { |     if ( $self->{cached}->{status} eq 'ok' and defined($response) ) { | ||||||
|         my $data = eval { decode_json($response) }; |         my $data = eval { decode_json($response) }; | ||||||
|  |  | ||||||
| #         print 'Dumper1: ' . Dumper $data; |  | ||||||
|  |  | ||||||
|         if ($@) { |         if ($@) { | ||||||
|             _ErrorHandling( $self, |             _ErrorHandling( $self, | ||||||
|                 'OpenWeatherMap Weather decode JSON err ' . $@ ); |                 'OpenWeatherMap Weather decode JSON err ' . $@ ); | ||||||
|         } |         } | ||||||
|         elsif ( defined( $data->{cod} ) and defined( $data->{message} ) ) { |         elsif ( defined( $data->{cod} ) and $data->{cod} != 200 and defined( $data->{message} ) ) { | ||||||
| #             print 'Dumper2: ' . Dumper $data; |  | ||||||
|             _ErrorHandling( $self, $data->{cod} . ': ' . $data->{message} ); |             _ErrorHandling( $self, $data->{cod} . ': ' . $data->{message} ); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| #             print Dumper $data;       ## für Debugging |  | ||||||
|             return if ( $self->{endpoint} eq 'forcast' ); |  | ||||||
|  |  | ||||||
|  |         ###### Ab hier wird die ResponseHash Referenze für die Rückgabe zusammen gestellt | ||||||
|             $self->{cached}->{current_date_time} = strftime( |             $self->{cached}->{current_date_time} = strftime( | ||||||
|                 "%a,%e %b %Y %H:%M %p", |                 "%a,%e %b %Y %H:%M %p", | ||||||
|                 localtime( $self->{fetchTime} ) |                 localtime( $self->{fetchTime} ) | ||||||
|               ), |             ); | ||||||
|  |              | ||||||
|  |             if ( $self->{endpoint} eq 'weather' ) { | ||||||
|                 $self->{cached}->{country} = $data->{sys}->{country}; |                 $self->{cached}->{country} = $data->{sys}->{country}; | ||||||
|                 $self->{cached}->{city}    = $data->{name}; |                 $self->{cached}->{city}    = $data->{name}; | ||||||
|                 $self->{cached}->{current} = { |                 $self->{cached}->{current} = { | ||||||
| @@ -295,21 +294,74 @@ sub _ProcessingRetrieveData($$) { | |||||||
|                     ), |                     ), | ||||||
|                     'pubDate' => |                     'pubDate' => | ||||||
|                     strftime( "%a,%e %b %Y %H:%M %p", localtime( $data->{dt} ) ), |                     strftime( "%a,%e %b %Y %H:%M %p", localtime( $data->{dt} ) ), | ||||||
|  |                 }; | ||||||
|             } |             } | ||||||
|               if ( $self->{endpoint} eq 'weather' ); |  | ||||||
|  |             if ( $self->{endpoint} eq 'forecas' ) { | ||||||
|  |                 my $i = 0; | ||||||
|  |                 if ( ref( $data->{list} ) eq "ARRAY" | ||||||
|  |                     and scalar( @{ $data->{list} } ) > 0 ) | ||||||
|  |                 { | ||||||
|  |                     foreach ( @{ $data->{list} } ) { | ||||||
|  |                         push( | ||||||
|  |                             @{ $self->{cached}->{forecast}->{daily} }, | ||||||
|  |                             { | ||||||
|  |                                 'temperature' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp} - 273.15 ) ) + 0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'temp_c' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp} - 273.15 ) ) + 0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'low_c' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp_min} - 273.15 ) ) + | ||||||
|  |                                     0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'high_c' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp_max} - 273.15 ) ) + | ||||||
|  |                                     0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'tempLow' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp_min} - 273.15 ) ) + | ||||||
|  |                                     0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'tempHigh' => int( | ||||||
|  |                                     sprintf( "%.1f", ( $data->{list}[$i]{main}->{temp_max} - 273.15 ) ) + | ||||||
|  |                                     0.5 | ||||||
|  |                                 ), | ||||||
|  |                                 'humidity'   => $data->{list}[$i]{main}->{humidity}, | ||||||
|  |                                 'condition'  => encode_utf8( $data->{list}[$i]{weather}[0]{description} ), | ||||||
|  |                                 'pressure'   => $data->{list}[$i]{main}->{pressure}, | ||||||
|  |                                 'wind'       => $data->{list}[$i]{wind}->{speed}, | ||||||
|  |                                 'wind_speed' => $data->{list}[$i]{wind}->{speed}, | ||||||
|  |                                  | ||||||
|  |                                 'cloudCover'     => $data->{list}[$i]{clouds}->{all}, | ||||||
|  |                                 'visibility'     => $data->{visibility}, | ||||||
|  |                                 'code'           => $codes{ $data->{list}[$i]{weather}[0]{id} }, | ||||||
|  |                                 'iconAPI'    => $data->{list}[$i]{weather}[0]{icon}, | ||||||
|  |                                  | ||||||
|  |                                 'pubDate' => | ||||||
|  |                                 strftime( "%a,%e %b %Y %H:%M %p", localtime( $data->{list}[$i]{dt} ) ), | ||||||
|  |                             } | ||||||
|  |                         ); | ||||||
|  |                          | ||||||
|  |                         $i++; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     $self->{endpoint} = 'none' if ( $self->{endpoint} eq 'forecast' ); | ||||||
|  |  | ||||||
|     _RetrieveDataFromOpenWeatherMap($self) |     _RetrieveDataFromOpenWeatherMap($self) | ||||||
|       if ( $self->{endpoint} eq 'weather' ); |       if ( $self->{endpoint} eq 'weather' ); | ||||||
|     $self->{endpoint} = 'none' if ( $self->{endpoint} eq 'forcast' ); |  | ||||||
|  |  | ||||||
|     _CallWeatherCallbackFn($self); |     _CallWeatherCallbackFn($self) if ( $self->{endpoint} eq 'none' ); | ||||||
| } | } | ||||||
|  |  | ||||||
| sub _CallWeatherCallbackFn($) { | sub _CallWeatherCallbackFn($) { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  | #     print 'Dumperausgabe: ' . Dumper $self; | ||||||
|     ### Aufruf der callbackFn |     ### Aufruf der callbackFn | ||||||
|     main::Weather_RetrieveCallbackFn( $self->{devName} ); |     main::Weather_RetrieveCallbackFn( $self->{devName} ); | ||||||
| } | } | ||||||
| @@ -323,10 +375,10 @@ sub _ErrorHandling($$) { | |||||||
|     $self->{cached}->{validity} = 'stale'; |     $self->{cached}->{validity} = 'stale'; | ||||||
| } | } | ||||||
|  |  | ||||||
| sub _CreateForcastRef($) { | sub _CreateForecastRef($) { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  |  | ||||||
|     my $forcastRef = ( |     my $forecastRef = ( | ||||||
|         { |         { | ||||||
|             lat  => $self->{lat}, |             lat  => $self->{lat}, | ||||||
|             long => $self->{long}, |             long => $self->{long}, | ||||||
| @@ -335,7 +387,7 @@ sub _CreateForcastRef($) { | |||||||
|         } |         } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     return $forcastRef; |     return $forecastRef; | ||||||
| } | } | ||||||
|  |  | ||||||
| ############################################################################## | ############################################################################## | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user