mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 10:46:53 +00:00
*** empty log message ***
git-svn-id: https://svn.fhem.de/fhem/trunk@384 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
d407cdf4a2
commit
909b068f36
@ -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)
|
193
fhem/FHEM/59_Weather.pm
Executable file
193
fhem/FHEM/59_Weather.pm
Executable file
@ -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 <name> Weather <location> [interval]
|
||||
# define MyWeather Weather "Maintal,HE" 3600
|
||||
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
return "syntax: define <name> Weather <location> [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;
|
@ -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.
|
||||
|
@ -119,7 +119,7 @@ with DEVICEID substituted by the device's ID.
|
||||
<H3>6. USB extenders</H3>
|
||||
|
||||
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).
|
||||
|
@ -73,6 +73,7 @@
|
||||
<a href="#structure">structure</a>
|
||||
<a href="#WS2000">WS2000</a>
|
||||
<a href="#WS300">WS300</a>
|
||||
<a href="#Weather">Weather</a>
|
||||
<a href="#X10">X10</a>
|
||||
<a href="#FHEMRENDERER">FHEMRENDERER</a>
|
||||
|
||||
@ -2186,6 +2187,84 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="Weather"></a>
|
||||
<h3>Weather</h3>
|
||||
<ul>
|
||||
<br>
|
||||
|
||||
<a name="Weather"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> Weather <location> [<interval>]</code><br>
|
||||
<br>
|
||||
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 <i>cpan -i Weather::Google</i> to install it.<br><br>
|
||||
|
||||
A Weather device periodically gathers current and forecast weather conditions
|
||||
from the Google Weather API.<br><br>
|
||||
|
||||
The parameter <code>location</code> is any string that is recognized as a
|
||||
location, either a town name or a zip code. Browse to the URL
|
||||
<code>http://www.google.de/ig/api?weather=location&hl=en</code>
|
||||
to see the raw output for your location.<br><br>
|
||||
|
||||
The parameter <code>interval</code> is the time between subsequent updates
|
||||
in seconds. It defaults to 3600 (1 hour).<br><br>
|
||||
|
||||
Examples:
|
||||
<pre>
|
||||
define MyWeather Weather "Frankfurt,HE"
|
||||
define Forecast Weather "Amsterdam,NL" 1800
|
||||
define weather Weather "30000,France"
|
||||
</pre>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="Weatherset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
||||
<a name="Weatherget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<code>get <name> <reading></code><br><br>
|
||||
|
||||
Valid readings and their meaning (? can be one of 0, 1, 2, 3 and stands
|
||||
for today, tomorrow, ...):<br>
|
||||
<table>
|
||||
<tr><td>city</td><td>name of town returned for location</td></tr>
|
||||
<tr><td>condition</td><td>current condition, one of Sunny, Clear, Partly Cloudy, Mostly Cloudy, Overcast, Chance of Rain</td></tr>
|
||||
<tr><td>current_date_time</td><td>last update of forecast on server</td></tr>
|
||||
<tr><td>fc?_condition</td><td>forecast condition</td></tr>
|
||||
<tr><td>fc?_day_of_week</td><td>day of week for day +?</td></tr>
|
||||
<tr><td>fc?_high_c</td><td>forecasted daily high in degrees centigrade</td></tr>
|
||||
<tr><td>fc?_icon</td><td>relative path for forecast icon, prefix with <code>http://www.google.com</code> to form a valid URL for display in web interfaces</td></tr>
|
||||
<tr><td>fc?_low_c</td><td>forecasted daily low in degrees centigrade</td></tr>
|
||||
<tr><td>humidity</td><td>current humidity</td></tr>
|
||||
<tr><td>icon</td><td>relative path for current icon</td></tr>
|
||||
<tr><td>postal_code</td><td>location sent to server</td></tr>
|
||||
<tr><td>temp_c</td><td>current temperature in degrees centigrade</td></tr>
|
||||
<tr><td>temp_f</td><td>current temperature in degrees Fahrenheit</td></tr>
|
||||
<tr><td>wind_condition</td><td>wind direction and speed</td></tr>
|
||||
</table>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<a name="SCIVT"></a>
|
||||
<h3>SCIVT</h3>
|
||||
<ul>
|
||||
@ -2297,7 +2376,8 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
<code>get <name> counter</code>
|
||||
<br><br>
|
||||
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 <i>then stops</i>.
|
||||
See <a href="#M232Counter">M232Counter</a> for how we care about this.
|
||||
<br><br>
|
||||
</ul>
|
||||
|
||||
@ -2349,6 +2429,10 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
Do not forget to start the counter (with <code>set .. start</code> for
|
||||
M232) or to start the counter and set the reading to a specified value
|
||||
(with <code>set ... value</code> for M232Counter).<br><br>
|
||||
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 <i>basis</i> is adjusted accordingly.
|
||||
<br><br>
|
||||
</ul>
|
||||
|
||||
<a name="M232Counterset"></a>
|
||||
@ -3611,7 +3695,7 @@ isday, sunrise_coord</pre>
|
||||
$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 <a
|
||||
href="#holiday2we>holida2we</a> global attribute is set, $we is 1 for
|
||||
href="#holiday2we">holida2we</a> global attribute is set, $we is 1 for
|
||||
holidays too.
|
||||
Example:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user