From 63fe6a30660809c0ca17451840c1302018f82686 Mon Sep 17 00:00:00 2001 From: LeonGaultier Date: Thu, 17 Jan 2019 10:51:24 +0000 Subject: [PATCH] 59_Weather: Codestyle, add attribut model to API git-svn-id: https://svn.fhem.de/fhem/trunk@18292 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/59_Weather.pm | 403 +++++++++++++++++++--------------------- 2 files changed, 197 insertions(+), 207 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 68e389517..c404564fd 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - change: 59_Weather: Codestyle, add attribut model to API - bugfix: 73_AutoShuttersControl: fix drive up then roommate asleep - bugfix: DarkSkyAPI: fix uninitialized value in localtime at line 430 - bugfix: 89_FULLY: fixed command set url diff --git a/fhem/FHEM/59_Weather.pm b/fhem/FHEM/59_Weather.pm index eb1f48f28..7d18c2d53 100755 --- a/fhem/FHEM/59_Weather.pm +++ b/fhem/FHEM/59_Weather.pm @@ -79,77 +79,74 @@ my @iconlist = ( ################################### sub Weather_LanguageInitialize($) { + my ($lang) = @_; - 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]); - } + 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]); + } } ##################################### sub Weather_Initialize($) { + my ($hash) = @_; - my ($hash) = @_; + $hash->{DefFn} = "Weather_Define"; + $hash->{UndefFn} = "Weather_Undef"; + $hash->{GetFn} = "Weather_Get"; + $hash->{SetFn} = "Weather_Set"; + $hash->{AttrList}= "disable:0,1 " . $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 " . $readingFnAttributes; - $hash->{NotifyFn}= "Weather_Notify"; - - #Weather_DebugCodes('de'); + #Weather_DebugCodes('de'); } ################################### sub degrees_to_direction($@) { - my ($degrees,@directions_txt_i18n) = @_; - my $mod = int((($degrees + 11.25) % 360) / 22.5); - return $directions_txt_i18n[$mod]; + my ($degrees,@directions_txt_i18n) = @_; + my $mod = int((($degrees + 11.25) % 360) / 22.5); + return $directions_txt_i18n[$mod]; } @@ -173,7 +170,6 @@ sub Weather_ReturnWithError($$) { } sub Weather_RetrieveCallbackFn($) { - my $name = shift; my $hash = $defs{$name}; my $responseRef = $hash->{fhem}->{api}->getWeather; @@ -300,7 +296,6 @@ sub Weather_WriteReadings($$) { ################################### sub Weather_GetUpdate($) { - my ($hash) = @_; my $name = $hash->{NAME}; @@ -321,148 +316,146 @@ 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 $value; - 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"; + return "$a[0] $reading => $value"; } ################################### 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")) { - Weather_DisarmTimer($hash); - Weather_GetUpdate($hash); - return undef; - } else { - return "Unknown argument $cmd, choose one of update:noArg"; - } + # usage check + if((@a == 2) && ($a[1] eq "update")) { + Weather_DisarmTimer($hash); + Weather_GetUpdate($hash); + return undef; + } 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)= @_; + 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}); + # 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)); + # 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)); - #$delay= 3; # delay removed until further notice + #$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; + 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; - # defaults - my $API="DarkSkyAPI,cachemaxage:600"; - my $interval = 3600; + # parse parameters + my ($arrayref, $hashref)= parseParams($def); + my @a= @{$arrayref}; + my %h= %{$hashref}; - # parse parameters - my ($arrayref, $hashref)= parseParams($def); - my @a= @{$arrayref}; - my %h= %{$hashref}; - - # check minimum syntax - return $usage unless(scalar @a == 2); - my $name= $a[0]; + # check minimum syntax + 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 { + # evaluate API options + my ($api,$apioptions)= split(',', $API, 2); + $apioptions= "" unless(defined($apioptions)); + eval { require "$api.pm"; - }; - return "$name: cannot load API $api: $@" if($@); + }; + 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->{APIKEY} = $apikey; - $hash->{APIOPTIONS} = $apioptions; - #$hash->{UNITS} = "c"; # hardcoded to use degrees centigrade (Celsius) - $hash->{READINGS}->{current_date_time}->{TIME}= TimeNow(); - $hash->{READINGS}->{current_date_time}->{VAL}= "none"; + $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->{APIKEY} = $apikey; + $hash->{APIOPTIONS} = $apioptions; + $attr{$name}->{model} = $api; + #$hash->{UNITS} = "c"; # hardcoded to use degrees centigrade (Celsius) + $hash->{READINGS}->{current_date_time}->{TIME}= TimeNow(); + $hash->{READINGS}->{current_date_time}->{VAL}= "none"; - $hash->{fhem}->{allowCache}= 1; + $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} } ); + my $apistring = $api . '::Weather'; + $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; + return undef; } ##################################### sub Weather_Undef($$) { + my ($hash, $arg) = @_; - my ($hash, $arg) = @_; - - RemoveInternalTimer($hash); - return undef; + RemoveInternalTimer($hash); + return undef; } ##################################### @@ -476,116 +469,112 @@ use constant ICONSCALE => 0.5; ##################################### sub WeatherIconIMGTag($) { - - my $width= int(ICONSCALE*ICONWIDTH); - my ($icon)= @_; - my $url= FW_IconURL("weather/$icon"); - my $style= " width=$width"; - return "\"$icon\""; - + my $width= int(ICONSCALE*ICONWIDTH); + my ($icon)= @_; + my $url= FW_IconURL("weather/$icon"); + my $style= " width=$width"; + return "\"$icon\""; } ##################################### -sub WeatherAsHtmlV($;$) -{ +sub WeatherAsHtmlV($;$) { + my ($d,$items) = @_; - my ($d,$items) = @_; - $d = "" if(!$d); - $items = 9 if( !$items ); - return "$d is not a Weather instance
" + $d = "" if(!$d); + $items = 9 if( !$items ); + return "$d is not a Weather instance
" 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 = ''; - $ret .= sprintf('', + my $ret = '
%s%s
%s°C %s%%
%s
'; + $ret .= sprintf('', $width, WeatherIconIMGTag(ReadingsVal($d, "icon", "")), ReadingsVal($d, "condition", ""), ReadingsVal($d, "temp_c", ""), ReadingsVal($d, "humidity", ""), ReadingsVal($d, "wind_condition", "")); - my $fc = ( (defined($h->{READINGS}->{fc1_day_of_week}) and $h->{READINGS}->{fc1_day_of_week}) ? 'fc' : 'hfc' ); - for(my $i=1; $i<$items; $i++) { + my $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('', $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", "")); - } + } - $ret .= "
%s%s
%s°C %s%%
%s
%s%s: %s
min %s°C max %s°C
"; - return $ret; + $ret .= ""; + return $ret; } -sub WeatherAsHtml($;$) -{ - my ($d,$i) = @_; - WeatherAsHtmlV($d,$i); +sub WeatherAsHtml($;$) { + my ($d,$i) = @_; + + WeatherAsHtmlV($d,$i); } -sub WeatherAsHtmlH($;$) -{ +sub WeatherAsHtmlH($;$) { + my ($d,$items) = @_; - my ($d,$items) = @_; - $d = "" if(!$d); - $items = 9 if( !$items ); - return "$d is not a Weather instance
" + $d = "" if(!$d); + $items = 9 if( !$items ); + return "$d is not a Weather instance
" 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 = ( (defined($h->{READINGS}->{fc1_day_of_week}) and $h->{READINGS}->{fc1_day_of_week}) ? 'fc' : 'hfc' ); + my $ret = '
'; + my $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++) { + # 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 .= ''; + } + $ret .= ''; - # condition - $ret .= sprintf('', ReadingsVal($d, "condition", "")); - for(my $i=1; $i<$items; $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 .= ''; + } + $ret .= ''; - # temp/hum | min - $ret .= sprintf('', ReadingsVal($d, "temp_c", ""), ReadingsVal($d, "humidity", "")); - for(my $i=1; $i<$items; $i++) { + # 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 .= ''; + } + $ret .= ''; - # wind | max - $ret .= sprintf('', ReadingsVal($d, "wind_condition", "")); - for(my $i=1; $i<$items; $i++) { + # wind | max + $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°C %s%%
%s°C %s%%min %s°C
%s
%smax %s°C
"; + } + $ret .= ""; - return $ret; + return $ret; } -sub WeatherAsHtmlD($;$) -{ - my ($d,$i) = @_; - if($FW_ss) { +sub WeatherAsHtmlD($;$) { + my ($d,$i) = @_; + + if($FW_ss) { WeatherAsHtmlV($d,$i); - } else { + } else { WeatherAsHtmlH($d,$i); - } + } } #####################################