diff --git a/fhem/CHANGED b/fhem/CHANGED index 1977037f7..333350623 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -501,3 +501,4 @@ - bugfix: sunrise stuff fixed, doc missing - feature: CUL FHT sending added - bugfix: workaround to make M232 counter wraparound + - feature: Google Weather API support form FHEM (Boris 2009-06-01) \ No newline at end of file diff --git a/fhem/FHEM/59_Weather.pm b/fhem/FHEM/59_Weather.pm new file mode 100755 index 000000000..0593aa519 --- /dev/null +++ b/fhem/FHEM/59_Weather.pm @@ -0,0 +1,193 @@ +# +# +# 59_Weather.pm +# written by Dr. Boris Neubert 2009-06-01 +# e-mail: omega at online dot de +# +############################################## +package main; + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday); +use Weather::Google; + +##################################### +sub Weather_Initialize($) { + + my ($hash) = @_; + +# Provider +# $hash->{Clients} = undef; + +# Consumer + $hash->{DefFn} = "Weather_Define"; + $hash->{UndefFn} = "Weather_Undef"; + $hash->{GetFn} = "Weather_Get"; + $hash->{AttrList}= "loglevel:0,1,2,3,4,5"; + +} + +################################### +sub f_to_c($) { + + my ($f)= @_; + + return int(($f-32)*5/9+0.5); +} + +################################### +sub Weather_UpdateReading($$$$$) { + + my ($hash,$prefix,$key,$tn,$value)= @_; + + return 0 if(!defined($value) || $value eq ""); + return 0 if($key eq "unit_system"); + + if($key eq "temp") { + $key= "temp_c"; + $value= f_to_c($value); + } elsif($key eq "low") { + $key= "low_c"; + $value= f_to_c($value); + } elsif($key eq "high") { + $key= "high_c"; + $value= f_to_c($value); + } + + my $reading= $prefix . $key; + my $r= $hash->{READINGS}; + $r->{$reading}{TIME}= $tn; + $r->{$reading}{VAL} = $value; + Log 5, "Weather $hash->{NAME}: $reading= $value"; + + return 1; +} + +################################### +sub Weather_GetUpdate($) +{ + my ($hash) = @_; + + if(!$hash->{LOCAL}) { + InternalTimer(gettimeofday()+$hash->{INTERVAL}, "Weather_GetUpdate", $hash, 1); + } + + my $name = $hash->{NAME}; + + + # time + my $tn = TimeNow(); + + + # get weather information from Google weather API + # see http://search.cpan.org/~possum/Weather-Google-0.03/lib/Weather/Google.pm + + my $location= $hash->{LOCATION}; + my $WeatherObj= new Weather::Google($location); + + Log 4, "$name: Updating weather information for $location."; + + my $current = $WeatherObj->current_conditions; + foreach my $condition ( keys ( %$current ) ) { + my $value= $current->{$condition}; + Weather_UpdateReading($hash,"",$condition,$tn,$value); + } + + my $fci= $WeatherObj->forecast_information; + foreach my $i ( keys ( %$fci ) ) { + my $reading= $i; + my $value= $fci->{$i}; + Weather_UpdateReading($hash,"",$i,$tn,$value); + } + + for(my $t= 0; $t<= 3; $t++) { + my $fcc= $WeatherObj->forecast_conditions($t); + my $prefix= sprintf("fc%d_", $t); + foreach my $condition ( keys ( %$fcc ) ) { + my $value= $fcc->{$condition}; + Weather_UpdateReading($hash,$prefix,$condition,$tn,$value); + } + } + + if(!$hash->{LOCAL}) { + DoTrigger($name, undef) if($init_done); + } + + return 1; +} + +# Perl Special: { $defs{Weather}{READINGS}{condition}{VAL} } +# conditions: Mostly Cloudy, Overcast, Clear, Chance of Rain + +################################### +sub Weather_Get($@) { + + my ($hash, @a) = @_; + + return "argument is missing" if(int(@a) != 2); + + $hash->{LOCAL} = 1; + Weather_GetUpdate($hash); + delete $hash->{LOCAL}; + + my $reading= $a[1]; + my $value; + + if(defined($hash->{READINGS}{$reading})) { + $value= $hash->{READINGS}{$reading}{VAL}; + } else { + return "no such reading: $reading"; + } + + return "$a[0] $reading => $value"; +} + + +##################################### +sub Weather_Define($$) { + + my ($hash, $def) = @_; + + # define Weather [interval] + # define MyWeather Weather "Maintal,HE" 3600 + + my @a = split("[ \t][ \t]*", $def); + + return "syntax: define Weather [interval]" + if(int(@a) < 3 && int(@a) > 4); + + $hash->{STATE} = "Initialized"; + + my $name = $a[0]; + my $location = $a[2]; + my $interval = 3600; + if(int(@a)==4) { $interval= $a[3]; } + + $hash->{LOCATION} = $location; + $hash->{INTERVAL} = $interval; + $hash->{READINGS}{current_date_time}{TIME}= TimeNow(); + $hash->{READINGS}{current_date_time}{VAL}= "none"; + + $hash->{LOCAL} = 1; + Weather_GetUpdate($hash); + delete $hash->{LOCAL}; + + InternalTimer(gettimeofday()+$hash->{INTERVAL}, "Weather_GetUpdate", $hash, 0); + + return undef; +} + +##################################### +sub Weather_Undef($$) { + + my ($hash, $arg) = @_; + + RemoveInternalTimer($hash); + return undef; +} + +##################################### + + +1; diff --git a/fhem/HISTORY b/fhem/HISTORY index 6aef3979d..2682be50e 100644 --- a/fhem/HISTORY +++ b/fhem/HISTORY @@ -403,3 +403,7 @@ - Sun May 31 2009 (Boris) - 81_M232Counter.pm: counter stops at 65536; workaround makes counter wraparound + +- Mon Jun 01 2009 (Boris) + - 59_Weather.pm: new virtual device for weather forecasts, documentation + updated. diff --git a/fhem/docs/USB.html b/fhem/docs/USB.html index f60a1a558..f5e36f9a8 100644 --- a/fhem/docs/USB.html +++ b/fhem/docs/USB.html @@ -119,7 +119,7 @@ with DEVICEID substituted by the device's ID.

