diff --git a/fhem/CHANGED b/fhem/CHANGED index f96d496fb..7985fc22f 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,6 +1,7 @@ # 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. - SVN + - feature: rain Module by baumrasen - feature: endPlotNow attribute for SVG-Plots (ChrisD) - feature: new module 51_BBB_BMP180.pm added (betateilchen) - feature: readingsGroup: allow devStateIcon to be displayed @@ -8,7 +9,8 @@ - feature: YAMAHA_AVR - new remoteControl commands for Tuner Preset selection - feature: RSS amended (read image from pipe, scaling options, line width) - + - feature: WWO Module by baumrasen + - 2013-09-29 (5.5) - feature: new module 55_PIFACE.pm added (betateilchen) - feature: Calendar can read from file and limit number of calendar events diff --git a/fhem/FHEM/59_WWO.pm b/fhem/FHEM/59_WWO.pm index b0af68dbc..2ffc828c2 100644 --- a/fhem/FHEM/59_WWO.pm +++ b/fhem/FHEM/59_WWO.pm @@ -1,4 +1,4 @@ -# $Id: 59_WWO.pm 3878 2013-10-04 07:11:43Z baumrasen $ +# $Id$ ############################################################################## # # 59_WWO.pm diff --git a/fhem/FHEM/98_rain.pm b/fhem/FHEM/98_rain.pm new file mode 100644 index 000000000..e24cebf20 --- /dev/null +++ b/fhem/FHEM/98_rain.pm @@ -0,0 +1,546 @@ +# $Id $ +############################################## +# +# Rain computing +# +# based / modified from dewpoint.pm (C) by Rudolf Koenig +# +# Copyright (C) 2012 Andreas Vogt +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The GNU General Public License may also be found at http://www.gnu.org/licenses/gpl-2.0.html . +# + +package main; +use strict; +use warnings; +use Time::Local; + +# Debug this module? YES = 1, NO = 0 +my $rain_debug = 0; + +########################## +sub +rain_Initialize($) +{ + my ($hash) = @_; + $hash->{DefFn} = "rain_Define"; + $hash->{NotifyFn} = "rain_Notify"; + $hash->{NotifyOrderPrefix} = "10-"; # Want to be called before the rest + $hash->{AttrList} = "disable:0,1"; +} + +########################## +sub +rain_Define($$) +{ + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + + return "wrong syntax: define rain devicename [rain_name] [israining_name] [new_name]" + if(@a < 3); + + my $name = $a[0]; + my $devname = $a[2]; + + if(@a == 6) { + $hash->{RAIN_NAME} = $a[3]; + $hash->{ISRAINING_NAME} = $a[4]; + $hash->{NEW_NAME} = $a[5]; + } elsif (@a == 3) { + $hash->{RAIN_NAME} = "rain"; + $hash->{ISRAINING_NAME} = "israining"; + $hash->{NEW_NAME} = "rain_calc"; + } else { + return "wrong syntax: define rain devicename-regex [rain_name israining_name new_name]" + } + + eval { "Hallo" =~ m/^$devname$/ }; + return "Bad regecaxp: $@" if($@); + $hash->{DEV_REGEXP} = $devname; + + $hash->{STATE} = "active"; + return undef; +} + +########################## +sub +rain_Notify($$) +{ + my ($hash, $dev) = @_; + my $hashName = $hash->{NAME}; + + return "" if(AttrVal($hashName, "disable", undef)); + return "" if(!defined($hash->{DEV_REGEXP})); + + my @txt = ( "rain", "rain_h", "rain_d", "humidity", "temperature", + "israining", "unknown1", "unknown2", "unknown3"); + my @sfx = ( "(counter)", "(l/m2)", "(km/h)", "(%)", "(Celsius)", + "(yes/no)", "","",""); + my %repchanged = ("rain"=>1, "wind"=>1, "humidity"=>1, "temperature"=>1, + "israining"=>1, "rain_all"=>1); + + # time + my $tm = TimeNow(); + my $tsecs= time(); # number of non-leap seconds since January 1, 1970, UTC + + # The next instr wont work for empty hashes, so we init it now + $dev->{READINGS}{$txt[0]}{VAL} = 0 if(!$dev->{READINGS}); + my $r = $dev->{READINGS}; + + my $devName = $dev->{NAME}; + + my $re = $hash->{DEV_REGEXP}; + + # rain + my $rain_name = "rain"; + my $israining_name = "israining"; + my $new_name = "rain_calc"; + # fan + my $devname_out = ""; + my $min_rain = 0; + # alarm + my $devname_ref = ""; + my $diff_rain = 0; + + if (!defined($hash->{RAIN_NAME}) || !defined($hash->{ISRAINING_NAME}) || !defined($hash->{NEW_NAME})) { + # should never happen! + Log3 $hash, 1, "Error rain: RAIN_NAME || ISRAINING_NAME || NEW_NAME undefined"; + return ""; + } + $rain_name = $hash->{RAIN_NAME}; + $israining_name = $hash->{ISRAINING_NAME}; + $new_name = $hash->{NEW_NAME}; + Log3 $hash, 5, "rain_notify: devname=$devName rainname=$hashName, dev=$devName, dev_regex=$re rain_name=$rain_name israining_name=$israining_name"; + + my $max = int(@{$dev->{CHANGED}}); + my $n = -1; + my $lastval; + + return "" if($devName !~ m/^$re$/); + + Log3 $hash, 1, "rain_notify: max='$max'" if ($rain_debug == 1); + + my $rain_value = ""; + my $israining = ""; + + for (my $i = 0; $i < $max; $i++) { + my $s = $dev->{CHANGED}[$i]; + + Log3 $hash, 1, "rain_notify: s='$s'" if ($rain_debug == 1); + + ################ + # Filtering + next if(!defined($s)); + my ($evName, $val, $rest) = split(" ", $s, 3); # resets $1 + next if(!defined($evName)); + next if(!defined($val)); + Log3 $hash, 1, "rain_notify: evName='$evName' val=$val'" if ($rain_debug == 1); + if (($evName eq "R:") && ($rain_name eq "R")) { + $n = $i; + #my ($evName1, $val1, $evName2, $val2, $rest) = split(" ", $s, 5); # resets $1 + #$lastval = $evName1." ".$val1." ".$evName2." ".$val2; + $lastval = $s; + if ($s =~ /T: [-+]?([0-9]*\.[0-9]+|[0-9]+)/) { + $rain_value = $1; + } + if ($s =~ /H: [-+]?([0-9]*\.[0-9]+|[0-9]+)/) { + $israining = $1; + } + Log3 $hash, 1, "rain_notify T: H:, rain=$rain_value unit=$israining" if ($rain_debug == 1); + } elsif ($evName eq $rain_name.":") { + $rain_value = $val; + Log3 $hash, 1, "rain_notify rain_value! rain=$rain_value" if ($rain_debug == 1); + } elsif ($evName eq $israining_name.":") { + $israining = $val; + Log3 $hash, 1, "rain_notify israining! unit=$israining" if ($rain_debug == 1); + } + + } + + Log3 $hash, 3, "rain_notify: n='$n'" if ($rain_debug == 1); + Log3 $hash, 3, "rain_notify: rain_name='$rain_name'" if ($rain_debug == 1); + + if ($n == -1) { $n = $max; } + + Log3 $hash, 5, "rain_notify: get the following values rain_value=$rain_value " . ($rain_value eq "") . " israining=$israining " . ($israining eq "") if ($rain_debug == 1); + + if (($rain_value eq "") || ($israining eq "")) { Log3 $hash, 1, "rain_notify: no values for calculation found!"; } + if (($rain_value eq "") || ($israining eq "")) { return undef; } # no way to calculate rain! + + # We found rain_value and israining. so we can calculate rain first + + # my $rain = sprintf("%.1f", rain($rain_value,$israining)); + my $rain = sprintf("%.1f", $rain_value); + + Log3 $hash, 1, "rain_notify: rain=$rain" if ($rain_debug == 1); + + + # >define rain [ ] + # + # Calculates rain for device from rain_value and israining and write it + # to new Reading rain. + # If optional , and is specified + # then read rain_value from reading , israining from reading + # and write rain to reading . + # if rain_name eq "R" then use rain_value from state T: H: R:, add to the state + # Example: + # define raintest1 rain rain .* + # define raintest2 rain rain .* T H D + my $sensor = $new_name; + my $current; + + $current = $rain; + +# $dev->{READINGS}{$sensor}{TIME} = $tm; +# $dev->{READINGS}{$sensor}{VAL} = $current; +# $dev->{CHANGED}[$n++] = $sensor . ": " . $current; + + my $rain_value_prev=0; + my $rain_h_last=0; + my $rain_h_curr=0; + my $rain_h_start; + + my $rain_d_last=0; + my $rain_d_curr=0; + my $rain_d_start; + + my $rain_h_trig_tsecs; + my $rain_d_trig_tsecs; + + my $rain_tsecs_prev; + + # get previous tsecs + if(defined($r->{$sensor ."_tsecs"})) { + $rain_tsecs_prev= $r->{$sensor ."_tsecs"}{VAL}; + } else{ + $rain_tsecs_prev= 0; # 1970-01-01 + } + + $r->{$sensor ."_tsecs"}{TIME} = $tm; + $r->{$sensor ."_tsecs"}{VAL} = $tsecs; + $dev->{CHANGED}[$n++] = $sensor . "_tsecs: " . $tsecs; + + #TODO there should be a handling for new created devices (rain is existing with a large value for the last day) + #TODO there should be a handling batterie replacement (rain could not be negativ) + #TODO is the value "israining" needed? + + # get previous value + if(defined($r->{$sensor ."_now_value"})) { + $rain_value_prev= $r->{$sensor ."_now_value"}{VAL}; + } else{ + $rain_value_prev= 0; # 0 + } + + $r->{$sensor ."_now_value"}{TIME} = $tm; + $r->{$sensor ."_now_value"}{VAL} = $current; + $dev->{CHANGED}[$n++] = $sensor . "_now_value: " . $current; + + my $rain_diff = $current - $rain_value_prev; + + $r->{$sensor ."_now_diff"}{TIME} = $tm; + $r->{$sensor ."_now_diff"}{VAL} = $rain_diff; + $dev->{CHANGED}[$n++] = $sensor . "_now_diff: " . $rain_diff; + + # get previous tsecs + if(defined($r->{$sensor ."_h_start"})) { + $rain_h_start= $r->{$sensor ."_h_start"}{VAL}; + } else{ + $rain_h_start= 0; # 1970-01-01 + } + + # get previous tsecs + if(defined($r->{$sensor ."_d_start"})) { + $rain_d_start= $r->{$sensor ."_d_start"}{VAL}; + } else{ + $rain_d_start= 0; # 1970-01-01 + } + + # get previous rain_h_last + if(defined($r->{$sensor ."_h_last"})) { + $rain_h_last= $r->{$sensor ."_h_last"}{VAL}; + } else{ + $rain_h_last= 0; + } + + # get previous rain_d_last + if(defined($r->{$sensor ."_d_last"})) { + $rain_d_last= $r->{$sensor ."_d_last"}{VAL}; + } else{ + $rain_d_last= 0; + } + + # get previous tsecs + if(defined($r->{$sensor ."_h_trig_tsecs"})) { + $rain_h_trig_tsecs= $r->{$sensor ."_h_trig_tsecs"}{VAL}; + } else{ + $rain_h_trig_tsecs= 0; # 1970-01-01 + } + + # get previous tsecs + if(defined($r->{$sensor ."_d_trig_tsecs"})) { + $rain_d_trig_tsecs= $r->{$sensor ."_d_trig_tsecs"}{VAL}; + } else{ + $rain_d_trig_tsecs= 0; # 1970-01-01 + } + + Log3 $hash, 1, "get rain_h_trig IS " . localtime($rain_h_trig_tsecs) if ($rain_debug == 1); + Log3 $hash, 1, "get rain_d_trig IS " . localtime($rain_d_trig_tsecs) if ($rain_debug == 1); + + # look forward to the next hour trigger event + my @th=localtime($tsecs+1800); + # time for the hour-trigger (every houre at) 30 min + my $rain_h_trig=sprintf("%04d-%02d-%02d_%02d:%02d",$th[5]+1900,$th[4]+1,$th[3],$th[2],"30"); + Log3 $hash, 1, "NEW rain_h_trigger would be = $rain_h_trig" if ($rain_debug == 1); + + Log3 $hash, 1, "rain_h_trigger_tsecs = $rain_h_trig_tsecs" if ($rain_debug == 1); + Log3 $hash, 1, "secunds until hour-reset = " . ($rain_h_trig_tsecs-$tsecs) if ($rain_debug == 1); + + if (($rain_h_trig_tsecs-$tsecs)>3600){ # something is wrong + + ### debughelper --> + #$DB::single = 1; + Log3 $hash, 1, "something is wrong! the diff until next reset should not be greater than one hour. Now set New Trigger" if ($rain_debug == 1); + + #my @timeData = gmtime(time); + #Debug "timeData: ". join(' ', @timeData); + + #my @utcData = utcdate(time); + #Debug "utcData: ". join(' ', @utcData); + + #my @gmData = gmtime(time); + #Debug "gmData: ". join(' ', @gmData); + + #TODO should be 5:30 UTC? + $rain_h_trig_tsecs = timelocal(0,30,7,$th[3],$th[4],$th[5]+1900); + + # remember $rain_d_trig_tsecs / trigger-time for next event to zero rain + $r->{$sensor ."_h_trig_tsecs"}{TIME} = $tm; + $r->{$sensor ."_h_trig_tsecs"}{VAL} = "$rain_h_trig_tsecs"; + } + + if($tsecs>$rain_h_trig_tsecs){ # wenn now groesser ist, als der letzte trigger-wert, dann beginnt eine neue einheit + Log3 $hash, 1, "Detect new rain hour!" if ($rain_debug == 1); + Log3 $hash, 1, "NEW rain_h_trigger IS = $rain_h_trig" if ($rain_debug == 1); + + #$time = timelocal($sec,$min,$hour,$mday,$mon,$year); + $rain_h_trig_tsecs = timelocal(0,30,$th[2],$th[3],$th[4],$th[5]+1900); + Log3 $hash, 1, "rain_h_trigger_tsecs = $rain_h_trig_tsecs" if ($rain_debug == 1); + + #$rain_h_last = sprintf("%0.1f", ($rain_raw_adj-$rain_raw_h_start) * $def->{RAINUNIT} / 1000); + $rain_h_last = sprintf("%0.1f", $current-$rain_h_start); + # remember $rain_h_last + $r->{$sensor ."_h_last"}{TIME} = $tm; + $r->{$sensor ."_h_last"}{VAL} = "$rain_h_last"; + + # set new rain_raw_hour_start_value + $rain_h_start = $current; + # remember $rain_raw_h_start + $r->{$sensor ."_h_start"}{TIME} = $tm; + $r->{$sensor ."_h_start"}{VAL} = "$rain_h_start"; + + # remember $rain_h_trig_tsecs / trigger-time for next event to zero rain + $r->{$sensor ."_h_trig_tsecs"}{TIME} = $tm; + $r->{$sensor ."_h_trig_tsecs"}{VAL} = "$rain_h_trig_tsecs"; + } + + # look forward to the next day trigger event + @th=localtime($tsecs+86400); + # the time for the day-trigger: 7:30 Uhr + my $rain_d_trig=sprintf("%04d-%02d-%02d_%02d:%02d",$th[5]+1900,$th[4]+1,$th[3],"7","30"); + Log3 $hash, 1, "NEW rain_d_trigger would be= $rain_d_trig" if ($rain_debug == 1); + + Log3 $hash, 1, "rain_d_trigger_tsecs = $rain_d_trig_tsecs" if ($rain_debug == 1); + Log3 $hash, 1, "secunds until day-reset = " . ($rain_d_trig_tsecs-$tsecs) if ($rain_debug == 1); + + if (($rain_d_trig_tsecs-$tsecs)>86400){ # something is wrong + Log3 $hash, 1, "something is wrong! the diff until next reset should not be greater than one day. Now set New Trigger" if ($rain_debug == 1); + $rain_d_trig_tsecs = timelocal(0,30,7,$th[3],$th[4],$th[5]+1900); + + # remember $rain_d_trig_tsecs / trigger-time for next event to zero rain + $r->{$sensor ."_d_trig_tsecs"}{TIME} = $tm; + $r->{$sensor ."_d_trig_tsecs"}{VAL} = "$rain_d_trig_tsecs"; + } + + if($tsecs>$rain_d_trig_tsecs){ + + Log3 $hash, 1, "Detect new rain day!" if ($rain_debug == 1); + Log3 $hash, 1, "NEW rain_d_trigger IS= $rain_d_trig" if ($rain_debug == 1); + + # $time = timelocal($sec,$min,$hour,$mday,$mon,$year); + $rain_d_trig_tsecs = timelocal(0,30,7,$th[3],$th[4],$th[5]+1900); + Log3 $hash, 1, "rain_d_trigger_tsecs = $rain_d_trig_tsecs" if ($rain_debug == 1); + + $rain_d_last = sprintf("%0.1f", ($current-$rain_d_start)); + + # remember $rain_h_last + $r->{$sensor ."_d_last"}{TIME} = $tm; + $r->{$sensor ."_d_last"}{VAL} = "$rain_d_last"; + + # set new rain_raw_day_start_value + $rain_d_start=$current; + # remember $rain_raw_h_start + $r->{$sensor ."_d_start"}{TIME} = $tm; + $r->{$sensor ."_d_start"}{VAL} = "$rain_d_start"; + + # remember $rain_d_trig_tsecs / trigger-time for next event to zero rain + $r->{$sensor ."_d_trig_tsecs"}{TIME} = $tm; + $r->{$sensor ."_d_trig_tsecs"}{VAL} = "$rain_d_trig_tsecs"; + + } + + $rain_h_curr = sprintf("%0.1f", ($current-$rain_h_start)); + #remember $rain_raw_h_start + $r->{$sensor ."_h_curr"}{TIME} = $tm; + $r->{$sensor ."_h_curr"}{VAL} = $rain_h_curr; + + $rain_d_curr = sprintf("%0.1f", ($current-$rain_d_start)); + #remember $rain_raw_d_start + $r->{$sensor ."_d_curr"}{TIME} = $tm; + $r->{$sensor ."_d_curr"}{VAL} = $rain_d_curr; + + Log3 $hash, 1, "Rain Curr h: $rain_h_curr / Rain Last h: $rain_h_last" if ($rain_debug == 1); + Log3 $hash, 1, "Rain Curr d: $rain_d_curr / Rain Last d: $rain_d_last" if ($rain_debug == 1); + + Log3 $hash, 1, "r1(prev) and r2: $rain_value_prev / $current" if ($rain_debug == 1); + + my $tsecs_dif = $tsecs-$rain_tsecs_prev; + my $rain_now_rate=0; + if ($tsecs_dif!=0){ + $rain_now_rate=sprintf("%0.1f",($current-$rain_value_prev)*3600/$tsecs_dif); + } + + Log3 $hash, 1, "rdif r2-r1=" . ($current-$rain_value_prev) if ($rain_debug == 1); + Log3 $hash, 1, "rain_nowrate (tsec_dif=". ($tsecs_dif) .") $rain_now_rate" if ($rain_debug == 1); + + # remember $rain_d_trig_tsecs / trigger-time for next event to zero rain + $r->{$sensor ."_now_rate"}{TIME} = $tm; + $r->{$sensor ."_now_rate"}{VAL} = "$rain_now_rate"; + + # For logging/summary + my $rain_all = "cH: $rain_h_curr lH: $rain_h_last cD: $rain_d_curr lD: $rain_d_last IR: $israining Rnow: $rain_now_rate Rdif: $rain_diff"; +# Log GetLogLevel($def->{NAME},4), "KS300 $dev: $rain_all" if ($rain_debug == 1); + Log3 $hash, 1, "$rain_all" if ($rain_debug == 1); + # remember rain + $r->{$sensor ."_all"}{TIME} = $tm; + $r->{$sensor ."_all"}{VAL} = "$rain_all"; + + #$dev->{STATE} = $val; + $dev->{CHANGED}[$n++] = $sensor ."_all: $rain_all"; + + + Log3 $hash, 1, "rain_notify: current=$current" if ($rain_debug == 1); + + + return undef; +} + +# ----------------------------- +# Rain calculation. +# see http://www.faqs.org/faqs/meteorology/rain-rain/ "5. EXAMPLE" +sub +rain($$$) +{ + my ($rain_value, $israining, $hash) = @_; + + Log3 $hash, 5, "Info: rain() e==0: rain=$rain_value, israining=$israining"; + + my $dp; + + my $A = 17.2694; + my $B = ($rain_value > 0) ? 237.3 : 265.5; + my $es = 610.78 * exp( $A * $rain_value / ($rain_value + $B) ); + my $e = $israining/ 100 * $es; + if ($e == 0) { + Log3 $hash, 1, "Error: rain() e==0: rain=$rain_value, israining=$israining"; + return 0; + } + my $e1 = $e / 610.78; + my $f = log( $e1 ) / $A; + my $f1 = 1 - $f; + if ($f1 == 0) { + Log3 $hash, 1, "Error: rain() (1-f)==0: rain=$rain_value, israining=$israining"; + return 0; + } + $dp = $B * $f / $f1 ; + return($dp); +} + +1; + + +=pod +=begin html + + +

