diff --git a/fhem/CHANGED b/fhem/CHANGED
index 2b9e61152..bd06f1f14 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.
+ - new: 59_WUup: first release (Forum #65587)
- feature: 49_SSCam: V2.6.3, snapGallery can be triggered by e.g. notify
- bugfix: 93_DbLog: V2.22.3, Forum:#74690, unitialized message in row ...
- feature: 34_ESPEasy: reject non local IPs wo/ basic auth
diff --git a/fhem/FHEM/59_WUup.pm b/fhem/FHEM/59_WUup.pm
new file mode 100644
index 000000000..554230408
--- /dev/null
+++ b/fhem/FHEM/59_WUup.pm
@@ -0,0 +1,532 @@
+# $Id$
+################################################################################
+# 59_WUup.pm
+#
+# Copyright: mahowi
+# e-mail: mahowi@gmx.net
+#
+# Based on 55_weco.pm by betateilchen
+#
+# 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 .
+#
+################################################################################
+
+package main;
+
+use strict;
+use warnings;
+use Time::HiRes qw(gettimeofday);
+use HttpUtils;
+use UConv;
+
+my $version = "0.9.2";
+
+# Declare functions
+sub WUup_Initialize($);
+sub WUup_Define($$$);
+sub WUup_Undef($$);
+sub WUup_Attr(@);
+sub WUup_stateRequestTimer($);
+sub WUup_send($);
+sub WUup_receive($);
+
+################################################################################
+#
+# Main routines
+#
+################################################################################
+
+sub WUup_Initialize($) {
+ my ($hash) = @_;
+
+ $hash->{DefFn} = "WUup_Define";
+ $hash->{UndefFn} = "WUup_Undef";
+ $hash->{AttrFn} = "WUup_Attr";
+ $hash->{AttrList} =
+ "disable:1 "
+ . "disabledForIntervals "
+ . "interval "
+ . "unit_windspeed:km/h,m/s "
+ . "wuwinddir wuwindspeedmph wuwindgustmph wuwindgustdir wuwinddir_avg2m "
+ . "wuwinddir_avg2m wuwindgustmph_10m wuwindgustdir_10m wuhumidity "
+ . "wusoilmoisture wudewptf wutempf wurainin wudailyrainin wubaromin "
+ . "wusoiltempf wusolarradiation wuUV "
+ . $readingFnAttributes;
+ $hash->{VERSION} = $version;
+}
+
+sub WUup_Define($$$) {
+ my ( $hash, $def ) = @_;
+ my @a = split( "[ \t][ \t]*", $def );
+
+ return "syntax: define WUup "
+ if ( int(@a) != 4 );
+
+ my $name = $hash->{NAME};
+
+ $hash->{VERSION} = $version;
+ $hash->{INTERVAL} = 300;
+
+ $hash->{helper}{stationid} = $a[2];
+ $hash->{helper}{password} = $a[3];
+ $hash->{helper}{softwaretype} = 'FHEM';
+ $hash->{helper}{url} =
+"https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php";
+ $hash->{helper}{url_rf} =
+"https://rtupdate.wunderground.com/weatherstation/updateweatherstation.php";
+
+ readingsSingleUpdate( $hash, "state", "defined", 1 );
+
+ $attr{$name}{room} = "Weather" if ( !defined( $attr{$name}{room} ) );
+ $attr{$name}{unit_windspeed} = "km/h"
+ if ( !defined( $attr{$name}{unit_windspeed} ) );
+
+ RemoveInternalTimer($hash);
+
+ if ($init_done) {
+ WUup_stateRequestTimer($hash);
+ }
+ else {
+ InternalTimer( gettimeofday(), "WUup_stateRequestTimer", $hash, 0 );
+ }
+
+ Log3 $name, 3, "WUup ($name): defined";
+
+ return undef;
+}
+
+sub WUup_Undef($$) {
+ my ( $hash, $arg ) = @_;
+ RemoveInternalTimer($hash);
+ return undef;
+}
+
+sub WUup_Attr(@) {
+ my ( $cmd, $name, $attrName, $attrVal ) = @_;
+ my $hash = $defs{$name};
+
+ if ( $attrName eq "disable" ) {
+ if ( $cmd eq "set" and $attrVal eq "1" ) {
+ readingsSingleUpdate( $hash, "state", "disabled", 1 );
+ Log3 $name, 3, "WUup ($name) - disabled";
+ }
+
+ elsif ( $cmd eq "del" ) {
+ readingsSingleUpdate( $hash, "state", "active", 1 );
+ Log3 $name, 3, "WUup ($name) - enabled";
+ }
+ }
+
+ if ( $attrName eq "disabledForIntervals" ) {
+ if ( $cmd eq "set" ) {
+ readingsSingleUpdate( $hash, "state", "unknown", 1 );
+ Log3 $name, 3, "WUup ($name) - disabledForIntervals";
+ }
+
+ elsif ( $cmd eq "del" ) {
+ readingsSingleUpdate( $hash, "state", "active", 1 );
+ Log3 $name, 3, "WUup ($name) - enabled";
+ }
+ }
+
+ if ( $attrName eq "interval" ) {
+ if ( $cmd eq "set" ) {
+ if ( $attrVal < 3 ) {
+ Log3 $name, 1,
+"WUup ($name) - interval too small, please use something >= 3 (sec), default is 300 (sec).";
+ return
+"interval too small, please use something >= 3 (sec), default is 300 (sec)";
+ }
+ else {
+ $hash->{INTERVAL} = $attrVal;
+ Log3 $name, 4, "WUup ($name) - set interval to $attrVal";
+ }
+ }
+
+ elsif ( $cmd eq "del" ) {
+ $hash->{INTERVAL} = 300;
+ Log3 $name, 4, "WUup ($name) - set interval to default";
+ }
+ }
+
+ return undef;
+}
+
+sub WUup_stateRequestTimer($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+
+ if ( !IsDisabled($name) ) {
+ readingsSingleUpdate( $hash, "state", "active", 1 )
+ if (
+ (
+ ReadingsVal( $name, "state", 0 ) eq "defined"
+ or ReadingsVal( $name, "state", 0 ) eq "disabled"
+ or ReadingsVal( $name, "state", 0 ) eq "Unknown"
+ )
+ );
+
+ WUup_send($hash);
+
+ }
+ else {
+ readingsSingleUpdate( $hash, "state", "disabled", 1 );
+ }
+
+ InternalTimer( gettimeofday() + $hash->{INTERVAL},
+ "WUup_stateRequestTimer", $hash, 1 );
+
+ Log3 $name, 5,
+ "Sub WUup_stateRequestTimer ($name) - Request Timer is called";
+}
+
+sub WUup_send($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+ my $version = $hash->{VERSION};
+ my $url = "";
+ if ( $hash->{INTERVAL} < 300 ) {
+ $url = $hash->{helper}{url_rf};
+ }
+ else {
+ $url = $hash->{helper}{url};
+ }
+ $url .= "?ID=" . $hash->{helper}{stationid};
+ $url .= "&PASSWORD=" . $hash->{helper}{password};
+ my $datestring = strftime "%F+%T", gmtime;
+ $datestring =~ s/:/%3A/g;
+ $url .= "&dateutc=" . $datestring;
+
+ $attr{$name}{unit_windspeed} = "km/h"
+ if ( !defined( $attr{$name}{unit_windspeed} ) );
+
+ my ( $data, $d, $r, $o );
+ my $a = $attr{$name};
+ while ( my ( $key, $value ) = each(%$a) ) {
+ next if substr( $key, 0, 2 ) ne 'wu';
+ $key = substr( $key, 2, length($key) - 2 );
+ ( $d, $r, $o ) = split( ":", $value );
+ if ( defined($r) ) {
+ $o = ( defined($o) ) ? $o : 0;
+ $value = ReadingsVal( $d, $r, 0 ) + $o;
+ }
+ if ( $key =~ /\w+f$/ ) {
+ $value = UConv::c2f( $value, 4 );
+ }
+ elsif ( $key =~ /\w+mph.*/ ) {
+
+ if ( $attr{$name}{unit_windspeed} eq "m/s" ) {
+ Log3 $name, 5, "WUup ($name) - windspeed unit is m/s";
+ $value = UConv::kph2mph( ( UConv::mps2kph( $value, 4 ) ), 4 );
+ }
+ else {
+ Log3 $name, 5, "WUup ($name) - windspeed unit is km/h";
+ $value = UConv::kph2mph( $value, 4 );
+ }
+ }
+ elsif ( $key eq "baromin" ) {
+ $value = UConv::hpa2inhg( $value, 4 );
+ }
+ elsif ( $key =~ /.*rainin$/ ) {
+ $value = UConv::mm2in( $value, 4 );
+ }
+ $data .= "&$key=$value";
+ }
+
+ readingsBeginUpdate($hash);
+ if ( defined($data) ) {
+ readingsBulkUpdate( $hash, "data", $data );
+ Log3 $name, 4, "WUup ($name) - data sent: $data";
+ $url .= $data;
+ $url .= "&softwaretype=" . $hash->{helper}{softwaretype};
+ $url .= "&action=updateraw";
+ if ( $hash->{INTERVAL} < 300 ) {
+ $url .= "&realtime=1&rtfreq=" . $hash->{INTERVAL};
+ }
+ my $param = {
+ url => $url,
+ timeout => 4,
+ hash => $hash,
+ method => "GET",
+ header =>
+ "agent: FHEM-WUup/$version\r\nUser-Agent: FHEM-WUup/$version",
+ callback => \&WUup_receive
+ };
+
+ Log3 $name, 5, "WUup ($name) - full URL: $url";
+ HttpUtils_NonblockingGet($param);
+
+ # my $response = GetFileFromURL($url);
+ # readingsBulkUpdate( $hash, "response", $response );
+ # Log3 $name, 4, "WUup ($name) - server response: $response";
+ }
+ else {
+ CommandDeleteReading( undef, "$name data" );
+ CommandDeleteReading( undef, "$name response" );
+ Log3 $name, 3, "WUup ($name) - no data";
+ readingsBulkUpdate( $hash, "state", "defined" );
+
+ }
+ readingsEndUpdate( $hash, 1 );
+
+ return;
+}
+
+sub WUup_receive($) {
+ my ( $param, $err, $data ) = @_;
+ my $hash = $param->{hash};
+ my $name = $hash->{NAME};
+
+ if ( $err ne "" ) {
+ Log3 $name, 3,
+ "WUup ($name) - error while requesting " . $param->{url} . " - $err";
+ readingsSingleUpdate( $hash, "state", "ERROR", undef );
+ readingsSingleUpdate( $hash, "response", $err, undef );
+ }
+ elsif ( $data ne "" ) {
+ Log3 $name, 4, "WUup ($name) - server response: $data";
+ readingsSingleUpdate( $hash, "response", $data, undef );
+ }
+}
+
+1;
+
+################################################################################
+#
+# Documentation
+#
+################################################################################
+#
+# Changelog:
+#
+# 2017-01-23 initial release
+# 2017-02-10 added german docu
+# 2017-02-22 fixed bug when module cannot get reenabled after disabling
+# added disabledForIntervals
+# changed attribute WUInterval to interval
+# default interval 300
+# 2017-02-23 added attribute unit_windspeed
+# converted units rounded to 4 decimal places
+# 2017-03-16 implemented non-blocking mode
+# 2017-08-16 integrated RapidFire mode (thanks to Scooty66)
+#
+################################################################################
+
+=pod
+=item helper
+=item summary sends weather data to Weather Underground
+=item summary_DE sendet Wetterdaten zu Weather Underground
+=begin html
+
+
+WUup
+
+
+
+ Define
+
+
+
+ define <name> WUup <stationId> <password>
+
+ This module provides connection to
+ www.wunderground.com
+ to send data from your own weather station.
+
+
+
+
+
+ Set-Commands
+
+
+ - not implemented -
+
+
+
+
+ Get-Commands
+
+
+ - not implemented -
+
+
+
+
+ Attributes
+
+ - readingFnAttributes
+ - interval - Interval (seconds) to send data to
+ www.wunderground.com.
+ Will be adjusted to 300 (which is the default) if set to a value lower than 3.
+ If lower than 300, RapidFire mode will be used.
+ - disable - disables the module
+ - disabledForIntervals
+ - unit_windspeed - change the units of your windspeed readings (m/s or km/h)
+ - wu.... - Attribute name corresponding to
+parameter name from api.
+ Each of these attributes contains information about weather data to be sent
+ in format
sensorName:readingName
+ Example: attr WUup wutempf outside:temperature
will
+ define the attribute wutempf and
+ reading "temperature" from device "outside" will be sent to
+ network as parameter "tempf" (which indicates current temperature)
+
+ Units get converted to angloamerican system automatically
+ (°C -> °F; km/h(m/s) -> mph; mm -> in; hPa -> inHg)
+ The following information is supported:
+
+ - winddir - [0-360 instantaneous wind direction]
+ - windspeedmph - [mph instantaneous wind speed]
+ - windgustmph - [mph current wind gust, using software specific time period]
+ - windgustdir - [0-360 using software specific time period]
+ - windspdmph_avg2m - [mph 2 minute average wind speed mph]
+ - winddir_avg2m - [0-360 2 minute average wind direction]
+ - windgustmph_10m - [mph past 10 minutes wind gust mph]
+ - windgustdir_10m - [0-360 past 10 minutes wind gust direction]
+ - humidity - [% outdoor humidity 0-100%]
+ - dewptf- [F outdoor dewpoint F]
+ - tempf - [F outdoor temperature]
+ - rainin - [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
+ - dailyrainin - [rain inches so far today in local time]
+ - baromin - [barometric pressure inches]
+ - soiltempf - [F soil temperature]
+ - soilmoisture - [%]
+ - solarradiation - [W/m²]
+ - UV - [index]
+
+
+
+
+
+ Readings/Events:
+
+
+ - data - data string transmitted to www.wunderground.com
+ - response - response string received from server
+
+
+
+ Notes
+
+ - Find complete api description
+here
+ - Have fun!
+
+
+
+
+=end html
+=begin html_DE
+
+
+WUup
+
+
+
+ Define
+
+
+
+ define <name> WUup <stationId> <password>
+
+ Dieses Modul stellt eine Verbindung zu www.wunderground.com
+ her, um Daten einer eigenen Wetterstation zu versenden..
+
+
+
+
+
+ Set-Befehle
+
+
+
+
+ Get-Befehle
+
+
+
+
+ Attribute
+
+ - readingFnAttributes
+ - interval - Sendeinterval in Sekunden. Wird auf 300 (Default-Wert)
+ eingestellt, wenn der Wert kleiner als 3 ist.
+ Wenn der Wert kleiner als 300 ist, wird der RapidFire Modus verwendet.
+ - disable - deaktiviert das Modul
+ - disabledForIntervals
+ - unit_windspeed - gibt die Einheit der Readings für die
+ Windgeschwindigkeiten an (m/s oder km/h)
+ - wu.... - Attributname entsprechend dem
+Parameternamen aus der API.
+ Jedes dieser Attribute enthält Informationen über zu sendende Wetterdaten
+ im Format sensorName:readingName
.
+ Beispiel: attr WUup wutempf outside:temperature
definiert
+ das Attribut wutempf und sendet das Reading "temperature" vom Gerät "outside" als Parameter "tempf"
+ (welches die aktuelle Temperatur angibt).
+
+ Einheiten werden automatisch ins anglo-amerikanische System umgerechnet.
+ (°C -> °F; km/h(m/s) -> mph; mm -> in; hPa -> inHg)
+ Unterstützte Angaben
+
+ - Winddir - [0-360 momentane Windrichtung]
+ - Windspeedmph - [mph momentane Windgeschwindigkeit]
+ - Windgustmph - [mph aktuellen Böe, mit Software-spezifischem Zeitraum]
+ - Windgustdir - [0-360 mit Software-spezifischer Zeit]
+ - Windspdmph_avg2m - [mph durchschnittliche Windgeschwindigkeit innerhalb 2 Minuten]
+ - Winddir_avg2m - [0-360 durchschnittliche Windrichtung innerhalb 2 Minuten]
+ - Windgustmph_10m - [mph Böen der vergangenen 10 Minuten]
+ - Windgustdir_10m - [0-360 Richtung der Böen der letzten 10 Minuten]
+ - Feuchtigkeit - [% Außenfeuchtigkeit 0-100%]
+ - Dewptf- [F Taupunkt im Freien]
+ - Tempf - [F Außentemperatur]
+ - Rainin - [in Regen in der vergangenen Stunde]
+ - Dailyrainin - [in Regenmenge bisher heute]
+ - Baromin - [inHg barometrischer Druck]
+ - Soiltempf - [F Bodentemperatur]
+ - Bodenfeuchtigkeit - [%]
+ - Solarradiation - [W/m²]
+ - UV - [Index]
+
+
+
+
+
+ Readings/Events:
+
+
+ - data - Daten, die zu www.wunderground.com gesendet werden
+ - response - Antwort, die vom Server empfangen wird
+
+
+
+ Notizen
+
+ - Die komplette API-Beschreibung findet sich
+hier
+ - Viel Spaß!
+
+
+
+
+=end html_DE
+=cut
diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt
index 73a7c9165..0addbd16a 100644
--- a/fhem/MAINTAINER.txt
+++ b/fhem/MAINTAINER.txt
@@ -263,6 +263,7 @@ FHEM/59_PROPLANTA.pm tupol http://forum.fhem.de Unterstue
FHEM/59_WWO.pm baumrasen http://forum.fhem.de Unterstuetzende Dienste/Wettermodule
FHEM/59_Weather.pm neubert http://forum.fhem.de Unterstuetzende Dienste/Wettermodule
FHEM/59_Wunderground.pm loredo http://forum.fhem.de Unterstuetzende Dienste/Wettermodule
+FHEM/59_WUup.pm mahowi http://forum.fhem.de Unterstuetzende Dienste/Wettermodule
FHEM/60_allergy.pm markus-m http://forum.fhem.de Unterstuetzende Dienste
FHEM/60_EM.pm rudolfkoenig http://forum.fhem.de SlowRF
FHEM/61_EMWZ.pm rudolfkoenig http://forum.fhem.de SlowRF