mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +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
|
- bugfix: sunrise stuff fixed, doc missing
|
||||||
- feature: CUL FHT sending added
|
- feature: CUL FHT sending added
|
||||||
- bugfix: workaround to make M232 counter wraparound
|
- 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)
|
- Sun May 31 2009 (Boris)
|
||||||
- 81_M232Counter.pm: counter stops at 65536; workaround makes counter wraparound
|
- 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>
|
<H3>6. USB extenders</H3>
|
||||||
|
|
||||||
To increase the maximum cable length from 5 meters to 10 meters, so-called
|
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
|
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
|
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).
|
or put an active (self-powered) hub in the middle (unconfirmed).
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
<a href="#structure">structure</a>
|
<a href="#structure">structure</a>
|
||||||
<a href="#WS2000">WS2000</a>
|
<a href="#WS2000">WS2000</a>
|
||||||
<a href="#WS300">WS300</a>
|
<a href="#WS300">WS300</a>
|
||||||
|
<a href="#Weather">Weather</a>
|
||||||
<a href="#X10">X10</a>
|
<a href="#X10">X10</a>
|
||||||
<a href="#FHEMRENDERER">FHEMRENDERER</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>
|
</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>
|
<a name="SCIVT"></a>
|
||||||
<h3>SCIVT</h3>
|
<h3>SCIVT</h3>
|
||||||
<ul>
|
<ul>
|
||||||
@ -2297,7 +2376,8 @@ A line ending with \ will be concatenated with the next one, so long lines
|
|||||||
<code>get <name> counter</code>
|
<code>get <name> counter</code>
|
||||||
<br><br>
|
<br><br>
|
||||||
Gets the number of ticks of the counter since the last reset. The 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 <i>then stops</i>.
|
||||||
|
See <a href="#M232Counter">M232Counter</a> for how we care about this.
|
||||||
<br><br>
|
<br><br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -2348,7 +2428,11 @@ A line ending with \ will be concatenated with the next one, so long lines
|
|||||||
<br>
|
<br>
|
||||||
Do not forget to start the counter (with <code>set .. start</code> for
|
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
|
M232) or to start the counter and set the reading to a specified value
|
||||||
(with <code>set ... value</code> for M232Counter). <br><br>
|
(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>
|
</ul>
|
||||||
|
|
||||||
<a name="M232Counterset"></a>
|
<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
|
$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
|
one would normally expect). Additionally $we is 1 if it is weekend (i.e
|
||||||
$wday == 0 || $wday == 6), and 0 otherwise. If the <a
|
$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.
|
holidays too.
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user