rain

+
    + Rain calculations. Offers different values from a rain sensor.
    + + + Define +
      + define <name> rain <devicename-regex> [<rain_name> <israining_name> <new_name>]
      +
      +
        + Calculates rain values for device <devicename-regex> from incremental rain-value and israining-state + and write it to some new readings named rain_calc_???????. + If optional <rain_name>, <israining_name> and <new_name> is specified + then read rain from reading <rain_name>, israining from reading <israining_name> + and write the calculated rain to reading <new_name>. +
      + + The following values are generated: +
        +
      • rain_calc_all --> all values in one line
      • +
      • rain_calc_d_curr --> liter rain at the current day (from 7:30 local time)
      • +
      • rain_calc_d_last --> liter rain of 24h before 7:30 local time
      • +
      • rain_calc_d_start --> first incremental rain value from the rain device after 7:30 local time
      • +
      • rain_calc_h_curr --> liter rain at the current hour (from XX:30)
      • +
      • rain_calc_h_last --> liter rain of 1 hour before the last XX:30 time
      • +
      • rain_calc_h_start --> first incremental rain value from the rain device after last XX:30
      • +
      • rain_calc_now_diff --> fallen rain in liter since last value from rain device
      • +
      • rain_calc_now_rate --> fallen rain in liter/hour since last value from rain device
      • + +
      + +
      + + Example:
      +    # Compute the rain for the rain/israining
      +    # events of the ks300 device and generate reading rain_calc.
      +    define rain_ks300 rain ks300
      +
      +    
      +
    + + + Set
      N/A

    + + + Get
      N/A

    + + + Attributes + +
