# $Id: 98_openweathermap.pm 14102 2017-04-25 10:54:58Z betateilchen $ ############################################################################## # # 98_openweathermap.pm # An FHEM Perl module connecting to www.openweathermap.org (owo) # providing the following tasks: # # 1. send weather data from your own weather station to owo network # # 2. set a wheater station as datasource inside your fhem installation # # 3. retrieve wheather date via owo APII from any weather station # inside owo network # # All tasks can be accessed single or in any desired combination. # Copyright: betateilchen ® # e-mail : fhem.development@betateilchen.de # # This file is part of fhem. # # Fhem is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # Fhem is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with fhem. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## # Changelog: # # 2013-07-28 initial release # # 2013-07-29 fixed: some typos in documentation # added: "set <name> send" # # 2013-07-30 modi: replaced try/catch by eval # added: some more logging # added: delete some station readings before update # added: attribute owoSendUrl # # 2013-08-08 added: proxy support by reading env-Settings # # 2013-08-11 modi: switched from GetLogLevel() to Log3() # fixed: use JSON (due to Fritzbox problems) # # 2013-08-12 added: XML for decoding, controlled by attribute owoUseXml # added: attribute owoProxy for proxy configuration # # 2013-08-13 added: new reading for html response on "send" # added: new reading for html response on "get/set" # 2013-10-12 added: NotifyFn # # 2013-12-08 fixed: first try to remove duplicate processing # # 2014-02-04 added: shutdownFn # # 2014-02-14 modi: changed Loglevel from 3 to 4 where possible # # 2014-03-22 added: added set command 'clear' # package main; use strict; use warnings; use POSIX; use XML::Simple; eval {require JSON}; use feature qw/say switch/; no if $] >= 5.017011, warnings => 'experimental'; require LWP::UserAgent; # test my $ua = LWP::UserAgent->new; # test $ua->timeout(10); # test $ua->env_proxy; # test sub OWO_abs2rel($$$); sub OWO_isday($$); ################################### sub openweathermap_Initialize($) { my ($hash) = @_; $hash->{SetFn} = "OWO_Set"; $hash->{GetFn} = "OWO_Get"; $hash->{DefFn} = "OWO_Define"; $hash->{UndefFn} = "OWO_Undefine"; $hash->{NotifyFn} = "OWO_Notify"; $hash->{AttrFn} = "OWO_Attr"; $hash->{ShutdownFn} = "OWO_Shutdown"; $hash->{AttrList} = "do_not_notify:0,1 ". "owoGetUrl owoSendUrl owoInterval:600,900,1800,3600 ". "owoApiKey owoProxy owoStation owoUser owoUseXml:1,0 ". "owoDebug:0,1 owoRaw:0,1 owoTimestamp:0,1 ". "owoSrc00 owoSrc01 owoSrc02 owoSrc03 owoSrc04 ". "owoSrc05 owoSrc06 owoSrc07 owoSrc08 owoSrc09 ". "owoSrc10 owoSrc11 owoSrc12 owoSrc13 owoSrc14 ". "owoSrc15 owoSrc16 owoSrc17 owoSrc18 owoSrc19 ". $readingFnAttributes; } sub OWO_Shutdown($) { my ($hash) = @_; my $name = $hash->{NAME}; Log3 ($name,4,"owo $name: shutdown requested"); return undef; } sub OWO_Set($@){ my ($hash, @a) = @_; my $name = $hash->{NAME}; my $usage = "Unknown argument, choose one of clear:readings stationById stationByGeo ". "stationByName stationByZip send:noArg"; my $response; return "No Argument given" if(!defined($a[1])); my $urlString = AttrVal($name, "owoGetUrl", undef); return "Please set attribute owoGetUrl!" if(!defined($urlString)); my $cmd = $a[1]; given($cmd){ when("?") { return $usage; } when("clear"){ CommandDeleteReading(undef, "$name _.*"); CommandDeleteReading(undef, "$name c_.*"); CommandDeleteReading(undef, "$name g_.*"); return; } when("send"){ OWO_GetStatus($hash,1); return; } when("stationByName"){ $urlString = $urlString."?q="; my $count; my $element = @a; for ($count = 2; $count < $element; $count++) { $urlString = $urlString."%20".$a[$count]; } } when("stationById"){ $urlString = $urlString."?id=".$a[2]; } when("stationByZip"){ $urlString = $urlString."?zip=".$a[2]; } when("stationByGeo"){ $a[2] = AttrVal("global", "latitude", 0) unless(defined($a[2])); $a[3] = AttrVal("global", "longitude", 0) unless(defined($a[3])); $urlString = $urlString."?lat=$a[2]&lon=$a[3]"; } default: { return $usage; } } UpdateReadings($hash, $urlString, "c_"); return; } sub OWO_Get($@){ my ($hash, @a) = @_; my $name = $hash->{NAME}; my $usage = "Unknown argument, choose one of stationById stationByGeo stationByName stationByZip"; my $response; return "No Argument given" if(!defined($a[1])); my $urlString = AttrVal($name, "owoGetUrl", undef); return "Please set attribute owoGetUrl!" if(!defined($urlString)); my $cmd = $a[1]; given($cmd){ when("?") { return $usage; } when("stationByName"){ $urlString = $urlString."?q="; my $count; my $element = @a; for ($count = 2; $count < $element; $count++) { $urlString = $urlString."%20".$a[$count]; } } when("stationById"){ $urlString = $urlString."?id=".$a[2]; } when("stationByZip"){ $urlString = $urlString."?zip=".$a[2]; } when("stationByGeo"){ $a[2] = AttrVal("global", "latitude", 0) unless(defined($a[2])); $a[3] = AttrVal("global", "longitude", 0) unless(defined($a[3])); $urlString = $urlString."?lat=$a[2]&lon=$a[3]"; } default: { return $usage; } } UpdateReadings($hash, $urlString, "g_"); return; # return $response; } sub OWO_Attr(@){ my @a = @_; my $hash = $defs{$a[1]}; my (undef, $name, $attrName, $attrValue) = @a; given($attrName){ when("owoInterval"){ if($attrValue ne ""){ $attrValue = 600 if($attrValue < 600); $hash->{helper}{INTERVAL} = $attrValue; } else { $hash->{helper}{INTERVAL} = 1800; } $attr{$name}{$attrName} = $attrValue; RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{helper}{INTERVAL}, "OWO_GetStatus", $hash, 0); break; } when("owoProxy"){ if($attrValue ne ""){ $ua->proxy(['http'], $attrValue); } } default { $attr{$name}{$attrName} = $attrValue; } } return ""; } sub OWO_Notify($$) { my ($hash,$dev) = @_; if( grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}) ) { delete $modules{openweathermap}->{NotifyFn}; foreach my $d (keys %defs) { next if($defs{$d}{TYPE} ne "openweathermap"); OWO_GetStatus($hash); } } } sub OWO_GetStatus($;$){ my ($hash, $local) = @_; my $name = $hash->{NAME}; my $htmlDummy; $local = 0 unless(defined($local)); $attr{$name}{"owoInterval"} = 600 if(AttrVal($name,"owoInterval",0) < 600); RemoveInternalTimer($hash); ##### start of send job (own weather data) # # do we have anything to send from our own station? # my ($user, $pass) = split(":", AttrVal($name, "owoUser","")); my $station = AttrVal($name, "owoStation", undef); if(defined($user) && defined($station)){ Log3($name, 3, "owo $name: started: SendData"); my $lat = AttrVal("global", "latitude", ""); my $lon = AttrVal("global", "longitude", ""); my $alt = AttrVal("global", "altitude", ""); my $urlString = AttrVal($name, "owoSendUrl", "http://openweathermap.org/data/post"); my ($p1, $p2) = split("//", $urlString); $urlString = $p1."//$user:$pass\@".$p2; my $dataString = "name=$station&lat=$lat&long=$lon&alt=$alt"; my ($count, $paraName, $paraVal, $p, $s, $v, $o); for ($count = 0; $count < 20; $count++) { $paraName = "owoSrc".sprintf("%02d",$count); $paraVal = AttrVal($name, $paraName, undef); if(defined($paraVal)){ ($p, $s, $v, $o) = split(":", AttrVal($name, $paraName, "")); $o = 0 if(!defined($o)); $v = ReadingsVal($s, $v, 0) + $o; $dataString = $dataString."&$p=$v"; Log3($name, 4, "owo $name: reading: $paraName $p $s $v"); readingsSingleUpdate($hash, "my_".$p, $v, 1); } } $dataString .= "&APPID=".AttrVal($name, "owoApiKey", ""); my $sendString = $urlString."?".$dataString; if(AttrVal($name, "owoDebug",1) == 0){ Log3($name, 4, "owo $name: sending: $dataString"); $htmlDummy = $ua->post($sendString); Log3($name, 3, "owo $name: htmlResponse: ".$htmlDummy->status_line); } else { Log3($name, 3, "owo $name: debug: $dataString"); } readingsBeginUpdate($hash); readingsBulkUpdate($hash, "_httpResponse_my", $htmlDummy->status_line) if $htmlDummy; readingsBulkUpdate($hash, "my_response", $htmlDummy->decoded_content) if $htmlDummy; readingsBulkUpdate($hash, "state","active"); if(AttrVal($name, "owoTimestamp", 0) == 1){ readingsBulkUpdate($hash, "my_lastSent", time); } else { readingsBulkUpdate($hash, "my_lastSent", localtime(time)); } readingsEndUpdate($hash, 1); if(defined($htmlDummy)){ CommandDeleteReading(undef, "$name my_.*") if $htmlDummy->is_error; } } ##### end of send job ##### start of update job (set station) # # Do we already have a stationId set? # If yes => update this station # my $cId = ReadingsVal($name,"c_stationId", undef); if(defined($cId)){ my $cName = ReadingsVal($name,"stationName", ""); Log3($name, 4, "owo $name: retrievingStationData: Id: $cId Name: $cName"); fhem("set $name stationById $cId"); } ##### end of update job InternalTimer(gettimeofday()+$hash->{helper}{INTERVAL}, "OWO_GetStatus", $hash, 0) unless($local == 1); return; } sub OWO_Define($$){ my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); my $name = $hash->{NAME}; $hash->{helper}{INTERVAL} = 1800; $hash->{helper}{AVAILABLE} = 1; $attr{$name}{"owoDebug"} = 1; $attr{$name}{"owoUseXml"} = 1; $attr{$name}{"owoInterval"} = 1800; $attr{$name}{"owoGetUrl"} = "http://api.openweathermap.org/data/2.5/weather"; $attr{$name}{"owoSendUrl"} = "http://openweathermap.org/data/post"; if( $init_done ) { delete $modules{openweathermap}->{NotifyFn}; OWO_GetStatus($hash); } else { readingsSingleUpdate($hash, "state", "defined",1); } # readingsSingleUpdate($hash, "state","defined",1); # InternalTimer(gettimeofday()+$hash->{helper}{INTERVAL}, "OWO_GetStatus", $hash, 0); Log3($name, 4, "owo $name: created"); return; } sub OWO_Undefine($$){ my($hash, $name) = @_; RemoveInternalTimer($hash); return undef; } sub UpdateReadings($$$){ my ($hash, $url, $prefix) = @_; my $name = $hash->{NAME}; my ($jsonWeather, $response); my $xmlMode = AttrVal($name, "owoUseXml", ""); $url .= "&mode=xml" if($xmlMode eq "1"); $url .= "&APPID=".AttrVal($name, "owoApiKey", ""); eval {$response = $ua->get("$url")}; # # error handling for not found stations (error 404 from server) # if($response->decoded_content =~ m/error/i){ CommandDeleteReading(undef, "$name $prefix.*"); readingsSingleUpdate($hash, "_httpResponse_".substr($prefix,0,1), $response->decoded_content, 1); return; } if(defined($response)){ if(AttrVal($name, "owoDebug", 1) == 1){ Log3($name, 4, "owo $name: response:\n".$response->decoded_content); } } else { Log3($name, 4, "owo $name: error: no response from server"); return; } CommandDeleteReading(undef, "$name $prefix.*"); readingsSingleUpdate($hash, "_httpResponse_".substr($prefix,0,1), $response->status_line, 1); if($xmlMode eq "1" && $response->is_success){ Log3($name, 4, "owo $name: decoding XML"); my $xml = new XML::Simple; $jsonWeather = undef; $jsonWeather = $xml->XMLin($response->decoded_content, KeyAttr => 'current' ); if(defined($jsonWeather)){ readingsBeginUpdate($hash); if(AttrVal($name, "owoRaw", 0) == 1){ readingsBulkUpdate($hash, $prefix."rawData", $response->decoded_content); } readingsBulkUpdate($hash, "_dataSource", "www.openweathermap.org"); readingsBulkUpdate($hash, "_decodedWith", "XML"); readingsBulkUpdate($hash, $prefix."lastWx", $jsonWeather->{lastupdate}{value}); readingsBulkUpdate($hash, $prefix."sunrise", $jsonWeather->{city}{sun}{rise}); readingsBulkUpdate($hash, $prefix."sunset", $jsonWeather->{city}{sun}{set}); readingsBulkUpdate($hash, $prefix."stationId", $jsonWeather->{city}{id}); readingsBulkUpdate($hash, $prefix."stationName", utf8ToLatin1($jsonWeather->{city}{name})); readingsBulkUpdate($hash, $prefix."stationCountry", $jsonWeather->{city}{country}); readingsBulkUpdate($hash, $prefix."stationLat", sprintf("%.4f",$jsonWeather->{city}{coord}{lat})); readingsBulkUpdate($hash, $prefix."stationLon", sprintf("%.4f",$jsonWeather->{city}{coord}{lon})); readingsBulkUpdate($hash, $prefix."temperature", sprintf("%.1f",$jsonWeather->{temperature}{value}-273.15)); readingsBulkUpdate($hash, $prefix."tempMin", sprintf("%.1f",$jsonWeather->{temperature}{min}-273.15)); readingsBulkUpdate($hash, $prefix."tempMax", sprintf("%.1f",$jsonWeather->{temperature}{max}-273.15)); readingsBulkUpdate($hash, $prefix."humidity", $jsonWeather->{humidity}{value}); readingsBulkUpdate($hash, $prefix."pressure", $jsonWeather->{pressure}{value}); # readingsBulkUpdate($hash, $prefix."pressureRel", $jsonWeather->{main}{sea_level}); readingsBulkUpdate($hash, $prefix."windSpeed", $jsonWeather->{wind}{speed}{value}); readingsBulkUpdate($hash, $prefix."windDir", $jsonWeather->{wind}{direction}{value}); readingsBulkUpdate($hash, $prefix."clouds", $jsonWeather->{clouds}{value}); readingsBulkUpdate($hash, $prefix."rain3h", $jsonWeather->{rain}{"3h"}); readingsBulkUpdate($hash, $prefix."snow3h", $jsonWeather->{snow}{"3h"}); readingsBulkUpdate($hash, "state", "active"); readingsEndUpdate($hash, 1); } else { Log3($name, 2, "owo $name error: update not possible!"); } } if($xmlMode ne "1" && $response->is_success){ Log3($name, 4, "owo $name: decoding JSON"); my $json = JSON->new->allow_nonref; eval {$jsonWeather = $json->decode($response->decoded_content)}; warn $@ if $@; if(defined($jsonWeather)){ readingsBeginUpdate($hash); if(AttrVal($name, "owoRaw", 0) == 1){ readingsBulkUpdate($hash, $prefix."rawData", $response->decoded_content); } if(AttrVal($name, "owoTimestamp", 0) == 1){ readingsBulkUpdate($hash, $prefix."lastWx", $jsonWeather->{dt}); readingsBulkUpdate($hash, $prefix."sunrise", $jsonWeather->{sys}{sunrise}); readingsBulkUpdate($hash, $prefix."sunset", $jsonWeather->{sys}{sunset}); } else { readingsBulkUpdate($hash, $prefix."lastWx", localtime($jsonWeather->{dt})); readingsBulkUpdate($hash, $prefix."sunrise", localtime($jsonWeather->{sys}{sunrise})); readingsBulkUpdate($hash, $prefix."sunset", localtime($jsonWeather->{sys}{sunset})); } readingsBulkUpdate($hash, "_dataSource", "www.openweathermap.org"); readingsBulkUpdate($hash, "_decodedWith", "JSON"); readingsBulkUpdate($hash, $prefix."stationId", $jsonWeather->{id}); readingsBulkUpdate($hash, $prefix."lastRxCode", $jsonWeather->{cod}); readingsBulkUpdate($hash, $prefix."stationName", utf8ToLatin1($jsonWeather->{name})); readingsBulkUpdate($hash, $prefix."humidity", $jsonWeather->{main}{humidity}); readingsBulkUpdate($hash, $prefix."pressureAbs", $jsonWeather->{main}{pressure}); readingsBulkUpdate($hash, $prefix."pressureRel", $jsonWeather->{main}{sea_level}); readingsBulkUpdate($hash, $prefix."windSpeed", $jsonWeather->{wind}{speed}); readingsBulkUpdate($hash, $prefix."windDir", $jsonWeather->{wind}{deg}); readingsBulkUpdate($hash, $prefix."clouds", $jsonWeather->{clouds}{all}); readingsBulkUpdate($hash, $prefix."rain3h", $jsonWeather->{rain}{"3h"}); readingsBulkUpdate($hash, $prefix."snow3h", $jsonWeather->{snow}{"3h"}); readingsBulkUpdate($hash, $prefix."stationLat", sprintf("%.4f",$jsonWeather->{coord}{lat})); readingsBulkUpdate($hash, $prefix."stationLon", sprintf("%.4f",$jsonWeather->{coord}{lon})); readingsBulkUpdate($hash, $prefix."temperature", sprintf("%.1f",$jsonWeather->{main}{temp}-273.15)); readingsBulkUpdate($hash, $prefix."tempMin", sprintf("%.1f",$jsonWeather->{main}{temp_min}-273.15)); readingsBulkUpdate($hash, $prefix."tempMax", sprintf("%.1f",$jsonWeather->{main}{temp_max}-273.15)); readingsBulkUpdate($hash, "state", "active"); readingsEndUpdate($hash, 1); } else { Log3($name, 2, "owo $name error: update not possible!"); } } return; } sub OWO_abs2rel($$$){ # Messwerte my $Pa = $_[0]; my $Temp = $_[1]; my $Alti = $_[2]; # Konstanten my $g0 = 9.80665; my $R = 287.05; my $T = 273.15; my $Ch = 0.12; my $a = 0.065; my $E = 0; if($Temp < 9.1) { $E = 5.6402*(-0.0916 + exp(0.06 * $Temp)); } else { $E = 18.2194*(1.0463 - exp(-0.0666 * $Temp)); } my $xp = $Alti * $g0 / ($R*($T+$Temp + $Ch*$E + $a*$Alti/2)); my $Pr = $Pa*exp($xp); return int($Pr); } sub OWO_isday($$){ my $name = $_[0]; my $src = $_[1]; my $response; if(AttrVal($name, "owoTimestamp",0)){ $response = (time > ReadingsVal($name, $src."_sunrise", 0) && time < ReadingsVal($name, $src."_sunset", 0) ? "1" : "0"); } else { $response = "Attribute owoTimestamp not set to 1!"; } return $response; } # OpenWeatherMap API parameters # ----------------------------- # 01 wind_dir - wind direction, grad # 02 wind_speed - wind speed, mps # 03 temp - temperature, grad C # 04 humidity - relative humidity, % # 05 pressure - atmosphere pressure # 06 wind_gust - speed of wind gust, mps # 07 rain_1h - rain in recent hour, mm # 08 rain_24h - rain in recent 24 hours, mm # 09 rain_today - rain today, mm # 10 snow - snow in recent 24 hours, mm # 11 lum - illumination, W/M² # 12 radiation - radiation # 13 dewpoint - dewpoint # 14 uv - UV index # name - station name # lat - latitude # long - longitude # alt - altitude, m 1; =pod not to be translated =begin html <a name="openweathermap"></a> <h3>openweathermap</h3> <ul> <b>Prerequisits</b> <ul> <br/> <li>Module uses following additional Perl modules:<br/><br/> <code>XML::Simple, JSON</code><br/><br/> If not already installed in your environment, please install them using appropriate commands from your environment.<br/> Use of JSON is optional. You can activate it by setting attribute owoUseXml to 0</li><br/> <li>please check global attributes latitude, longitude and altitude are set correctly</li> <li>you can use all task alone, in any combination or all together</li> </ul> <br/><br/> <a name="openweathermapdefine"></a> <b>Define</b> <ul> <br/> <code>define <name> openweathermap</code> <br/><br/> This module provides connection to openweathermap-network www.openweathermap.org (owo)<br/> You can use this module to do three different tasks:<br/> <br/> <ul> <li>1. send weather data from your own weather station to owo network.</li> <li>2. set any weather data in owo network as datasource for your fhem installation. Data from this station will be updated periodically.</li> <li>3. retrieve weather data from any weather station in owo network once. (same as 2. but without update)</li> </ul> <br/> Example:<br/> <br/> <ul><code>define owo openweathermap</code></ul> </ul> <br/><br/> <b>Configuration of your owo tasks</b><br/><br/> <ul> <a name="owoconfiguration1"></a> <li>1. providing your own weather data to owo network</li> <br/> <ul><code> define owo openweathermap<br/> attr owo owoUser myuser:mypassword<br/> attr owo owoStation myStationName<br/> attr owo owoInterval 600<br/> attr owo owoSrc00 temp:sensorname:temperature<br/> </code></ul><br/> <a name="owoconfiguration2"></a> <li>2. set a weather station from owo network as data source for your fhem installation</li> <br/> <ul><code> set owo stationByName Leimen <br/><br/> set owo stationById 2879241 <br/><br/> set owo stationByGeo 49.3511 8.6894 </code></ul> <br/><br/> <ul> <li>All commands will retrieve weather data for Leimen (near Heidelberg,DE)</li> <li>Readings will be updated periodically, based on value of owoInterval.</li> <li>If lat and lon value in stationByGeo are omitted, the corresponding values from global attributes are used.</li> <li>All readings will use prefix "c_"</li> </ul> <br/> <a name="owoconfiguration3"></a> <li>3. get weather data from a selected weather station once (e.g. to do own presentations)</li> <br/> <ul><code> get owo stationByName Leimen <br/><br/> get owo stationById 2879241 <br/><br/> get owo stationByGeo 49.3511 8.6894 </code></ul> <br/><br/> <ul> <li>All commands will retrieve weather data for Leimen (near Heidelberg,DE) once.</li> <li>Readings will not be updated periodically.</li> <li>If lat and lon value in stationByGeo are omitted, the corresponding values from global attributes are used.</li> <li>All readings will use prefix "g_"</li> </ul> <br/> </ul> <br/><br/> <a name="openweathermapset"></a> <b>Set-Commands</b><br/> <ul> <br/> <code>set <name> clear</code><br/> <br/> <ul>Delete all readings for cleanup</ul> <br/><br/> <code>set <name> send</code><br/> <br/> <ul>start an update cycle manually: <ul> <li>send own data</li> <li>update c_* readings from "set" station (if defined)</li> <br/> <li>does not affect or re-trigger running timer cycles!</li> <li>main purpose: for debugging and testing</li> </ul> </ul> <br/><br/> <code>set <name> <stationById stationId>|<stationByName stationName>|<stationByGeo> [lat lon]>|<stationByZip stationZipCode></code> <br/><br/> <ul>see description above: <a href="#owoconfiguration2">Configuration task 2</a></ul> <br/><br/> </ul> <br/><br/> <a name="openweathermapget"></a> <b>Get-Commands</b><br/> <ul> <br/> <code>get <name> <stationById stationId>|<stationByName stationName>|<stationByGeo> [lat lon]>|<stationByZip stationZipCode></code> <br/><br/> <ul>see description above: <a href="#owoconfiguration3">Configuration task 3</a></ul> <br/> Used exactly as the "set" command, but with two differences:<br/><br/> <ul> <li>all generated readings use prefix "g_" instead of "c_"</li> <li>readings will not be updated automatically</li> </ul> </ul> <br/><br/> <a name="openweathermapattr"></a> <b>Attributes</b><br/><br/> <ul> <li><a href="#do_not_notify">do_not_notify</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li> <br/> <li><b>owoApiKey</b></li> <yourOpenweathermapApiKey> - find it in your owo account! If set, it will be used in all owo requests.<br/> <li><b>owoDebug</b></li> <0|1> this attribute <b>must be defined and set to 0</b> to start sending own weather data to owo network. Otherwise you can find all data as debug informations in logfile.<br/> <li><b>owoGetUrl</b></li> <owoApiUrl> - current URL to owo api. If this url changes, you can correct it here unless updated version of 98_openweather becomes available.<br/> <li><b>owoInterval</b></li> <intervalSeconds> - define the interval used for sending own weather data and for updating SET station. Default = 1800sec. If deleted, default will be used.<br/> <b>Please do not set interval below 600 seconds! This regulation is defined by openweathermap.org.</b><br/> Values below 600 will be corrected to 600.<br/> <li><b>owoProxy</b></li> <proxyAddress> - define a proxy server address, please give full url and port, e.g. http://192.168.111.222:8080<br/> <li><b>owoStation</b></li> <yourStationName> - define the station name to be used in "my stats" in owo account<br/> <li><b>owoUser</b></li> <user:password> - define your username and password for owo access here<br/> <li><b>owoRaw</b></li> <0|1> - defines wether JSON date from owo will be shown in an additional reading (e.g. to use it for own presentations)<br/> <li><b>owoSendUrl</b></li> Current URL to post your own data. If this url changes, you can correct it here unless updated version of 98_openweather becomes available.<br/> <li><b>owoTimestamp</b></li> <0|1> - defines whether date/time readings show timestamps or localtime-formatted informations<br/> <li><b>owoSrc00 ... owoSrc19</b></li> Each of this attributes contains information about weather data to be sent in format <code>owoParam:sensorName:readingName:offset</code><br/> Example: <code>attr owo owoSrc00 temp:outside:temperature</code> will define an attribut owoSrc00, and <br/> reading "temperature" from device "outside" will be sent to owo network als paramater "temp" (which indicates current temperature)<br/> Parameter "offset" will be added to the read value (e.g. necessary to send dewpoint - use offset 273.15 to send correct value) <li><b>owoUseXml</b></li> <0|1> - defines wether data must be decoded from XML, e.g. JSON not available on Fritzbox<br/> </ul> <br/><br/> <b>Generated Readings/Events:</b><br/><br/> <ul> <li><b>state</b> - current device state (defined|active)</li> <li><b>c_<readingName></b> - weather data from SET weather station. Readings will be updated periodically</li> <li><b>g_<readingName></b> - weather data from GET command. Readings will NOT be updated periodically</li> <li><b>my_lastSent</b> - time of last upload to owo network</li> <li><b>my_<readingName></b> - all readings from own weather station. These readings will be sent to owo network.</li> </ul> <br/><br/> <b>Author's notes</b><br/><br/> <ul> <li>further informations about sending your own weather data to owo: <a href="http://openweathermap.org/stations">Link</a></li> <li>further informations about owo location search: <a href="http://openweathermap.org/API">Link</a></li> <li>further informations about owo weather data: <a href="http://bugs.openweathermap.org/projects/api/wiki/Weather_Data">Link</a></li> </ul> </ul> =end html =begin html_DE <a name="openweathermap"></a> <h3>openweathermap</h3> <ul> Sorry, keine deutsche Dokumentation vorhanden.<br/><br/> Die englische Doku gibt es hier: <a href='http://fhem.de/commandref.html#openweathermap'>openweathermap</a><br/> </ul> =end html_DE =cut