diff --git a/59_Weather.pm b/59_Weather.pm index 79d536a..aa004bc 100755 --- a/59_Weather.pm +++ b/59_Weather.pm @@ -22,7 +22,6 @@ # ############################################################################## - package main; use strict; @@ -34,33 +33,138 @@ use vars qw($FW_ss); # use Data::Dumper; # for Debug only my %pressure_trend_txt_en = ( 0 => "steady", 1 => "rising", 2 => "falling" ); -my %pressure_trend_txt_de = ( 0 => "gleichbleibend", 1 => "steigend", 2 => "fallend" ); +my %pressure_trend_txt_de = + ( 0 => "gleichbleibend", 1 => "steigend", 2 => "fallend" ); my %pressure_trend_txt_nl = ( 0 => "stabiel", 1 => "stijgend", 2 => "dalend" ); -my %pressure_trend_txt_fr = ( 0 => "stable", 1 => "croissant", 2 => "décroissant" ); +my %pressure_trend_txt_fr = + ( 0 => "stable", 1 => "croissant", 2 => "décroissant" ); my %pressure_trend_txt_pl = ( 0 => "stabilne", 1 => "rośnie", 2 => "spada" ); -my %pressure_trend_txt_it = ( 0 => "stabile", 1 => "in aumento", 2 => "in diminuzione" ); +my %pressure_trend_txt_it = + ( 0 => "stabile", 1 => "in aumento", 2 => "in diminuzione" ); my %pressure_trend_sym = ( 0 => "=", 1 => "+", 2 => "-" ); -my @directions_txt_en = ('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'); -my @directions_txt_de = ('N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'); -my @directions_txt_nl = ('N', 'NNO', 'NO', 'ONO', 'O', 'OZO', 'ZO', 'ZZO', 'Z', 'ZZW', 'ZW', 'WZW', 'W', 'WNW', 'NW', 'NNW'); -my @directions_txt_fr = ('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSO', 'SO', 'OSO', 'O', 'ONO', 'NO', 'NNO'); -my @directions_txt_pl = ('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'); -my @directions_txt_it = ('N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSO', 'SO', 'OSO', 'O', 'ONO', 'NO', 'NNO'); +my @directions_txt_en = ( + 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', + 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW' +); +my @directions_txt_de = ( + 'N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', + 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW' +); +my @directions_txt_nl = ( + 'N', 'NNO', 'NO', 'ONO', 'O', 'OZO', 'ZO', 'ZZO', + 'Z', 'ZZW', 'ZW', 'WZW', 'W', 'WNW', 'NW', 'NNW' +); +my @directions_txt_fr = ( + 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', + 'S', 'SSO', 'SO', 'OSO', 'O', 'ONO', 'NO', 'NNO' +); +my @directions_txt_pl = ( + 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', + 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW' +); +my @directions_txt_it = ( + 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', + 'S', 'SSO', 'SO', 'OSO', 'O', 'ONO', 'NO', 'NNO' +); -my %wdays_txt_en = ('Mon' => 'Mon', 'Tue' => 'Tue', 'Wed'=> 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun'); -my %wdays_txt_de = ('Mon' => 'Mo', 'Tue' => 'Di', 'Wed'=> 'Mi', 'Thu' => 'Do', 'Fri' => 'Fr', 'Sat' => 'Sa', 'Sun' => 'So'); -my %wdays_txt_nl = ('Mon' => 'Maa', 'Tue' => 'Din', 'Wed'=> 'Woe', 'Thu' => 'Don', 'Fri' => 'Vri', 'Sat' => 'Zat', 'Sun' => 'Zon'); -my %wdays_txt_fr= ('Mon' => 'Lun', 'Tue' => 'Mar', 'Wed'=> 'Mer', 'Thu' => 'Jeu', 'Fri' => 'Ven', 'Sat' => 'Sam', 'Sun' => 'Dim'); -my %wdays_txt_pl = ('Mon' => 'Pon', 'Tue' => 'Wt', 'Wed'=> 'Śr', 'Thu' => 'Czw', 'Fri' => 'Pt', 'Sat' => 'Sob', 'Sun' => 'Nie'); -my %wdays_txt_it = ('Mon' => 'Lun', 'Tue' => 'Mar', 'Wed'=> 'Mer', 'Thu' => 'Gio', 'Fri' => 'Ven', 'Sat' => 'Sab', 'Sun' => 'Dom'); +my %wdays_txt_en = ( + 'Mon' => 'Mon', + 'Tue' => 'Tue', + 'Wed' => 'Wed', + 'Thu' => 'Thu', + 'Fri' => 'Fri', + 'Sat' => 'Sat', + 'Sun' => 'Sun' +); +my %wdays_txt_de = ( + 'Mon' => 'Mo', + 'Tue' => 'Di', + 'Wed' => 'Mi', + 'Thu' => 'Do', + 'Fri' => 'Fr', + 'Sat' => 'Sa', + 'Sun' => 'So' +); +my %wdays_txt_nl = ( + 'Mon' => 'Maa', + 'Tue' => 'Din', + 'Wed' => 'Woe', + 'Thu' => 'Don', + 'Fri' => 'Vri', + 'Sat' => 'Zat', + 'Sun' => 'Zon' +); +my %wdays_txt_fr = ( + 'Mon' => 'Lun', + 'Tue' => 'Mar', + 'Wed' => 'Mer', + 'Thu' => 'Jeu', + 'Fri' => 'Ven', + 'Sat' => 'Sam', + 'Sun' => 'Dim' +); +my %wdays_txt_pl = ( + 'Mon' => 'Pon', + 'Tue' => 'Wt', + 'Wed' => 'Śr', + 'Thu' => 'Czw', + 'Fri' => 'Pt', + 'Sat' => 'Sob', + 'Sun' => 'Nie' +); +my %wdays_txt_it = ( + 'Mon' => 'Lun', + 'Tue' => 'Mar', + 'Wed' => 'Mer', + 'Thu' => 'Gio', + 'Fri' => 'Ven', + 'Sat' => 'Sab', + 'Sun' => 'Dom' +); -my %status_items_txt_en = ( 0 => "Wind", 1 => "Humidity", 2 => "Temperature", 3 => "Right Now", 4 => "Weather forecast for " ); -my %status_items_txt_de = ( 0 => "Wind", 1 => "Feuchtigkeit", 2 => "Temperatur", 3 => "Jetzt Sofort", 4 => "Wettervorhersage für " ); -my %status_items_txt_nl = ( 0 => "Wind", 1 => "Vochtigheid", 2 => "Temperatuur", 3 => "Direct", 4 => "Weersvoorspelling voor " ); -my %status_items_txt_fr = ( 0 => "Vent", 1 => "Humidité", 2 => "Température", 3 => "Maintenant", 4 => "Prévisions météo pour " ); -my %status_items_txt_pl = ( 0 => "Wiatr", 1 => "Wilgotność", 2 => "Temperatura", 3 => "Teraz", 4 => "Prognoza pogody w " ); -my %status_items_txt_it = ( 0 => "Vento", 1 => "Umidità", 2 => "Temperatura", 3 => "Adesso", 4 => "Previsioni del tempo per " ); +my %status_items_txt_en = ( + 0 => "Wind", + 1 => "Humidity", + 2 => "Temperature", + 3 => "Right Now", + 4 => "Weather forecast for " +); +my %status_items_txt_de = ( + 0 => "Wind", + 1 => "Feuchtigkeit", + 2 => "Temperatur", + 3 => "Jetzt Sofort", + 4 => "Wettervorhersage für " +); +my %status_items_txt_nl = ( + 0 => "Wind", + 1 => "Vochtigheid", + 2 => "Temperatuur", + 3 => "Direct", + 4 => "Weersvoorspelling voor " +); +my %status_items_txt_fr = ( + 0 => "Vent", + 1 => "Humidité", + 2 => "Température", + 3 => "Maintenant", + 4 => "Prévisions météo pour " +); +my %status_items_txt_pl = ( + 0 => "Wiatr", + 1 => "Wilgotność", + 2 => "Temperatura", + 3 => "Teraz", + 4 => "Prognoza pogody w " +); +my %status_items_txt_it = ( + 0 => "Vento", + 1 => "Umidità", + 2 => "Temperatura", + 3 => "Adesso", + 4 => "Previsioni del tempo per " +); my %wdays_txt_i18n; my @directions_txt_i18n; @@ -68,79 +172,101 @@ my %pressure_trend_txt_i18n; my %status_items_txt_i18n; my @iconlist = ( - 'storm', 'storm', 'storm', 'thunderstorm', 'thunderstorm', 'rainsnow', - 'sleet', 'snow', 'drizzle', 'drizzle', 'icy' ,'chance_of_rain', - 'chance_of_rain', 'snowflurries', 'chance_of_snow', 'heavysnow', 'snow', 'sleet', - 'sleet', 'dust', 'fog', 'haze', 'smoke', 'flurries', - 'windy', 'icy', 'cloudy', 'mostlycloudy_night', 'mostlycloudy', 'partly_cloudy_night', - 'partly_cloudy', 'sunny', 'sunny', 'mostly_clear_night', 'mostly_sunny', 'heavyrain', - 'sunny', 'scatteredthunderstorms', 'scatteredthunderstorms', 'scatteredthunderstorms', 'scatteredshowers', 'heavysnow', - 'chance_of_snow', 'heavysnow', 'partly_cloudy', 'heavyrain', 'chance_of_snow', 'scatteredshowers'); + 'storm', 'storm', + 'storm', 'thunderstorm', + 'thunderstorm', 'rainsnow', + 'sleet', 'snow', + 'drizzle', 'drizzle', + 'icy', 'chance_of_rain', + 'chance_of_rain', 'snowflurries', + 'chance_of_snow', 'heavysnow', + 'snow', 'sleet', + 'sleet', 'dust', + 'fog', 'haze', + 'smoke', 'flurries', + 'windy', 'icy', + 'cloudy', 'mostlycloudy_night', + 'mostlycloudy', 'partly_cloudy_night', + 'partly_cloudy', 'sunny', + 'sunny', 'mostly_clear_night', + 'mostly_sunny', 'heavyrain', + 'sunny', 'scatteredthunderstorms', + 'scatteredthunderstorms', 'scatteredthunderstorms', + 'scatteredshowers', 'heavysnow', + 'chance_of_snow', 'heavysnow', + 'partly_cloudy', 'heavyrain', + 'chance_of_snow', 'scatteredshowers' +); ################################### sub Weather_LanguageInitialize($) { my ($lang) = @_; - if($lang eq "de") { - %wdays_txt_i18n= %wdays_txt_de; - @directions_txt_i18n= @directions_txt_de; - %pressure_trend_txt_i18n= %pressure_trend_txt_de; - %status_items_txt_i18n= %status_items_txt_de; - } elsif($lang eq "nl") { - %wdays_txt_i18n= %wdays_txt_nl; - @directions_txt_i18n= @directions_txt_nl; - %pressure_trend_txt_i18n= %pressure_trend_txt_nl; - %status_items_txt_i18n= %status_items_txt_nl; - } elsif($lang eq "fr") { - %wdays_txt_i18n= %wdays_txt_fr; - @directions_txt_i18n= @directions_txt_fr; - %pressure_trend_txt_i18n= %pressure_trend_txt_fr; - %status_items_txt_i18n= %status_items_txt_fr; - } elsif($lang eq "pl") { - %wdays_txt_i18n= %wdays_txt_pl; - @directions_txt_i18n= @directions_txt_pl; - %pressure_trend_txt_i18n= %pressure_trend_txt_pl; - %status_items_txt_i18n= %status_items_txt_pl; - } elsif($lang eq "it") { - %wdays_txt_i18n= %wdays_txt_it; - @directions_txt_i18n= @directions_txt_it; - %pressure_trend_txt_i18n= %pressure_trend_txt_it; - %status_items_txt_i18n= %status_items_txt_it; - } else { - %wdays_txt_i18n= %wdays_txt_en; - @directions_txt_i18n= @directions_txt_en; - %pressure_trend_txt_i18n= %pressure_trend_txt_en; - %status_items_txt_i18n= %status_items_txt_en; + if ( $lang eq "de" ) { + %wdays_txt_i18n = %wdays_txt_de; + @directions_txt_i18n = @directions_txt_de; + %pressure_trend_txt_i18n = %pressure_trend_txt_de; + %status_items_txt_i18n = %status_items_txt_de; + } + elsif ( $lang eq "nl" ) { + %wdays_txt_i18n = %wdays_txt_nl; + @directions_txt_i18n = @directions_txt_nl; + %pressure_trend_txt_i18n = %pressure_trend_txt_nl; + %status_items_txt_i18n = %status_items_txt_nl; + } + elsif ( $lang eq "fr" ) { + %wdays_txt_i18n = %wdays_txt_fr; + @directions_txt_i18n = @directions_txt_fr; + %pressure_trend_txt_i18n = %pressure_trend_txt_fr; + %status_items_txt_i18n = %status_items_txt_fr; + } + elsif ( $lang eq "pl" ) { + %wdays_txt_i18n = %wdays_txt_pl; + @directions_txt_i18n = @directions_txt_pl; + %pressure_trend_txt_i18n = %pressure_trend_txt_pl; + %status_items_txt_i18n = %status_items_txt_pl; + } + elsif ( $lang eq "it" ) { + %wdays_txt_i18n = %wdays_txt_it; + @directions_txt_i18n = @directions_txt_it; + %pressure_trend_txt_i18n = %pressure_trend_txt_it; + %status_items_txt_i18n = %status_items_txt_it; + } + else { + %wdays_txt_i18n = %wdays_txt_en; + @directions_txt_i18n = @directions_txt_en; + %pressure_trend_txt_i18n = %pressure_trend_txt_en; + %status_items_txt_i18n = %status_items_txt_en; } } ################################### sub Weather_DebugCodes($) { - my ($lang)= @_; - my @YahooCodes_i18n= YahooWeatherAPI_getYahooCodes($lang); + my ($lang) = @_; + my @YahooCodes_i18n = YahooWeatherAPI_getYahooCodes($lang); Debug "Weather Code List, see http://developer.yahoo.com/weather/#codes"; - for(my $c= 0; $c<= 47; $c++) { - Debug sprintf("%2d %30s %30s", $c, $iconlist[$c], $YahooCodes_i18n[$c]); + for ( my $c = 0 ; $c <= 47 ; $c++ ) { + Debug + sprintf( "%2d %30s %30s", $c, $iconlist[$c], $YahooCodes_i18n[$c] ); } } - ##################################### sub Weather_Initialize($) { my ($hash) = @_; - $hash->{DefFn} = 'Weather_Define'; - $hash->{UndefFn} = 'Weather_Undef'; - $hash->{GetFn} = 'Weather_Get'; - $hash->{SetFn} = 'Weather_Set'; - $hash->{AttrList} = - 'disable:0,1 ' - . 'forecast:hourly,daily,every,off ' - . 'forecastLimit ' - . $readingFnAttributes; - $hash->{NotifyFn}= 'Weather_Notify'; + $hash->{DefFn} = 'Weather_Define'; + $hash->{UndefFn} = 'Weather_Undef'; + $hash->{GetFn} = 'Weather_Get'; + $hash->{SetFn} = 'Weather_Set'; + $hash->{AttrList} = + 'disable:0,1 ' + . 'forecast:hourly,daily,every,off ' + . 'forecastLimit ' + . $readingFnAttributes; + $hash->{NotifyFn} = 'Weather_Notify'; #Weather_DebugCodes('de'); } @@ -148,166 +274,232 @@ sub Weather_Initialize($) { ################################### sub degrees_to_direction($@) { - my ($degrees,@directions_txt_i18n) = @_; - my $mod = int((($degrees + 11.25) % 360) / 22.5); + my ( $degrees, @directions_txt_i18n ) = @_; + my $mod = int( ( ( $degrees + 11.25 ) % 360 ) / 22.5 ); return $directions_txt_i18n[$mod]; } - sub Weather_ReturnWithError($$) { - my ($hash, $responseRef)= @_; - my $name= $hash->{NAME}; + my ( $hash, $responseRef ) = @_; + my $name = $hash->{NAME}; readingsBeginUpdate($hash); - readingsBulkUpdate($hash, 'lastError', $responseRef->{status}); + readingsBulkUpdate( $hash, 'lastError', $responseRef->{status} ); - foreach my $r (keys %{$responseRef} ) { - readingsBulkUpdate($hash, $r, $responseRef->{$r}) if ( ref($responseRef->{$r}) ne 'HASH' ); + foreach my $r ( keys %{$responseRef} ) { + readingsBulkUpdate( $hash, $r, $responseRef->{$r} ) + if ( ref( $responseRef->{$r} ) ne 'HASH' ); } - readingsBulkUpdate($hash, 'state', 'API Maintainer: ' . $responseRef->{apiMaintainer} . ' ErrorMsg: ' . $responseRef->{status}); - readingsEndUpdate($hash, 1); + readingsBulkUpdate( $hash, 'state', + 'API Maintainer: ' + . $responseRef->{apiMaintainer} + . ' ErrorMsg: ' + . $responseRef->{status} ); + readingsEndUpdate( $hash, 1 ); - my $next= 60; # $next= $hash->{INTERVAL}; - Weather_RearmTimer($hash, gettimeofday()+$next); + my $next = 60; # $next= $hash->{INTERVAL}; + Weather_RearmTimer( $hash, gettimeofday() + $next ); return; } sub Weather_RetrieveCallbackFn($) { - my $name = shift; - my $hash = $defs{$name}; + my $name = shift; + my $hash = $defs{$name}; my $responseRef = $hash->{fhem}->{api}->getWeather; if ( $responseRef->{status} eq 'ok' ) { - Weather_WriteReadings($hash,$responseRef); + Weather_WriteReadings( $hash, $responseRef ); } else { - Weather_ReturnWithError($hash,$responseRef); + Weather_ReturnWithError( $hash, $responseRef ); } } sub Weather_WriteReadings($$) { - my ($hash,$dataRef) = @_; + my ( $hash, $dataRef ) = @_; my $name = $hash->{NAME}; readingsBeginUpdate($hash); # delete some unused readings - 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_speed}) if(defined($hash->{READINGS}->{unit_speed})); - 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}->{temp_f} ) + if ( defined( $hash->{READINGS}->{temp_f} ) ); + 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_pressuree} ) + if ( defined( $hash->{READINGS}->{unit_pressuree} ) ); + delete( $hash->{READINGS}->{unit_temperature} ) + if ( defined( $hash->{READINGS}->{unit_temperature} ) ); # housekeeping information - readingsBulkUpdate($hash, 'lastError', ''); - foreach my $r (keys %{$dataRef} ) { - readingsBulkUpdate($hash, $r, $dataRef->{$r}) - if ( ref($dataRef->{$r}) ne 'HASH' and ref($dataRef->{$r}) ne 'ARRAY' ); - readingsBulkUpdate($hash, '.license', $dataRef->{license}->{text}); + readingsBulkUpdate( $hash, 'lastError', '' ); + foreach my $r ( keys %{$dataRef} ) { + readingsBulkUpdate( $hash, $r, $dataRef->{$r} ) + if ( ref( $dataRef->{$r} ) ne 'HASH' + and ref( $dataRef->{$r} ) ne 'ARRAY' ); + readingsBulkUpdate( $hash, '.license', $dataRef->{license}->{text} ); } ### current - if ( defined($dataRef->{current}) and ref( $dataRef->{current} ) eq 'HASH' ) { - while( my ($r,$v) = each %{$dataRef->{current}} ) { - readingsBulkUpdate($hash, $r, $v) - if ( ref($dataRef->{$r}) ne 'HASH' and ref($dataRef->{$r}) ne 'ARRAY' ); + if ( defined( $dataRef->{current} ) + and ref( $dataRef->{current} ) eq 'HASH' ) + { + while ( my ( $r, $v ) = each %{ $dataRef->{current} } ) { + readingsBulkUpdate( $hash, $r, $v ) + if ( ref( $dataRef->{$r} ) ne 'HASH' + and ref( $dataRef->{$r} ) ne 'ARRAY' ); } - readingsBulkUpdate($hash, 'icon', $iconlist[$dataRef->{current}->{code}]); - if ( defined($dataRef->{current}->{wind_direction}) - and $dataRef->{current}->{wind_direction} - and defined($dataRef->{current}->{wind_speed}) - and $dataRef->{current}->{wind_speed} - ) + readingsBulkUpdate( $hash, 'icon', + $iconlist[ $dataRef->{current}->{code} ] ); + if ( defined( $dataRef->{current}->{wind_direction} ) + and $dataRef->{current}->{wind_direction} + and defined( $dataRef->{current}->{wind_speed} ) + and $dataRef->{current}->{wind_speed} ) { - my $wdir= degrees_to_direction($dataRef->{current}->{wind_direction}, @directions_txt_i18n); - readingsBulkUpdate($hash, 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{current}->{wind_speed} . ' km/h'); + my $wdir = + degrees_to_direction( $dataRef->{current}->{wind_direction}, + @directions_txt_i18n ); + readingsBulkUpdate( $hash, 'wind_condition', + 'Wind: ' + . $wdir . ' ' + . $dataRef->{current}->{wind_speed} + . ' km/h' ); } } ### forecast - if ( ref( $dataRef->{forecast} ) eq 'HASH' - and AttrVal($name, 'forecast', 'every') ne 'off' ) { - ## hourly - if ( defined($dataRef->{forecast}->{hourly}) - and ref( $dataRef->{forecast}->{hourly} ) eq 'ARRAY' - and scalar( @{ $dataRef->{forecast}->{hourly} } ) > 0 - and (AttrVal($name, 'forecast', 'every') eq 'every' - or AttrVal($name, 'forecast', 'hourly') eq 'hourly') - ) - { - my $i= 0; - my $limit = AttrVal($name,'forecastLimit',-1); - foreach my $fc (@{$dataRef->{forecast}->{hourly}}) { - $i++; - my $f= "hfc" . $i ."_"; + if ( ref( $dataRef->{forecast} ) eq 'HASH' + and AttrVal( $name, 'forecast', 'every' ) ne 'off' ) + { + ## hourly + if ( + defined( $dataRef->{forecast}->{hourly} ) + and ref( $dataRef->{forecast}->{hourly} ) eq 'ARRAY' + and scalar( @{ $dataRef->{forecast}->{hourly} } ) > 0 + and ( AttrVal( $name, 'forecast', 'every' ) eq 'every' + or AttrVal( $name, 'forecast', 'hourly' ) eq 'hourly' ) + ) + { + my $i = 0; + my $limit = AttrVal( $name, 'forecastLimit', -1 ); + foreach my $fc ( @{ $dataRef->{forecast}->{hourly} } ) { + $i++; + my $f = "hfc" . $i . "_"; - while( my ($r,$v) = each %{$fc} ) { - readingsBulkUpdate($hash, $f.$r, $v) - if ( ref($dataRef->{$r}) ne 'HASH' and ref($dataRef->{$r}) ne 'ARRAY' ); - } - readingsBulkUpdate($hash, $f . 'icon', $iconlist[$dataRef->{forecast}->{hourly}[$i-1]{code}]); - - if ( defined($dataRef->{forecast}->{hourly}[$i-1]{wind_direction}) - and $dataRef->{forecast}->{hourly}[$i-1]{wind_direction} - and defined($dataRef->{forecast}->{hourly}[$i-1]{wind_speed}) - and $dataRef->{forecast}->{hourly}[$i-1]{wind_speed} - ) - { - my $wdir= degrees_to_direction($dataRef->{forecast}->{hourly}[$i-1]{wind_direction}, @directions_txt_i18n); - readingsBulkUpdate($hash, $f . 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{forecast}->{hourly}[$i-1]{wind_speed} . ' km/h'); - } - - last if ( $i == $limit and $limit > 0 ); + while ( my ( $r, $v ) = each %{$fc} ) { + readingsBulkUpdate( $hash, $f . $r, $v ) + if ( ref( $dataRef->{$r} ) ne 'HASH' + and ref( $dataRef->{$r} ) ne 'ARRAY' ); } - } + readingsBulkUpdate( + $hash, + $f . 'icon', + $iconlist[ $dataRef->{forecast}->{hourly}[ $i - 1 ]{code} ] + ); - ## daily - if ( defined($dataRef->{forecast}->{daily}) - and ref( $dataRef->{forecast}->{daily} ) eq 'ARRAY' - and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0 - and (AttrVal($name, 'forecast', 'every') eq 'every' - or AttrVal($name, 'forecast', 'daily') eq 'daily') - ) - { - my $i= 0; - my $limit = AttrVal($name,'forecastLimit',-1); - foreach my $fc (@{$dataRef->{forecast}->{daily}}) { - $i++; - my $f= "fc" . $i ."_"; - - while( my ($r,$v) = each %{$fc} ) { - readingsBulkUpdate($hash, $f.$r, $v) - if ( ref($dataRef->{$r}) ne 'HASH' and ref($dataRef->{$r}) ne 'ARRAY' ); - } - readingsBulkUpdate($hash, $f . 'icon', $iconlist[$dataRef->{forecast}->{daily}[$i-1]{code}]); - - if ( defined($dataRef->{forecast}->{daily}[$i-1]{wind_direction}) - and $dataRef->{forecast}->{daily}[$i-1]{wind_direction} - and defined($dataRef->{forecast}->{daily}[$i-1]{wind_speed}) - and $dataRef->{forecast}->{daily}[$i-1]{wind_speed} + if ( + defined( + $dataRef->{forecast}->{hourly}[ $i - 1 ]{wind_direction} ) - { - my $wdir= degrees_to_direction($dataRef->{forecast}->{daily}[$i-1]{wind_direction}, @directions_txt_i18n); - readingsBulkUpdate($hash, $f . 'wind_condition', 'Wind: ' . $wdir . ' ' . $dataRef->{forecast}->{daily}[$i-1]{wind_speed} . ' km/h'); - } - - last if ( $i == $limit and $limit > 0 ); + and $dataRef->{forecast}->{hourly}[ $i - 1 ]{wind_direction} + and defined( + $dataRef->{forecast}->{hourly}[ $i - 1 ]{wind_speed} + ) + and $dataRef->{forecast}->{hourly}[ $i - 1 ]{wind_speed} + ) + { + my $wdir = degrees_to_direction( + $dataRef->{forecast} + ->{hourly}[ $i - 1 ]{wind_direction}, + @directions_txt_i18n + ); + readingsBulkUpdate( + $hash, + $f . 'wind_condition', + 'Wind: ' + . $wdir . ' ' + . $dataRef->{forecast}->{hourly}[ $i - 1 ]{wind_speed} + . ' km/h' + ); } + + last if ( $i == $limit and $limit > 0 ); } + } + + ## daily + if ( + defined( $dataRef->{forecast}->{daily} ) + and ref( $dataRef->{forecast}->{daily} ) eq 'ARRAY' + and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0 + and ( AttrVal( $name, 'forecast', 'every' ) eq 'every' + or AttrVal( $name, 'forecast', 'daily' ) eq 'daily' ) + ) + { + my $i = 0; + my $limit = AttrVal( $name, 'forecastLimit', -1 ); + foreach my $fc ( @{ $dataRef->{forecast}->{daily} } ) { + $i++; + my $f = "fc" . $i . "_"; + + while ( my ( $r, $v ) = each %{$fc} ) { + readingsBulkUpdate( $hash, $f . $r, $v ) + if ( ref( $dataRef->{$r} ) ne 'HASH' + and ref( $dataRef->{$r} ) ne 'ARRAY' ); + } + readingsBulkUpdate( + $hash, + $f . 'icon', + $iconlist[ $dataRef->{forecast}->{daily}[ $i - 1 ]{code} ] + ); + + if ( + defined( + $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_direction} + ) + and $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_direction} + and defined( + $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_speed} + ) + and $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_speed} + ) + { + my $wdir = degrees_to_direction( + $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_direction}, + @directions_txt_i18n + ); + readingsBulkUpdate( + $hash, + $f . 'wind_condition', + 'Wind: ' + . $wdir . ' ' + . $dataRef->{forecast}->{daily}[ $i - 1 ]{wind_speed} + . ' km/h' + ); + } + + last if ( $i == $limit and $limit > 0 ); + } + } } - my $val= 'T: ' . $dataRef->{current}->{temperature} . ' °C' - .' ' . substr($status_items_txt_i18n{1}, 0, 1) . ': ' . $dataRef->{current}->{humidity} . ' %' - .' ' . substr($status_items_txt_i18n{0}, 0, 1) . ': ' . $dataRef->{current}->{wind} . ' km/h' - .' P: ' . $dataRef->{current}->{pressure} . ' hPa'; + my $val = 'T: ' + . $dataRef->{current}->{temperature} . ' °C' . ' ' + . substr( $status_items_txt_i18n{1}, 0, 1 ) . ': ' + . $dataRef->{current}->{humidity} . ' %' . ' ' + . substr( $status_items_txt_i18n{0}, 0, 1 ) . ': ' + . $dataRef->{current}->{wind} . ' km/h' . ' P: ' + . $dataRef->{current}->{pressure} . ' hPa'; Log3 $hash, 4, "$name: $val"; - readingsBulkUpdate($hash, 'state', $val); + readingsBulkUpdate( $hash, 'state', $val ); - readingsEndUpdate($hash, 1); + readingsEndUpdate( $hash, 1 ); - Weather_RearmTimer($hash, gettimeofday()+$hash->{INTERVAL}); + Weather_RearmTimer( $hash, gettimeofday() + $hash->{INTERVAL} ); return; } @@ -317,16 +509,18 @@ sub Weather_GetUpdate($) { my ($hash) = @_; my $name = $hash->{NAME}; - if($attr{$name} && $attr{$name}->{disable}) { - Log3 $hash, 5, "Weather $name: retrieval of weather data is disabled by attribute."; - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, "pubDateComment", "disabled by attribute"); - readingsBulkUpdate($hash, "validity", "stale"); - readingsEndUpdate($hash, 1); - Weather_RearmTimer($hash, gettimeofday()+$hash->{INTERVAL}); - } else { -# Weather_RetrieveData($name, 0); - $hash->{fhem}->{api}->setRetrieveData; + if ( $attr{$name} && $attr{$name}->{disable} ) { + Log3 $hash, 5, + "Weather $name: retrieval of weather data is disabled by attribute."; + readingsBeginUpdate($hash); + readingsBulkUpdate( $hash, "pubDateComment", "disabled by attribute" ); + readingsBulkUpdate( $hash, "validity", "stale" ); + readingsEndUpdate( $hash, 1 ); + Weather_RearmTimer( $hash, gettimeofday() + $hash->{INTERVAL} ); + } + else { + # Weather_RetrieveData($name, 0); + $hash->{fhem}->{api}->setRetrieveData; } return 1; @@ -334,22 +528,23 @@ sub Weather_GetUpdate($) { ################################### sub Weather_Get($@) { - my ($hash, @a) = @_; + my ( $hash, @a ) = @_; - return "argument is missing" if(int(@a) != 2); + return "argument is missing" if ( int(@a) != 2 ); - my $reading= $a[1]; + my $reading = $a[1]; my $value; - if(defined($hash->{READINGS}->{$reading})) { - $value = $hash->{READINGS}->{$reading}->{VAL}; - } else { - my $rt = ''; - if(defined($hash->{READINGS})) { - $rt = join(":noArg ", sort keys %{$hash->{READINGS}}); - } + if ( defined( $hash->{READINGS}->{$reading} ) ) { + $value = $hash->{READINGS}->{$reading}->{VAL}; + } + else { + my $rt = ''; + if ( defined( $hash->{READINGS} ) ) { + $rt = join( ":noArg ", sort keys %{ $hash->{READINGS} } ); + } - return "Unknown reading $reading, choose one of " . $rt; + return "Unknown reading $reading, choose one of " . $rt; } return "$a[0] $reading => $value"; @@ -357,118 +552,133 @@ sub Weather_Get($@) { ################################### sub Weather_Set($@) { - my ($hash, @a) = @_; + my ( $hash, @a ) = @_; - my $cmd= $a[1]; + my $cmd = $a[1]; # usage check - if((@a == 2) && ($a[1] eq "update")) { + if ( ( @a == 2 ) && ( $a[1] eq "update" ) ) { Weather_DisarmTimer($hash); Weather_GetUpdate($hash); return undef; - } else { + } + else { return "Unknown argument $cmd, choose one of update:noArg"; } } ################################### sub Weather_RearmTimer($$) { - my ($hash, $t) = @_; - - InternalTimer($t, "Weather_GetUpdate", $hash, 0) ; + my ( $hash, $t ) = @_; + + InternalTimer( $t, "Weather_GetUpdate", $hash, 0 ); } sub Weather_DisarmTimer($) { - my ($hash)= @_; - + my ($hash) = @_; + RemoveInternalTimer($hash); } sub Weather_Notify($$) { - my ($hash,$dev) = @_; - my $name = $hash->{NAME}; - my $type = $hash->{TYPE}; + my ( $hash, $dev ) = @_; + my $name = $hash->{NAME}; + my $type = $hash->{TYPE}; - return if($dev->{NAME} ne "global"); - return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}})); + return if ( $dev->{NAME} ne "global" ); + return if ( !grep( m/^INITIALIZED|REREADCFG$/, @{ $dev->{CHANGED} } ) ); # return if($attr{$name} && $attr{$name}->{disable}); # update weather after initialization or change of configuration # wait 10 to 29 seconds to avoid congestion due to concurrent activities Weather_DisarmTimer($hash); - my $delay= 10+int(rand(20)); + my $delay = 10 + int( rand(20) ); #$delay= 3; # delay removed until further notice - Log3 $hash, 5, "Weather $name: FHEM initialization or rereadcfg triggered update, delay $delay seconds."; - Weather_RearmTimer($hash, gettimeofday()+$delay) ; + Log3 $hash, 5, +"Weather $name: FHEM initialization or rereadcfg triggered update, delay $delay seconds."; + Weather_RearmTimer( $hash, gettimeofday() + $delay ); return undef; } ##################################### sub Weather_Define($$) { - my ($hash, $def) = @_; + my ( $hash, $def ) = @_; - my $usage= "syntax: define Weather [API=] [apikey=] [location=] [interval=] [lang=]"; + my $usage = +"syntax: define Weather [API=] [apikey=] [location=] [interval=] [lang=]"; # defaults - my $API="DarkSkyAPI,cachemaxage:600"; - my $interval = 3600; + my $API = "DarkSkyAPI,cachemaxage:600"; + my $interval = 3600; # parse parameters - my ($arrayref, $hashref)= parseParams($def); - my @a= @{$arrayref}; - my %h= %{$hashref}; + my ( $arrayref, $hashref ) = parseParams($def); + my @a = @{$arrayref}; + my %h = %{$hashref}; # check minimum syntax - return $usage unless(scalar @a == 2); - my $name= $a[0]; + return $usage unless ( scalar @a == 2 ); + my $name = $a[0]; - - my $location= $h{location} if exists $h{location}; - my $apikey = $h{apikey} if exists $h{apikey}; - my $lang= $h{lang} if exists $h{lang}; - $interval= $h{interval} if exists $h{interval}; - $API = $h{API} if exists $h{API}; + my $location = $h{location} if exists $h{location}; + my $apikey = $h{apikey} if exists $h{apikey}; + my $lang = $h{lang} if exists $h{lang}; + $interval = $h{interval} if exists $h{interval}; + $API = $h{API} if exists $h{API}; # evaluate API options - my ($api,$apioptions)= split(',', $API, 2); - $apioptions= "" unless(defined($apioptions)); - eval { - require "$api.pm"; - }; - return "$name: cannot load API $api: $@" if($@); + my ( $api, $apioptions ) = split( ',', $API, 2 ); + $apioptions = "" unless ( defined($apioptions) ); + eval { require "$api.pm"; }; + return "$name: cannot load API $api: $@" if ($@); $hash->{NOTIFYDEV} = "global"; - $hash->{fhem}->{interfaces}= "temperature;humidity;wind"; - $hash->{LOCATION} = ( (defined($location) and $location) ? $location : AttrVal( 'global', 'latitude', 'error' ).','.AttrVal( 'global', 'longitude', 'error' ) ); - $hash->{INTERVAL} = $interval; - $hash->{LANG} = ( (defined($lang) and $lang) ? $lang : lc(AttrVal('global','language','de')) ); - $hash->{API} = $api; - $hash->{MODEL} = $api; - $hash->{APIKEY} = $apikey; - $hash->{APIOPTIONS} = $apioptions; - $hash->{READINGS}->{current_date_time}->{TIME}= TimeNow(); - $hash->{READINGS}->{current_date_time}->{VAL}= "none"; - $hash->{fhem}->{allowCache}= 1; + $hash->{fhem}->{interfaces} = "temperature;humidity;wind"; + $hash->{LOCATION} = + ( ( defined($location) and $location ) + ? $location + : AttrVal( 'global', 'latitude', 'error' ) . ',' + . AttrVal( 'global', 'longitude', 'error' ) ); + $hash->{INTERVAL} = $interval; + $hash->{LANG} = + ( ( defined($lang) and $lang ) + ? $lang + : lc( AttrVal( 'global', 'language', 'de' ) ) ); + $hash->{API} = $api; + $hash->{MODEL} = $api; + $hash->{APIKEY} = $apikey; + $hash->{APIOPTIONS} = $apioptions; + $hash->{READINGS}->{current_date_time}->{TIME} = TimeNow(); + $hash->{READINGS}->{current_date_time}->{VAL} = "none"; + $hash->{fhem}->{allowCache} = 1; - readingsSingleUpdate($hash,'state','Initialized',1); - Weather_LanguageInitialize($hash->{LANG}); + readingsSingleUpdate( $hash, 'state', 'Initialized', 1 ); + Weather_LanguageInitialize( $hash->{LANG} ); my $apistring = $api . '::Weather'; - $hash->{fhem}->{api} = $apistring->new( { devName => $hash->{NAME}, apikey => $hash->{APIKEY}, location => $hash->{LOCATION}, apioptions => $hash->{APIOPTIONS}, language => $hash->{LANG} } ); + $hash->{fhem}->{api} = $apistring->new( + { + devName => $hash->{NAME}, + apikey => $hash->{APIKEY}, + location => $hash->{LOCATION}, + apioptions => $hash->{APIOPTIONS}, + language => $hash->{LANG} + } + ); - Weather_GetUpdate($hash) if($init_done); + Weather_GetUpdate($hash) if ($init_done); return undef; } ##################################### sub Weather_Undef($$) { - my ($hash, $arg) = @_; + my ( $hash, $arg ) = @_; RemoveInternalTimer($hash); return undef; @@ -485,51 +695,65 @@ use constant ICONSCALE => 0.5; ##################################### sub WeatherIconIMGTag($) { - my $width= int(ICONSCALE*ICONWIDTH); - my ($icon)= @_; - my $url= FW_IconURL("weather/$icon"); - my $style= " width=$width"; + my $width = int( ICONSCALE * ICONWIDTH ); + my ($icon) = @_; + my $url = FW_IconURL("weather/$icon"); + my $style = " width=$width"; return "\"$icon\""; } ##################################### sub WeatherAsHtmlV($;$$) { - my ($d,$items,$f) = @_; + my ( $d, $items, $f ) = @_; - $d = "" if(!$d); - $items = 6 if( !$items ); + $d = "" if ( !$d ); + $items = 6 if ( !$items ); return "$d is not a Weather instance
" - if(!$defs{$d} || $defs{$d}->{TYPE} ne "Weather"); + if ( !$defs{$d} || $defs{$d}->{TYPE} ne "Weather" ); - my $h = $defs{$d}; - my $width= int(ICONSCALE*ICONWIDTH); + my $h = $defs{$d}; + my $width = int( ICONSCALE * ICONWIDTH ); my $ret = ''; my $fc; - if ( defined($f) - and ($f eq 'h' - or $f eq 'd') + if ( + defined($f) + and ( $f eq 'h' + or $f eq 'd' ) ) { $fc = ( $f eq 'd' ? 'fc' : 'hfc' ); } - else { $fc = ( (defined($h->{READINGS}->{fc1_day_of_week}) and $h->{READINGS}->{fc1_day_of_week}) ? 'fc' : 'hfc' ); } - - $ret .= sprintf('', - $width, - WeatherIconIMGTag(ReadingsVal($d, "icon", "")), - ReadingsVal($d, "condition", ""), - ReadingsVal($d, "temp_c", ""), ReadingsVal($d, "humidity", ""), - ReadingsVal($d, "wind_condition", "")); + else { + $fc = ( + ( + defined( $h->{READINGS}->{fc1_day_of_week} ) + and $h->{READINGS}->{fc1_day_of_week} + ) ? 'fc' : 'hfc' + ); + } - for(my $i=1; $i<$items; $i++) { - $ret .= sprintf('', + $ret .= sprintf( +'', + $width, + WeatherIconIMGTag( ReadingsVal( $d, "icon", "" ) ), + ReadingsVal( $d, "condition", "" ), + ReadingsVal( $d, "temp_c", "" ), + ReadingsVal( $d, "humidity", "" ), + ReadingsVal( $d, "wind_condition", "" ) + ); + + for ( my $i = 1 ; $i < $items ; $i++ ) { + $ret .= sprintf( +'', $width, - WeatherIconIMGTag(ReadingsVal($d, "${fc}${i}_icon", "")), - ReadingsVal($d, "${fc}${i}_day_of_week", ""), - ReadingsVal($d, "${fc}${i}_condition", ""), - ReadingsVal($d, "${fc}${i}_low_c", " - "), ReadingsVal($d, "${fc}${i}_high_c", " - ")); + WeatherIconIMGTag( ReadingsVal( $d, "${fc}${i}_icon", "" ) ), + ReadingsVal( $d, "${fc}${i}_day_of_week", "" ), + ReadingsVal( $d, "${fc}${i}_condition", "" ), + ReadingsVal( $d, "${fc}${i}_low_c", " - " ), + ReadingsVal( $d, "${fc}${i}_high_c", " - " ) + ); } $ret .= "
%s%s
%s°C %s%%
%s
%s%s: %s
min %s°C max %s°C
%s%s
%s°C %s%%
%s
%s%s: %s
min %s°C max %s°C
"; @@ -537,63 +761,84 @@ sub WeatherAsHtmlV($;$$) { } sub WeatherAsHtml($;$) { - my ($d,$i) = @_; + my ( $d, $i ) = @_; - WeatherAsHtmlV($d,$i); + WeatherAsHtmlV( $d, $i ); } sub WeatherAsHtmlH($;$$) { - my ($d,$items,$f) = @_; + my ( $d, $items, $f ) = @_; - $d = "" if(!$d); - $items = 6 if( !$items ); + $d = "" if ( !$d ); + $items = 6 if ( !$items ); return "$d is not a Weather instance
" - if(!$defs{$d} || $defs{$d}->{TYPE} ne "Weather"); + if ( !$defs{$d} || $defs{$d}->{TYPE} ne "Weather" ); - my $h = $defs{$d}; - my $width= int(ICONSCALE*ICONWIDTH); + my $h = $defs{$d}; + my $width = int( ICONSCALE * ICONWIDTH ); - - - my $format= '
%s
%s
%s°C %s%%
%s
'; + my $format = +'
%s
%s
%s°C %s%%
%s
'; my $ret = ''; my $fc; - if ( defined($f) - and ($f eq 'h' - or $f eq 'd') + if ( + defined($f) + and ( $f eq 'h' + or $f eq 'd' ) ) { $fc = ( $f eq 'd' ? 'fc' : 'hfc' ); } - else { $fc = ( (defined($h->{READINGS}->{fc1_day_of_week}) and $h->{READINGS}->{fc1_day_of_week}) ? 'fc' : 'hfc' ); } + else { + $fc = ( + ( + defined( $h->{READINGS}->{fc1_day_of_week} ) + and $h->{READINGS}->{fc1_day_of_week} + ) ? 'fc' : 'hfc' + ); + } # icons - $ret .= sprintf('', $width, WeatherIconIMGTag(ReadingsVal($d, "icon", ""))); - for(my $i=1; $i<$items; $i++) { - $ret .= sprintf('', $width, WeatherIconIMGTag(ReadingsVal($d, "${fc}${i}_icon", ""))); + $ret .= sprintf( '', + $width, WeatherIconIMGTag( ReadingsVal( $d, "icon", "" ) ) ); + for ( my $i = 1 ; $i < $items ; $i++ ) { + $ret .= sprintf( '', + $width, + WeatherIconIMGTag( ReadingsVal( $d, "${fc}${i}_icon", "" ) ) ); } $ret .= ''; # condition - $ret .= sprintf('', ReadingsVal($d, "condition", "")); - for(my $i=1; $i<$items; $i++) { - $ret .= sprintf('', ReadingsVal($d, "${fc}${i}_day_of_week", ""), - ReadingsVal($d, "${fc}${i}_condition", "")); + $ret .= sprintf( '', + ReadingsVal( $d, "condition", "" ) ); + for ( my $i = 1 ; $i < $items ; $i++ ) { + $ret .= sprintf( + '', + ReadingsVal( $d, "${fc}${i}_day_of_week", "" ), + ReadingsVal( $d, "${fc}${i}_condition", "" ) + ); } $ret .= ''; # temp/hum | min - $ret .= sprintf('', ReadingsVal($d, "temp_c", ""), ReadingsVal($d, "humidity", "")); - for(my $i=1; $i<$items; $i++) { - $ret .= sprintf('', ReadingsVal($d, "${fc}${i}_low_c", " - ")); + $ret .= sprintf( + '', + ReadingsVal( $d, "temp_c", "" ), + ReadingsVal( $d, "humidity", "" ) + ); + for ( my $i = 1 ; $i < $items ; $i++ ) { + $ret .= sprintf( '', + ReadingsVal( $d, "${fc}${i}_low_c", " - " ) ); } $ret .= ''; # wind | max - $ret .= sprintf('', ReadingsVal($d, "wind_condition", "")); - for(my $i=1; $i<$items; $i++) { - $ret .= sprintf('', ReadingsVal($d, "${fc}${i}_high_c", " - ")); + $ret .= sprintf( '', + ReadingsVal( $d, "wind_condition", "" ) ); + for ( my $i = 1 ; $i < $items ; $i++ ) { + $ret .= sprintf( '', + ReadingsVal( $d, "${fc}${i}_high_c", " - " ) ); } $ret .= "
%s%s
%s%s
%s%s: %s
%s%s: %s
%s°C %s%%min %s°C
%s°C %s%%min %s°C
%smax %s°C
%smax %s°C
"; @@ -601,18 +846,18 @@ sub WeatherAsHtmlH($;$$) { } sub WeatherAsHtmlD($;$) { - my ($d,$i) = @_; - - if($FW_ss) { - WeatherAsHtmlV($d,$i); - } else { - WeatherAsHtmlH($d,$i); + my ( $d, $i ) = @_; + + if ($FW_ss) { + WeatherAsHtmlV( $d, $i ); + } + else { + WeatherAsHtmlH( $d, $i ); } } ##################################### - 1; =pod @@ -665,7 +910,7 @@ sub WeatherAsHtmlD($;$) { Examples:
       define Forecast Weather apikey=987498ghjgf864
-      define MyWeather Weather api=OpenWeatherMapAPI,cachemaxage:600 apikey=09878945fdskv876 location=52.4545,13.4545 interval=3600 lang=de
+      define MyWeather Weather API=OpenWeatherMapAPI,cachemaxage:600 apikey=09878945fdskv876 location=52.4545,13.4545 interval=3600 lang=de