+ + +=end html +=cut diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt index aa297cdc0..015798af2 100644 --- a/fhem/MAINTAINER.txt +++ b/fhem/MAINTAINER.txt @@ -84,7 +84,7 @@ FHEM/24_NetIO230B.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges FHEM/30_HUEBridge.pm justme1968 http://forum.fhem.de Sonstige Systeme FHEM/31_HUEDevice.pm justme1968 http://forum.fhem.de Sonstige Systeme FHEM/31_LightScene.pm justme1968 http://forum.fhem.de Automatisierung -FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstützende Dienste +FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstuetzende Dienste FHEM/32_mailcheck.pm justme1968 http://forum.fhem.de Automatisierung FHEM/33_readingsGroup.pm justme1968 http://forum.fhem.de Frontends FHEM/32_speedtest.pm justme1968 http://forum.fhem.de Sonstiges @@ -111,7 +111,7 @@ FHEM/55_PIFACE.pm betateilchen http://forum.fhem.de Raspberry FHEM/56_POKEYS.pm axelberner http://forum.fhem.de Sonstiges FHEM/57_Calendar.pm borisneubert http://forum.fhem.de Sonstiges FHEM/59_HCS.pm mfr69bs http://forum.fhem.de Automatisierung -FHEM/59_Twilight.pm dietmar63 http://forum.fhem.de Unterstützende Dienste +FHEM/59_Twilight.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste FHEM/59_WWO.pm baumrasen http://forum.fhem.de Sonstiges FHEM/59_Weather.pm borisneubert http://forum.fhem.de Sonstiges FHEM/60_EM.pm rudolfkoenig http://forum.fhem.de SlowRF @@ -133,8 +133,8 @@ FHEM/70_VIERA.pm teevau http://forum.fhem.de Sonstiges FHEM/70_WS3600.pm Josch http://forum.fhem.de Sonstiges FHEM/71_LISTENLIVE.pm betateilchen http://forum.fhem.de Multimedia FHEM/71_YAMAHA_AVR.pm markusbloch http://forum.fhem.de Multimedia -FHEM/72_FB_CALLMONITOR.pm markusbloch http://forum.fhem.de Unterstützende Dienste -FHEM/73_PRESENCE.pm markusbloch http://forum.fhem.de Unterstützende Dienste +FHEM/72_FB_CALLMONITOR.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste +FHEM/73_PRESENCE.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste FHEM/75_MSG.pm ruebedo http://forum.fhem.de Automatisierung FHEM/76_MSGFile.pm ruebedo http://forum.fhem.de Automatisierung FHEM/76_MSGMail.pm ruebedo http://forum.fhem.de Automatisierung @@ -163,10 +163,10 @@ FHEM/95_holiday.pm rudolfkoenig http://forum.fhem.de Sonstiges FHEM/95_remotecontrol.pm ulimaass http://forum.fhem.de Frontends FHEM/98_CULflash.pm rudolfkoenig http://forum.fhem.de Sonstiges FHEM/98_HMinfo.pm martinp876 http://forum.fhem.de Sonstiges -FHEM/98_Heating_Control.pm dietmar63 http://forum.fhem.de Unterstützende Dienste +FHEM/98_Heating_Control.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste FHEM/98_JsonList.pm mfr69bs http://forum.fhem.de Automatisierung FHEM/98_PID.pm betateilchen http://forum.fhem.de Automatisierung -FHEM/98_RandomTimer.pm dietmar63 http://forum.fhem.de Unterstützende Dienste +FHEM/98_RandomTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste FHEM/98_SVG.pm rudolfkoenig http://forum.fhem.de Frontends FHEM/98_THRESHOLD.pm damian-s http://forum.fhem.de Automatisierung FHEM/98_WOL.pm klassm http://forum.fhem.de Sonstiges @@ -179,6 +179,7 @@ FHEM/98_dummy.pm rudolfkoenig http://forum.fhem.de Automatis FHEM/98_fheminfo.pm mfr69bs http://forum.fhem.de Sonstiges FHEM/98_notice.pm mfr69bs http://forum.fhem.de Sonstiges FHEM/98_openweathermap.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste +FHEM/98_rain.pm baumrasen http://forum.fhem.de Sonstiges FHEM/98_structure.pm rudolfkoenig http://forum.fhem.de Automatisierung FHEM/98_telnet.pm rudolfkoenig http://forum.fhem.de Automatisierung FHEM/98_update.pm mfr69bs http://forum.fhem.de Sonstiges