6. USB extenders

To increase the maximum cable length from 5 meters to 10 meters, so-called -USB extenders are on sale. The consist of a fixed passive 1-port hub at the end of +USB extenders are on sale. They consist of a fixed passive 1-port hub at the end of an USB cable. This drives the USB to its limits and may cause all sorts of problems on the bus. Either do not use USB extenders (confirmed, see [10]) at all or put an active (self-powered) hub in the middle (unconfirmed). diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html index 6f5791c2c..2f860f6d6 100644 --- a/fhem/docs/commandref.html +++ b/fhem/docs/commandref.html @@ -73,6 +73,7 @@ structure   WS2000   WS300   + Weather   X10   FHEMRENDERER   @@ -2186,6 +2187,84 @@ A line ending with \ will be concatenated with the next one, so long lines + +

Weather

+
    +
    + + + Define +
      + define <name> Weather <location> [<interval>]
      +
      + Defines a virtual device for weather forecasts. You need to have the perl + module Weather::Google installed to use this device. If you do not have it, + use cpan -i Weather::Google to install it.

      + + A Weather device periodically gathers current and forecast weather conditions + from the Google Weather API.

      + + The parameter location is any string that is recognized as a + location, either a town name or a zip code. Browse to the URL + http://www.google.de/ig/api?weather=location&hl=en + to see the raw output for your location.

      + + The parameter interval is the time between subsequent updates + in seconds. It defaults to 3600 (1 hour).

      + + Examples: +
      +      define MyWeather Weather "Frankfurt,HE"
      +      define Forecast Weather "Amsterdam,NL" 1800
      +      define weather Weather "30000,France"
      +    
      +
    +
    + + + Set +
      + N/A +
    +
    + + + + Get +
      + get <name> <reading>

      + + Valid readings and their meaning (? can be one of 0, 1, 2, 3 and stands + for today, tomorrow, ...):
      + + + + + + + + + + + + + + + +
      cityname of town returned for location
      conditioncurrent condition, one of Sunny, Clear, Partly Cloudy, Mostly Cloudy, Overcast, Chance of Rain
      current_date_timelast update of forecast on server
      fc?_conditionforecast condition
      fc?_day_of_weekday of week for day +?
      fc?_high_cforecasted daily high in degrees centigrade
      fc?_iconrelative path for forecast icon, prefix with http://www.google.com to form a valid URL for display in web interfaces
      fc?_low_cforecasted daily low in degrees centigrade
      humiditycurrent humidity
      iconrelative path for current icon
      postal_codelocation sent to server
      temp_ccurrent temperature in degrees centigrade
      temp_fcurrent temperature in degrees Fahrenheit
      wind_conditionwind direction and speed
      + +
    +
    + + Attributes +
      + N/A +
    +
    +
+ + +

SCIVT

    @@ -2297,7 +2376,8 @@ A line ending with \ will be concatenated with the next one, so long lines get <name> counter

    Gets the number of ticks of the counter since the last reset. The counter - wraps around from 65535 to 0. + wraps around from 65,535 to 0 and then stops. + See M232Counter for how we care about this.

@@ -2348,7 +2428,11 @@ A line ending with \ will be concatenated with the next one, so long lines
Do not forget to start the counter (with set .. start for M232) or to start the counter and set the reading to a specified value - (with set ... value for M232Counter).

+ (with set ... value for M232Counter).

+ To avoid issues with the tick count reaching the end point, the device's + internal counter is automatically reset to 0 when the tick count is 64,000 + or above and the reading basis is adjusted accordingly. +

@@ -2449,7 +2533,7 @@ A line ending with \ will be concatenated with the next one, so long lines The structure device is used to organize/structure a devices in order to set groups of them at once (e.g. switching everything off in a house).
- + The list of attached devices can be modified through the addstruct / delstruct commands. Each attached device will get the attribute <struct_type>=<name>
when it is added to the list, and the @@ -2951,7 +3035,7 @@ A line ending with \ will be concatenated with the next one, so long lines
  • 3
    Month dependent date. Arguments: <nth> <weekday> <month <holiday-name>.
    - Examples:
    + Examples:
      3 1 Mon 05 First Monday In May
      3 2 Mon 05 Second Monday In May
      @@ -2962,7 +3046,7 @@ A line ending with \ will be concatenated with the next one, so long lines
    • 4
      Interval. Arguments: <MM-DD> <MM-DD> <holiday-name> .
      - Example:
      + Example:
        4 01-06 31-06 Summer holiday
      @@ -3611,7 +3695,7 @@ isday, sunrise_coord $month is in the range of 1 to 12, and $year is also corrected by 1900 (as one would normally expect). Additionally $we is 1 if it is weekend (i.e $wday == 0 || $wday == 6), and 0 otherwise. If the holida2we global attribute is set, $we is 1 for holidays too. Example: