MAINTAINER: Maintainer changes

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@16005 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
igami 2018-01-27 06:05:51 +00:00
parent 8b75e12792
commit c341bf3d5b
6 changed files with 523 additions and 519 deletions

View File

@ -4,6 +4,7 @@
# 59_Twilight.pm
# Copyright by Sebastian Stuecker
# erweitert von Dietmar Ortmann
# Maintained by igami since 02-2018
#
# used algorithm see: http://lexikon.astronomie.info/zeitgleichung/
#
@ -37,7 +38,7 @@ use warnings;
use POSIX;
use HttpUtils;
use Math::Trig;
use Time::Local 'timelocal_nocheck';
use Time::Local 'timelocal_nocheck';
sub Twilight_calc($$);
sub Twilight_my_gmt_offset();
@ -108,30 +109,30 @@ sub Twilight_Define($$)
if(int(@a)>4) { if ($a[4] =~ /^[\+-]*[0-9]*\.*[0-9]*$/ && $a[4] !~ /^[\. ]*$/ ) {
$indoor_horizon = $a[4];
if($indoor_horizon > 20) { $indoor_horizon=20;}
# minimal indoor_horizon makes values like civil_sunset and civil_sunrise
# minimal indoor_horizon makes values like civil_sunset and civil_sunrise
if($indoor_horizon < -6) { $indoor_horizon= -6;}
}else{
return "Argument Indoor_Horizon is not a valid number";}
}
$hash->{WEATHER_HORIZON} = 0;
$hash->{INDOOR_HORIZON} = $indoor_horizon;
$hash->{LATITUDE} = $latitude;
$hash->{LONGITUDE} = $longitude;
$hash->{WEATHER} = $weather;
$hash->{VERSUCHE} = 0;
$hash->{VERSUCHE} = 0;
$hash->{DEFINE} = 1;
$hash->{CONDITION} = 50;
$hash->{SUNPOS_OFFSET} = 5*60;
$attr{$name}{verbose} = 4 if ($name =~ /^tst.*$/ );
my $mHash = { HASH=>$hash };
Twilight_sunpos($mHash);
Twilight_sunpos($mHash);
Twilight_Midnight($mHash);
delete $hash->{DEFINE};
return undef;
}
################################################################################
@ -152,14 +153,14 @@ sub myInternalTimer($$$$$) {
my ($modifier, $tim, $callback, $hash, $waitIfInitNotDone) = @_;
my $timerName = "$hash->{NAME}_$modifier";
my $mHash = { HASH=>$hash, NAME=>"$hash->{NAME}_$modifier", MODIFIER=>$modifier};
my $mHash = { HASH=>$hash, NAME=>"$hash->{NAME}_$modifier", MODIFIER=>$modifier};
if (defined($hash->{TIMER}{$timerName})) {
Log3 $hash, 1, "[$hash->{NAME}] possible overwriting of timer $timerName - please delete first";
stacktrace();
} else {
$hash->{TIMER}{$timerName} = $mHash;
}
Log3 $hash, 5, "[$hash->{NAME}] setting Timer: $timerName " . FmtDateTime($tim);
InternalTimer($tim, $callback, $mHash, $waitIfInitNotDone);
return $mHash;
@ -191,12 +192,12 @@ sub myRemoveInternalTimer($$) {
################################################################################
sub myGetHashIndirekt ($$) {
my ($myHash, $function) = @_;
if (!defined($myHash->{HASH})) {
Log 3, "[$function] myHash not valid";
Log 3, "[$function] myHash not valid";
return undef;
};
return $myHash->{HASH};
};
return $myHash->{HASH};
}
################################################################################
sub Twilight_midnight_seconds($) {
@ -207,12 +208,12 @@ sub Twilight_midnight_seconds($) {
}
################################################################################
#sub Twilight_ssTimeAsEpoch($) {
# my ($zeit) = @_;
# my ($zeit) = @_;
# my ($hour, $min, $sec) = split(":",$zeit);
#
# my $days=0;
# if ($hour>=24) {$days = 1; $hour -=24};
#
# if ($hour>=24) {$days = 1; $hour -=24};
#
# my @jetzt_arr = localtime(time());
# #Stunden Minuten Sekunden
# $jetzt_arr[2] = $hour; $jetzt_arr[1] = $min; $jetzt_arr[0] = $sec;
@ -224,21 +225,21 @@ sub Twilight_midnight_seconds($) {
################################################################################
sub Twilight_calc($$) {
my ($deg, $idx) = @_;
my $midnight = time() - Twilight_midnight_seconds(time());
my $sr = sunrise_abs("Horizon=$deg");
my $ss = sunset_abs ("Horizon=$deg");
my ($srhour, $srmin, $srsec) = split(":",$sr); $srhour -= 24 if($srhour>=24);
my ($sshour, $ssmin, $sssec) = split(":",$ss); $sshour -= 24 if($sshour>=24);
my ($sshour, $ssmin, $sssec) = split(":",$ss); $sshour -= 24 if($sshour>=24);
my $sr1 = $midnight + 3600*$srhour+60*$srmin+$srsec;
my $ss1 = $midnight + 3600*$sshour+60*$ssmin+$sssec;
return (0,0) if (abs ($sr1 - $ss1) < 30);
return (0,0) if (abs ($sr1 - $ss1) < 30);
#return Twilight_ssTimeAsEpoch($sr) + 0.01*$idx,
# Twilight_ssTimeAsEpoch($ss) - 0.01*$idx;
# Twilight_ssTimeAsEpoch($ss) - 0.01*$idx;
return ($sr1 + 0.01*$idx), ($ss1 - 0.01*$idx);
}
################################################################################
@ -258,32 +259,32 @@ sub Twilight_TwilightTimes(@) {
foreach my $horizon (@horizons) {
$idx++; next if ($whitchTimes eq "weather" && !($horizon =~ m/weather/) );
my ($name, $deg) = split(":", $horizon);
my $sr = "sr$name"; my $ss = "ss$name";
my ($name, $deg) = split(":", $horizon);
my $sr = "sr$name"; my $ss = "ss$name";
$hash->{TW}{$sr}{NAME} = $sr; $hash->{TW}{$ss}{NAME} = $ss;
$hash->{TW}{$sr}{DEG} = $deg; $hash->{TW}{$ss}{DEG} = $deg;
$hash->{TW}{$sr}{LIGHT} = $idx+1;$hash->{TW}{$ss}{LIGHT} = $idx;
$hash->{TW}{$sr}{STATE} = $idx+1;$hash->{TW}{$ss}{STATE} = 12 - $idx;
$hash->{TW}{$sr}{SWIP} = $swip; $hash->{TW}{$ss}{SWIP} = $swip;
($hash->{TW}{$sr}{TIME}, $hash->{TW}{$ss}{TIME}) = Twilight_calc ($deg, $idx);
if ($hash->{TW}{$sr}{TIME} == 0) {
Log3 $hash, 4, "[$Name] hint: $hash->{TW}{$sr}{NAME}, $hash->{TW}{$ss}{NAME} are not defined(HORIZON=$deg)";
}
}
$attr{global}{latitude} = $lat;
$attr{global}{longitude} = $long;
$attr{global}{latitude} = $lat;
$attr{global}{longitude} = $long;
# ------------------------------------------------------------------------------
readingsBeginUpdate ($hash);
foreach my $ereignis (keys %{$hash->{TW}}) {
next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) );
readingsBulkUpdate($hash, $ereignis, $hash->{TW}{$ereignis}{TIME} == 0 ? "undefined" : FmtTime($hash->{TW}{$ereignis}{TIME}));
}
}
if ($hash->{CONDITION} != 50 ) {
readingsBulkUpdate ($hash,"condition", $hash->{CONDITION});
readingsBulkUpdate ($hash,"condition_txt",$hash->{CONDITION_TXT});
}
}
readingsEndUpdate ($hash, defined($hash->{LOCAL} ? 0 : 1));
# ------------------------------------------------------------------------------
my @horizonsOhneDeg = map {my($e, $deg)=split(":",$_); "$e"} @horizons;
@ -296,18 +297,18 @@ sub Twilight_TwilightTimes(@) {
my $lastMitternacht = $now-$secSinceMidnight;
my $nextMitternacht = ($secSinceMidnight > 12*3600) ? $lastMitternacht+24*3600 : $lastMitternacht;
my $jetztIstMitternacht = abs($now+5-$nextMitternacht)<=10;
my @keyListe = qw "DEG LIGHT STATE SWIP TIME NAMENEXT";
foreach my $ereignis (sort keys %{$hash->{TW}}) {
next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) );
myRemoveInternalTimer($ereignis, $hash); # if(!$jetztIstMitternacht);
if($hash->{TW}{$ereignis}{TIME} > 0) {
$myHash = myInternalTimer($ereignis, $hash->{TW}{$ereignis}{TIME}, "Twilight_fireEvent", $hash, 0);
map {$myHash->{$_} = $hash->{TW}{$ereignis}{$_} } @keyListe;
map {$myHash->{$_} = $hash->{TW}{$ereignis}{$_} } @keyListe;
}
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
return 1;
}
################################################################################
@ -318,7 +319,7 @@ sub Twilight_fireEvent($) {
return if (!defined($hash));
my $name = $hash->{NAME};
my $event = $myHash->{MODIFIER};
my $deg = $myHash->{DEG};
my $light = $myHash->{LIGHT};
@ -330,18 +331,18 @@ sub Twilight_fireEvent($) {
my $delta = int($eventTime - time());
my $oldState = ReadingsVal($name,"state","0");
my $nextEventTime = ($hash->{TW}{$nextEvent}{TIME} > 0) ? FmtTime($hash->{TW}{$nextEvent}{TIME}) : "undefined";
my $doTrigger = !(defined($hash->{LOCAL})) && ( abs($delta)<6 || $swip && $state gt $oldState);
#Log3 $hash, 3, "[$hash->{NAME}] swip-delta-oldState-doTrigger===>$swip/$delta/$oldState/$doTrigger";
Log3 $hash, 4,
sprintf ("[$hash->{NAME}] %-10s %-19s ", $event, FmtDateTime($eventTime)).
sprintf ("(%2d/$light/%+5.1f°/$doTrigger) ", $state, $deg).
sprintf ("(%2d/$light/%+5.1f°/$doTrigger) ", $state, $deg).
sprintf ("===> %-10s %-19s ", $nextEvent, $nextEventTime);
readingsBeginUpdate($hash);
readingsBulkUpdate ($hash, "state", $state);
readingsBulkUpdate ($hash, "light", $light);
@ -355,11 +356,11 @@ sub Twilight_fireEvent($) {
}
################################################################################
sub Twilight_Midnight($) {
my ($myHash) = @_;
my ($myHash) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash));
$hash->{SWIP} = 0;
return if (!defined($hash));
$hash->{SWIP} = 0;
my $param = Twilight_CreateHttpParameterAndGetData($myHash, "Mid");
}
################################################################################
@ -367,24 +368,24 @@ sub Twilight_Midnight($) {
sub Twilight_WeatherTimerUpdate($) {
my ($myHash) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash));
return if (!defined($hash));
$hash->{SWIP} = 1;
$hash->{SWIP} = 1;
my $param = Twilight_CreateHttpParameterAndGetData($myHash, "weather");
}
}
################################################################################
sub Twilight_CreateHttpParameterAndGetData($$) {
my ($myHash, $mode) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash));
return if (!defined($hash));
my $location = $hash->{WEATHER};
my $verbose = AttrVal($hash->{NAME}, "verbose", 3 );
my $URL = "http://query.yahooapis.com/v1/public/yql?q=select%%20*%%20from%%20weather.forecast%%20where%%20woeid=%s%%20and%%20u=%%27c%%27&format=%s&env=store%%3A%%2F%%2Fdatatables.org%%2Falltableswithkeys";
my $url = sprintf($URL, $location, "json");
Log3 $hash, 4, "[$hash->{NAME}] url=$url";
my $param = {
url => $url,
timeout => defined($hash->{DEFINE}) ? 10 :10,
@ -394,23 +395,23 @@ sub Twilight_CreateHttpParameterAndGetData($$) {
header => "User-Agent: Mozilla/5.0\r\nAccept: application/xml",
callback => \&Twilight_WeatherCallback,
mode => $mode };
if (defined($hash->{DEFINE})) {
delete $param->{callback};
my ($err, $result) = HttpUtils_BlockingGet($param);
Twilight_WeatherCallback($param, $err, $result);
} else {
HttpUtils_NonblockingGet($param);
}
}
}
################################################################################
sub Twilight_WeatherCallback(@) {
my ($param, $err, $result) = @_;
my $hash = $param->{hash};
return if (!defined($hash));
if ($err) {
Log3 $hash, 3, "[$hash->{NAME}] got no weather info from yahoo. Error code: $err";
$result = undef;
@ -418,22 +419,22 @@ sub Twilight_WeatherCallback(@) {
Log3 $hash, 4, "[$hash->{NAME}] got weather info from yahoo for $hash->{WEATHER}";
Log3 $hash, 5, "[$hash->{NAME}] answer=$result" if defined $result;
}
Twilight_getWeatherHorizon($hash, $result);
#$hash->{CONDITION} = 50;
#$hash->{CONDITION} = 50;
if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} <= 10) {
$hash->{VERSUCHE} += 1;
Twilight_RepeatTimerSet($hash, $param->{mode});
return;
}
Twilight_TwilightTimes ($hash, $param->{mode}, $result);
Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed to get valid weather data from yahoo" if ($hash->{CONDITION} != 50 && $hash->{VERSUCHE} > 0);
Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed got NO valid weather data from yahoo" if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} > 0);
$hash->{VERSUCHE} = 0;
$hash->{VERSUCHE} = 0;
Twilight_StandardTimerSet ($hash);
}
################################################################################
@ -446,8 +447,8 @@ sub Twilight_RepeatTimerSet($$) {
myInternalTimer ("Midnight", $midnight, "Twilight_Midnight", $hash, 0);
} else {
myInternalTimer ("Midnight", $midnight, "Twilight_WeatherTimerUpdate", $hash, 0);
}
}
}
################################################################################
sub Twilight_StandardTimerSet($) {
@ -484,13 +485,13 @@ sub Twilight_sunposTimerSet($) {
sub Twilight_getWeatherHorizon(@)
{
my ($hash, $result) = @_;
my $location=$hash->{WEATHER};
if ($location == 0) {
$hash->{WEATHER_HORIZON}="0";
$hash->{CONDITION}="0";
$hash->{CONDITION}="0";
return 1;
}
}
my $mod = "[".$hash->{NAME} ."] ";
my @faktor_cond_code = (10,10,10,10, 9, 7, 7, 7, 7, 7,
@ -504,39 +505,39 @@ sub Twilight_getWeatherHorizon(@)
my ($cond_code, $cond_txt, $temperatur, $aktTemp);
if (defined($result)) {
# ersetze in result(json) ": durch "=>
# dadurch entsteht ein Perlausdruck, der direkt geparst werden kann
my $perlAusdruck = $result;
#$perlAusdruck = "<h1>could";
$perlAusdruck =~ s/("[\w ]+")(\s*)(:)/$1=>/g;
$perlAusdruck =~ s/null/undef/g;
$perlAusdruck =~ s/true/1/g;
$perlAusdruck =~ s/false/0/g;
$perlAusdruck = 'return ' .$perlAusdruck;
$perlAusdruck = 'return ' .$perlAusdruck;
my $anonymSub = eval "sub {$perlAusdruck}";
Log3 $hash, 3, "[$hash->{NAME}] error $@ parsing $result" if($@);
if (!$@) {
my $resHash = $anonymSub->() if ($anonymSub gt "");
my $resHash = $anonymSub->() if ($anonymSub gt "");
Log3 $hash, 3, "[$hash->{NAME}] error $@ parsing $result" if($@);
#Log3 $hash, 3, "jsonAsPerl". Dumper $resHash->{query}{results}{channel}{item}{condition};
if (!$@) {
$cond_code = $resHash->{query}{results}{channel}{item}{condition}{code};
$cond_txt = $resHash->{query}{results}{channel}{item}{condition}{text};
$temperatur = $resHash->{query}{results}{channel}{item}{condition}{temp};
}
}
}
}
# wenn kein Code ermittelt werden kann, wird ein Pseudocode gesetzt
if (!defined($cond_code) ) {
$cond_code = "50"; # eigener neutraler Code
$cond_txt = "undefined";
$temperatur = "undefined";
} else {
} else {
$hash->{WEATHER_CORRECTION} = $faktor_cond_code[$cond_code] / 25 * 20;
$hash->{WEATHER_HORIZON} = $hash->{WEATHER_CORRECTION} + $hash->{INDOOR_HORIZON};
$hash->{CONDITION} = $cond_code;
@ -544,15 +545,15 @@ sub Twilight_getWeatherHorizon(@)
$hash->{TEMPERATUR} = $temperatur;
Log3 $hash, 4, "[$hash->{NAME}] $cond_code=$cond_txt $temperatur, correction: $hash->{WEATHER_CORRECTION}°";
}
my $doy = strftime("%j",localtime);
my $doy = strftime("%j",localtime);
my $declination = 0.4095*sin(0.016906*($doy-80.086));
if($hash->{WEATHER_HORIZON} > (89-$hash->{LATITUDE}+$declination) ){
$hash->{WEATHER_HORIZON} = 89-$hash->{LATITUDE}+$declination;
}
return 1;
}
################################################################################
sub Twilight_sunpos($)
@ -640,7 +641,7 @@ sub Twilight_sunpos($)
my $twilight = int(($dElevation+12.0)/18.0 * 1000)/10;
$twilight = 100 if ($twilight>100);
$twilight = 0 if ($twilight< 0);
my $twilight_weather ;
if( (my $ExtWeather = AttrVal($hashName, "useExtWeather", "")) eq "") {
@ -648,17 +649,17 @@ sub Twilight_sunpos($)
Log3 $hash, 5, "[$hash->{NAME}] " . "Original weather readings";
} else {
my($extDev,$extReading) = split(":",$ExtWeather);
my $extWeatherHorizont = ReadingsVal($extDev,$extReading,-1);
my $extWeatherHorizont = ReadingsVal($extDev,$extReading,-1);
if ($extWeatherHorizont >= 0){
$extWeatherHorizont = 100 if ($extWeatherHorizont > 100);
Log3 $hash, 5, "[$hash->{NAME}] " . "New weather readings from: ".$extDev.":".$extReading.":".$extWeatherHorizont;
Log3 $hash, 5, "[$hash->{NAME}] " . "New weather readings from: ".$extDev.":".$extReading.":".$extWeatherHorizont;
$twilight_weather = $twilight - int(0.007 * ($extWeatherHorizont ** 2)); ## SCM: 100% clouds => 30% light (rough estimation)
} else {
$twilight_weather = int(($dElevation-$hash->{WEATHER_HORIZON}+12.0)/18.0 * 1000)/10;
Log3 $hash, 3, "[$hash->{NAME}] " . "Error with external readings from: ".$extDev.":".$extReading." , taking original weather readings";
Log3 $hash, 3, "[$hash->{NAME}] " . "Error with external readings from: ".$extDev.":".$extReading." , taking original weather readings";
}
}
}
$twilight_weather = 100 if ($twilight_weather>100);
$twilight_weather = 0 if ($twilight_weather< 0);
@ -759,7 +760,7 @@ sub twilight($$$$) {
<br><br>
<b>indoor_horizon</b>
<br>
The parameter <b>indoor_horizon</b> gives a virtual horizon, that shall be used for calculation of indoor twilight. Minimal value -6 means indoor values are the same like civil values.
The parameter <b>indoor_horizon</b> gives a virtual horizon, that shall be used for calculation of indoor twilight. Minimal value -6 means indoor values are the same like civil values.
indoor_horizon 0 means indoor values are the same as real values. indoor_horizon > 0 means earlier indoor sunset resp. later indoor sunrise.
<br><br>
<b>Weather_Position</b>
@ -899,8 +900,8 @@ Example:
<br><br>
<b>indoor_horizon</b>
<br>
Der Parameter <b>indoor_horizon</b> bestimmt einen virtuellen Horizont, der f&uuml;r die Berechnung der D&auml;mmerung innerhalb von R&auml;men genutzt werden kann. Minimalwert ist -6 (ergibt gleichen Wert wie Zivile D&auml;mmerung). Bei 0 fallen
indoor- und realer D&aumlmmerungswert zusammen. Werte gr&oumlsser 0 ergeben fr&uumlhere Werte für den Abend bzw. sp&aumltere f&uumlr den Morgen.
Der Parameter <b>indoor_horizon</b> bestimmt einen virtuellen Horizont, der f&uuml;r die Berechnung der D&auml;mmerung innerhalb von R&auml;men genutzt werden kann. Minimalwert ist -6 (ergibt gleichen Wert wie Zivile D&auml;mmerung). Bei 0 fallen
indoor- und realer D&aumlmmerungswert zusammen. Werte gr&oumlsser 0 ergeben fr&uumlhere Werte für den Abend bzw. sp&aumltere f&uumlr den Morgen.
<br><br>
<b>Weather_Position</b>
<br>
@ -925,7 +926,7 @@ Example:
<b>Azimut, Elevation, Twilight (Seitenwinkel, Höhenwinkel, D&auml;mmerung)</b>
<br>
Das Modul berechnet zus&auml;tzlich Azimuth und Elevation der Sonne. Diese Werte k&ouml;nnen zur Rolladensteuerung verwendet werden.<br><br>
Das Reading <b>Twilight</b> wird als neuer "(twi)light" Wert hinzugef&uuml;gt. Er wird aus der Elevation der Sonne mit folgender Formel abgeleitet: (Elevation+12)/18 * 100). Das erlaubt eine detailliertere Kontrolle der Lampen w&auml;hrend Sonnenauf - und untergang. Dieser Wert ist zwischen 0% und 100% wenn die Elevation zwischen -12&deg; und 6&deg;
<br><br>
@ -990,7 +991,7 @@ Wissenswert dazu ist, dass die Sonne, abh&auml;gnig vom Breitengrad, bestimmte E
<li><b>useExtWeather &lt;device&gt;:&lt;reading&gt;</b></li>
Nutzt Daten von einem anderen Device um <b>twilight_weather</b> zu berechnen.<br/>
Das Reading sollte sich im Intervall zwischen 0 und 100 bewegen, z.B. das Reading <b>c_clouds</b> in einem<b><a href="#openweathermap">openweathermap</a></b> device, bei dem 0 heiteren und 100 bedeckten Himmel bedeuten.
Wird diese Attribut genutzt , werden Wettereffekte wie Starkregen oder Gewitter fuer die Berechnung von <b>twilight_weather</b> nicht mehr herangezogen.
Wird diese Attribut genutzt , werden Wettereffekte wie Starkregen oder Gewitter fuer die Berechnung von <b>twilight_weather</b> nicht mehr herangezogen.
</ul>
<br>

View File

@ -3,6 +3,7 @@
#
# 98_Heating_Control.pm
# written by Dietmar Ortmann
# Maintained by igami since 02-2018
#
# This file is part of fhem.
#
@ -36,7 +37,7 @@ sub Heating_Control_Initialize($)
# Consumer
$hash->{SetFn} = "Heating_Control_Set";
$hash->{AttrFn} = "Heating_Control_Attr";
$hash->{AttrFn} = "Heating_Control_Attr";
$hash->{DefFn} = "Heating_Control_Define";
$hash->{UndefFn} = "Heating_Control_Undef";
$hash->{GetFn} = "Heating_Control_Get";
@ -47,21 +48,21 @@ sub Heating_Control_Initialize($)
################################################################################
sub Heating_Control_Set($@) {
my ($hash, @a) = @_;
return "no set value specified" if(int(@a) < 2);
return "Unknown argument $a[1], choose one of enable disable " if($a[1] eq "?");
my $name = shift @a;
my $v = join(" ", @a);
Log3 $hash, 3, "[$name] set $name $v";
if ($v eq "enable") {
fhem("attr $name disable 0");
fhem("attr $name disable 0");
} elsif ($v eq "disable") {
fhem("attr $name disable 1");
fhem("attr $name disable 1");
}
return undef;
return undef;
}
########################################################################
sub Heating_Control_Get($@) {
@ -92,8 +93,8 @@ sub Heating_Control_SetTimerOfDay($) {
########################################################################
sub Heating_Control_Attr($$$$) {
my ($cmd, $name, $attrName, $attrVal) = @_;
WeekdayTimer_Attr($cmd, $name, $attrName, $attrVal);
WeekdayTimer_Attr($cmd, $name, $attrName, $attrVal);
return undef;
}
########################################################################
@ -101,15 +102,15 @@ sub Heating_Control_SetTimer($) {
my ($hash) = @_;
WeekdayTimer_DeleteTimer($hash);
WeekdayTimer_SetTimer($hash);
}
}
########################################################################
sub Heating_Control_SetTemp($) {
my ($name) = @_;
my $hash = $modules{Heating_Control}{defptr}{$name};
if(defined $hash) {
Heating_Control_SetTimer($hash);
}
}
}
########################################################################
sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
@ -170,12 +171,12 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<ul><b>profile</b><br>
Define the weekly profile. All timings are separated by space. A switchingtime is defined
by the following example: <br><br>
<ul><b>[&lt;weekdays&gt;|]&lt;time&gt;|&lt;parameter&gt;</b></ul><br>
<u>weekdays:</u> optional, if not set every day of the week is used.<br>
Otherwise you can define a day with its number or its shortname.<br>
<ul>
<ul>
<li>0,su sunday</li>
<li>1,mo monday</li>
<li>2,tu tuesday</li>
@ -236,26 +237,26 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<code>define HeizStatus2 notify Heating:. * {Heating_Control_SetAllTemps()}</code>
<br><p>
Some definitions without comment:
<code><pre>
define hc Heating_Control HeizungKueche de 7|23:35|25 34|23:30|22 23:30|16 23:15|22 8|23:45|16
define hc Heating_Control HeizungKueche de fr,$we|23:35|25 34|23:30|22 23:30|16 23:15|22 12|23:45|16
define hc Heating_Control HeizungKueche de 20:35|25 34|14:30|22 21:30|16 21:15|22 12|23:00|16
define hw Heating_Control HeizungKueche de mo-so, $we|{sunrise_abs_dat($date)}|18 mo-so, $we|{sunset_abs_dat($date)}|22
define ht Heating_Control HeizungKueche de mo-so,!$we|{sunrise_abs_dat($date)}|18 mo-so,!$we|{sunset_abs_dat($date)}|22
define hh Heating_Control HeizungKueche de {sunrise_abs_dat($date)}|19 {sunset_abs_dat($date)}|21
define hx Heating_Control HeizungKueche de 22:35|25 23:00|16
</code></pre>
the list of days can be set globaly for the whole Heating_Control:<p>
<code><pre>
define HeizungWohnen_an_wt Heating_Control HeizungWohnen de !$we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de $we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 78 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 57 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de fr,$we 09:00|19 (heizungAnAus("Ein"))
define hc Heating_Control HeizungKueche de 7|23:35|25 34|23:30|22 23:30|16 23:15|22 8|23:45|16
define hc Heating_Control HeizungKueche de fr,$we|23:35|25 34|23:30|22 23:30|16 23:15|22 12|23:45|16
define hc Heating_Control HeizungKueche de 20:35|25 34|14:30|22 21:30|16 21:15|22 12|23:00|16
define hw Heating_Control HeizungKueche de mo-so, $we|{sunrise_abs_dat($date)}|18 mo-so, $we|{sunset_abs_dat($date)}|22
define ht Heating_Control HeizungKueche de mo-so,!$we|{sunrise_abs_dat($date)}|18 mo-so,!$we|{sunset_abs_dat($date)}|22
define hh Heating_Control HeizungKueche de {sunrise_abs_dat($date)}|19 {sunset_abs_dat($date)}|21
define hx Heating_Control HeizungKueche de 22:35|25 23:00|16
</code></pre>
the list of days can be set globaly for the whole Heating_Control:<p>
<code><pre>
define HeizungWohnen_an_wt Heating_Control HeizungWohnen de !$we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de $we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 78 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 57 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de fr,$we 09:00|19 (heizungAnAus("Ein"))
</code></pre>
An example to be able to temporarily boost the temperature for one hour:
@ -267,9 +268,9 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
define HeatingBath_Boost dummy
attr HeatingBath_Boost setList state:0,23,24,25
attr HeatingBath_Boost webCmd state
define di_ResetBoostBath DOIF ([HeatingBath_Boost] > 0)
({Heating_Control_SetAllTemps()}, defmod di_ResetBoostBath_Reset at +01:00:00 set HeatingBath_Boost 0)
DOELSE
define di_ResetBoostBath DOIF ([HeatingBath_Boost] > 0)
({Heating_Control_SetAllTemps()}, defmod di_ResetBoostBath_Reset at +01:00:00 set HeatingBath_Boost 0)
DOELSE
({Heating_Control_SetAllTemps()})
attr di_ResetBoostBath do always
</code></pre>
@ -288,7 +289,7 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
</code></pre>
Now you can set "HeatingBath_Boost" in the web interface for a one-hour boost of 3 degrees in the bath.
(you can trigger that using the PRESENCE function using your girlfriend's device... grin).
Easy to extend this with a vacation timer using another dummy variable, here <code>VacationTemp</code>.<br>
Then you can use the command
<code>defmod defVacationEnd at 2016-12-30T00:00:00 set VacationTemp off, {Heating_Control_SetAllTemps()}</code>
@ -308,7 +309,7 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
}
</code></pre>
Pray that the device does not restart during your vacation, as the <code>define defVacationEnd ... at </code> is volatile and will be lost at restart!
</ul>
</ul>
@ -321,32 +322,32 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<a name="Heating_ControlLogattr"></a>
<b>Attributes</b>
<ul>
<li>delayedExecutionCond <br>
defines a delay Function. When returning true, the switching of the device is delayed until the function retruns a false value. The behavior is just like a windowsensor.
<li>delayedExecutionCond <br>
defines a delay Function. When returning true, the switching of the device is delayed until the function retruns a false value. The behavior is just like a windowsensor.
<br><br>
<b>Example:</b>
<pre>
attr hc delayedExecutionCond isDelayed("%HEATING_CONTROL","%WEEKDAYTIMER","%TIME","%NAME","%EVENT")
attr hc delayedExecutionCond isDelayed("%HEATING_CONTROL","%WEEKDAYTIMER","%TIME","%NAME","%EVENT")
</pre>
the parameters %HEATING_CONTROL(timer name) %TIME %NAME(device name) %EVENT are replaced at runtime by the correct value.
<br><br>
<b>Example of a function:</b>
<b>Example of a function:</b>
<pre>
sub isDelayed($$$$$) {
my($hc, $wdt, $tim, $nam, $event ) = @_;
my $theSunIsStillshining = ...
return ($tim eq "16:30" && $theSunIsStillshining) ;
return ($tim eq "16:30" && $theSunIsStillshining) ;
}
</pre>
</pre>
</li>
<li>switchInThePast<br>
<li>switchInThePast<br>
defines that the depending device will be switched in the past in definition and startup phase when the device is not recognized as a heating.
Heatings are always switched in the past.
</li>
</li>
<li><a href="#disable">disable</a></li>
<li><a href="#event-on-update-reading">event-on-update-reading</a></li>
@ -404,19 +405,19 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<u>Wochentage:</u> optionale Angabe, falls nicht gesetzt wird der Schaltpunkt jeden Tag ausgef&uumlhrt.
F&uumlr die Tage an denen dieser Schaltpunkt aktiv sein soll, ist jeder Tag mit seiner
Tagesnummer (Mo=1, ..., So=0) oder Name des Tages (Mo, Di, ..., So) einzusetzen.<br><br>
<ul>
<ul>
<li>0,so Sonntag</li>
<li>1,mo Montag</li>
<li>2,di Dienstag</li>
<li>3,mi Mittwoch</li>
<li>4 ...</li>
<li>7,$we Wochenende ($we)</li>
<li>8,!$we Wochentag (!$we)</li>
<li>8,!$we Wochentag (!$we)</li>
</ul><br>
Es ist m&oumlglich $we or !$we in der Tagesliste zu definieren.
Es ist m&oumlglich $we or !$we in der Tagesliste zu definieren.
So ist es auf einfache Art m&oumlglich die Schaltzeitpunkte f&uumlr das Wochenende oder Wochetage zu definieren.
$we und!$we werden als 7 bzw. 8 spezifiziert, wenn die numerische Variante der Tagesliste gew&aumlhlt wird.<br><br>
<u>Uhrzeit:</u>Angabe der Uhrzeit zu der geschaltet werden soll, Format: HH:MM:[SS](HH im 24 Stunden Format) oder eine Perlfunction wie {sunrise_abs()}.
$we und!$we werden als 7 bzw. 8 spezifiziert, wenn die numerische Variante der Tagesliste gew&aumlhlt wird.<br><br>
<u>Uhrzeit:</u>Angabe der Uhrzeit zu der geschaltet werden soll, Format: HH:MM:[SS](HH im 24 Stunden Format) oder eine Perlfunction wie {sunrise_abs()}.
In {} kannst du die Variable $date(epoch) nutzen, um die Schaltzeiten der Woche zu berechnen. Beispiel: {sunrise_abs_dat($date)}<br><br>
<u>Parameter:</u>Angabe der zu setzenden Temperatur als Zahl mit Format 99.9 oder als symbolische Konstante <b>eco</b>
@ -468,24 +469,24 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<code>define HeizStatus2 notify Heizung:.* {Heating_Control_SetAllTemps()}</code>
<br><p>
Einige Definitionen ohne weitere Erkl&aumlrung:
<code><pre>
define hc Heating_Control HeizungKueche de 7|23:35|25 34|23:30|22 23:30|16 23:15|22 8|23:45|16
define hc Heating_Control HeizungKueche de fr,$we|23:35|25 34|23:30|22 23:30|16 23:15|22 12|23:45|16
define hc Heating_Control HeizungKueche de 20:35|25 34|14:30|22 21:30|16 21:15|22 12|23:00|16
define hw Heating_Control HeizungKueche de mo-so, $we|{sunrise_abs_dat($date)}|18 mo-so, $we|{sunset_abs_dat($date)}|22
define ht Heating_Control HeizungKueche de mo-so,!$we|{sunrise_abs_dat($date)}|18 mo-so,!$we|{sunset_abs_dat($date)}|22
define hh Heating_Control HeizungKueche de {sunrise_abs_dat($date)}|19 {sunset_abs_dat($date)}|21
define hx Heating_Control HeizungKueche de 22:35|25 23:00|16
<code><pre>
define hc Heating_Control HeizungKueche de 7|23:35|25 34|23:30|22 23:30|16 23:15|22 8|23:45|16
define hc Heating_Control HeizungKueche de fr,$we|23:35|25 34|23:30|22 23:30|16 23:15|22 12|23:45|16
define hc Heating_Control HeizungKueche de 20:35|25 34|14:30|22 21:30|16 21:15|22 12|23:00|16
define hw Heating_Control HeizungKueche de mo-so, $we|{sunrise_abs_dat($date)}|18 mo-so, $we|{sunset_abs_dat($date)}|22
define ht Heating_Control HeizungKueche de mo-so,!$we|{sunrise_abs_dat($date)}|18 mo-so,!$we|{sunset_abs_dat($date)}|22
define hh Heating_Control HeizungKueche de {sunrise_abs_dat($date)}|19 {sunset_abs_dat($date)}|21
define hx Heating_Control HeizungKueche de 22:35|25 23:00|16
</code></pre>
Die Tagesliste kann global f&uumlr das ganze Heating_Control angegeben werden:<p>
<code><pre>
define HeizungWohnen_an_wt Heating_Control HeizungWohnen de !$we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de $we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 78 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 57 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de fr,$we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_wt Heating_Control HeizungWohnen de !$we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de $we 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 78 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de 57 09:00|19 (heizungAnAus("Ein"))
define HeizungWohnen_an_we Heating_Control HeizungWohnen de fr,$we 09:00|19 (heizungAnAus("Ein"))
</code></pre>
es ist möglich den Parameter als Perlcode zu spezifizieren:<p>
@ -493,12 +494,12 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
... 7|23:35|{getParameter(13,"this")} 7|23:36|{getParameter(14,"that")}
</code></pre>
ein detailiertes Beispiel ist in Heating_Control(EN) beschrieben<p>
</ul>
</ul>
<a name="Heating_Controlset"></a>
<b>Set</b>
<b>Set</b>
<code><b><font size="+1">set &lt;name&gt; &lt;value&gt;</font></b></code>
<br><br>
@ -513,7 +514,7 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<code>set hc disable</code><br>
<code>set hc enable</code><br>
</ul>
</ul>
</ul>
<a name="Heating_Controlget"></a>
<b>Get</b> <ul>N/A</ul><br>
@ -522,33 +523,33 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
<b>Attributes</b>
<ul>
<li>delayedExecutionCond <br>
definiert eine Veroegerungsfunktion. Wenn die Funktion wahr liefert, wird die Schaltung des Geraets solage verzoegert, bis die Funktion wieder falsch liefert. Das Verhalten entspricht einem Fensterkontakt.
definiert eine Veroegerungsfunktion. Wenn die Funktion wahr liefert, wird die Schaltung des Geraets solage verzoegert, bis die Funktion wieder falsch liefert. Das Verhalten entspricht einem Fensterkontakt.
<br><br>
<b>Beispiel:</b>
<b>Beispiel:</b>
<pre>
attr wd delayedExecutionCond isDelayed("$HEATING_CONTROL","$WEEKDAYTIMER","$TIME","$NAME","$EVENT")
attr wd delayedExecutionCond isDelayed("$HEATING_CONTROL","$WEEKDAYTIMER","$TIME","$NAME","$EVENT")
</pre>
Die Parameter $HEATING_CONTROL(timer Name) $TIME $NAME(device Name) $EVENT werden zur Laufzeit durch die echten Werte ersetzt.
<br><br>
<b>Beispielfunktion:</b>
<b>Beispielfunktion:</b>
<pre>
sub isDelayed($$$$$) {
my($hc, $wdt, $tim, $nam, $event ) = @_;
my $theSunIsStillshining = ...
return ($tim eq "16:30" && $theSunIsStillshining) ;
return ($tim eq "16:30" && $theSunIsStillshining) ;
}
</pre>
</pre>
</li>
<li>switchInThePast<br>
<li>switchInThePast<br>
Definiert, dass ein abh&aumlngiges Ger&aumlt in der Start- oder Definitionsphase mit einem Wert aus der Vergangheit geschaltet wird auch wenn das Ger&aumlt nicht als Heizung erkannt wurde.
Heizungen werden immer mit einem Wert aus der Vergangenheit geschaltet.
</li>
</li>
<li><a href="#disable">disable</a></li>
<li><a href="#event-on-update-reading">event-on-update-reading</a></li>
<li><a href="#event-on-change-reading">event-on-change-reading</a></li>
@ -558,4 +559,3 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
=end html_DE
=cut

View File

@ -3,6 +3,7 @@
#
# 98_RandomTimer_Initialize.pm
# written by Dietmar Ortmann
# Maintained by igami since 02-2018
#
# This file is part of fhem.
#
@ -96,7 +97,7 @@ sub RandomTimer_Define($$)
if(!($timeToSwitch =~ m/^[0-9]{2,4}$/i));
RandomTimer_setSwitchmode ($hash, "800/200") if (!defined $hash->{helper}{SWITCHMODE});
$hash->{NAME} = $name;
$hash->{DEVICE} = $device;
$hash->{helper}{TIMESPEC_START} = $timespec_start;
@ -107,11 +108,11 @@ sub RandomTimer_Define($$)
$hash->{helper}{S_REP} = $srep;
$hash->{helper}{S_REL} = $srel;
$hash->{COMMAND} = Value($hash->{DEVICE});
#$attr{$name}{verbose} = 4;
readingsSingleUpdate ($hash, "TimeToSwitch", $hash->{helper}{TIMETOSWITCH}, 1);
myRemoveInternalTimer("SetTimer", $hash);
myInternalTimer ("SetTimer", time(), "RandomTimer_SetTimer", $hash, 0);
@ -125,50 +126,50 @@ sub RandomTimer_SetTimer($) {
my $now = time();
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
RandomTimer_setActive($hash, 0);
RandomTimer_schaltZeitenErmitteln($hash, $now);
RandomTimer_setState($hash);
Log3 $hash, 4, "[".$hash->{NAME}."]" . " timings RandomTimer on $hash->{DEVICE}: "
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{startTime})) . " - "
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{stopTime}));
my $secToMidnight = 24*3600 -(3600*$hour + 60*$min + $sec);
my $setExecTime = max($now, $hash->{helper}{startTime});
myRemoveInternalTimer("Exec", $hash);
myInternalTimer ("Exec", $setExecTime, "RandomTimer_Exec", $hash, 0);
if ($hash->{helper}{REP} gt "") {
my $setTimerTime = max($now+$secToMidnight + 15,
my $setTimerTime = max($now+$secToMidnight + 15,
$hash->{helper}{stopTime}) + $hash->{helper}{TIMETOSWITCH}+15;
myRemoveInternalTimer("SetTimer", $hash);
myInternalTimer ("SetTimer", $setTimerTime, "RandomTimer_SetTimer", $hash, 0);
}
}
########################################################################
# define Test RandomTimer +00:00:05 Brunnen +00:05:00 60 ;
# attr Test room RandomTimerX ;
# define Test RandomTimer +00:00:05 Brunnen +00:05:00 60 ;
# attr Test room RandomTimerX ;
# attr Test verbose 5 ;
# define ds at +00:00:30 attr Test disable 1 ;
#
# delete RT_Test; define RT_Test RandomTimer *22:00:00 Brunnen 23:00:00 300
# set RT_Test disable 0
# set RT_Test disable 0
# delete RT_Test
sub RandomTimer_Exec($) {
my ($myHash) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash));
my $now = time();
# Wenn aktiv aber disabled, dann timer abschalten, Meldung ausgeben.
my $active = RandomTimer_isAktive($hash);
my $disabled = RandomTimer_isDisabled($hash);
my $stopTimeReached = RandomTimer_stopTimeReached($hash);
if ($active) {
# wenn temporär ausgeschaltet
if ($disabled) {
@ -207,16 +208,16 @@ sub RandomTimer_Exec($) {
RandomTimer_setActive($hash,0);
return;
}
if (!$disabled) {
if (!$disabled) {
if ($now>$hash->{helper}{startTime} && $now<$hash->{helper}{stopTime}) {
Log3 $hash, 3, "[".$hash->{NAME}."]"." starting RandomTimer on $hash->{DEVICE}: "
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{startTime})) . " - "
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{stopTime}));
RandomTimer_setActive($hash,1);
}
}
}
}
RandomTimer_setState($hash);
if ($now>$hash->{helper}{startTime} && $now<$hash->{helper}{stopTime}) {
RandomTimer_device_toggle($hash) if (!$disabled);
@ -254,7 +255,7 @@ sub RandomTimer_down($) {
########################################################################
sub RandomTimer_setState($) {
my ($hash) = @_;
if (RandomTimer_isDisabled($hash)) {
#$hash->{STATE} = "disabled";
readingsSingleUpdate ($hash, "state", "disabled", 0);
@ -262,20 +263,20 @@ sub RandomTimer_setState($) {
my $state = $hash->{helper}{active} ? "on" : "off";
readingsSingleUpdate ($hash, "state", $state, 1);
}
}
########################################################################
sub RandomTimer_Attr($$$) {
my ($cmd, $name, $attrName, $attrVal) = @_;
my $hash = $defs{$name};
if( $attrName ~~ ["switchmode"] ) {
RandomTimer_setSwitchmode($hash, $attrVal);
}
if( $attrName ~~ ["disable","disableCond"] ) {
# Schaltung vorziehen, damit bei einem disable abgeschaltet wird.
myRemoveInternalTimer("Exec", $hash);
myInternalTimer ("Exec", time()+1, "RandomTimer_Exec", $hash, 0);
@ -288,7 +289,7 @@ sub RandomTimer_setSwitchmode ($$) {
my ($hash, $attrVal) = @_;
my $mod = "[".$hash->{NAME} ."] ";
if(!($attrVal =~ m/^([0-9]{1,3})\/([0-9]{1,3})$/i)) {
Log3 undef, 3, $mod . "invalid switchMode <$attrVal>, use 999/999";
} else {
@ -317,7 +318,7 @@ sub RandomTimer_schaltZeitenErmitteln ($$) {
RandomTimer_startZeitErmitteln($hash, $now);
RandomTimer_stopZeitErmitteln ($hash, $now);
readingsBeginUpdate($hash);
readingsBulkUpdate ($hash, "Startzeit", FmtDateTime($hash->{helper}{startTime}));
readingsBulkUpdate ($hash, "Stoppzeit", FmtDateTime($hash->{helper}{stopTime}));
@ -385,7 +386,7 @@ sub RandomTimer_stopZeitErmitteln ($$) {
} else {
$stopTime = RandomTimer_zeitBerechnen($now, $hour, $min, $sec);
}
if (!AttrVal($hash->{NAME}, "forceStoptimeSameDay", 0)) {
if ($hash->{helper}{startTime} > $stopTime) {
$stopTime = RandomTimer_addDays($stopTime, 1);
@ -403,9 +404,9 @@ sub RandomTimer_device_toggle ($) {
if ($status ne "on" && $status ne "off" ) {
Log3 $hash, 3, "[".$hash->{NAME}."]"." result of function Value($hash->{DEVICE}) must be 'on' or 'off'";
}
my $sigma = ($status eq "on")
? $hash->{helper}{SIGMAWHENON}
my $sigma = ($status eq "on")
? $hash->{helper}{SIGMAWHENON}
: $hash->{helper}{SIGMAWHENOFF};
my $zufall = int(rand(1000));
@ -413,13 +414,13 @@ sub RandomTimer_device_toggle ($) {
if ($zufall < $sigma ) {
$hash->{COMMAND} = ($status eq "on") ? "off" : "on";
RandomTimer_device_switch($hash);
RandomTimer_device_switch($hash);
}
}
########################################################################
sub RandomTimer_device_switch ($) {
my ($hash) = @_;
my $command = "set @ $hash->{COMMAND}";
if ($hash->{COMMAND} eq "on") {
$command = AttrVal($hash->{NAME}, "onCmd", $command);
@ -438,17 +439,17 @@ sub RandomTimer_device_switch ($) {
########################################################################
sub RandomTimer_isDisabled($) {
my ($hash) = @_;
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
return $disable if($disable);
my $disableCond = AttrVal($hash->{NAME}, "disableCond", "nf" );
if ($disableCond eq "nf") {
return 0;
} else {
} else {
$disable = eval ($disableCond);
if ($@) {
$@ =~ s/\n/ /g;
$@ =~ s/\n/ /g;
Log3 ($hash, 3, "[$hash->{NAME}] ERROR: " . $@ . " EVALUATING " . $disableCond);
}
return $disable;
@ -459,7 +460,7 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
foreach my $hc ( sort keys %{$modules{RandomTimer}{defptr}} ) {
my $hash = $modules{RandomTimer}{defptr}{$hc};
my $myHash->{HASH}=$hash;
RandomTimer_SetTimer($myHash);
Log3 undef, 3, "RandomTimer_Wakeup() for $hash->{NAME} done!";
@ -470,7 +471,7 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
1;
=pod
=item device
=item device
=item summary imitates the random switch functionality of a timer clock (FS20 ZSU)
=item summary_DE bildet die Zufallsfunktion einer Zeitschaltuhr nach
=begin html
@ -562,7 +563,7 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
<b>Examples</b>
<pre>
attr ZufallsTimerZ disableCond (!isVerreist())
attr ZufallsTimerZ disableCond (Value("presenceDummy") ne "present")
attr ZufallsTimerZ disableCond (Value("presenceDummy") ne "present")
</pre>
</li>
@ -589,8 +590,8 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
</pre>
</li>
the decision to switch on or off depends on the state of the device and is evaluated by the funktion Value(<device>). Value() must
evaluate one of the values "on" or "off". The behavior of devices that do not evaluate one of those values can be corrected by defining a statFormat:
the decision to switch on or off depends on the state of the device and is evaluated by the funktion Value(<device>). Value() must
evaluate one of the values "on" or "off". The behavior of devices that do not evaluate one of those values can be corrected by defining a statFormat:
<pre>
attr stateFormat EDIPlug_01 {(ReadingsVal("EDIPlug_01","state","nF") =~ m/(ON|on)/i) ? "on" : "off" }
</pre>
@ -598,8 +599,8 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
<pre>
[EDIPlug] result of function Value(EDIPlug_01) must be 'on' or 'off'
</pre>
<li><a name="switchmode">switchmode</a><br>
Setting the switchmode you can influence the behavior of switching on/off.
The parameter has the Format 999/999 and the default ist 800/200. The values are in "per mill".
@ -610,7 +611,7 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
attr ZufallsTimerZ switchmode 400/400
</pre>
</li>
</ul>
=end html
=cut
=cut

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
###############################################################################
# $Id$
# Maintained by igami since 02-2018
#
# TODO
# - document how to include powerMap for other module maintainers

View File

@ -33,7 +33,7 @@ FHEM/00_NetzerI2C.pm klausw Sonstige Systeme
FHEM/00_OWX.pm pahenning 1Wire
FHEM/00_OWX_ASYNC ntruchsess 1Wire
FHEM/00_RPII2C klausw Einplatinencomputer
FHEM/00_SIGNALduino.pm Sidey Sonstige Systeme
FHEM/00_SIGNALduino.pm Sidey Sonstige Systeme
FHEM/00_SONOS.pm Reinerlein Multimedia
FHEM/00_TCM.pm klaus-schauer EnOcean
FHEM/00_THZ.pm immiimmi Heizungssteuerung/Raumklima
@ -272,7 +272,7 @@ FHEM/57_CALVIEW.pm chris1284 Unterstuetzende Dienste/Kalend
FHEM/59_HCS.pm hjr Automatisierung (oder auch PM)
FHEM/59_LuftdatenInfo igami Bastelecke
FHEM/59_OPENWEATHER.pm tupol Unterstuetzende Dienste/Wettermodule (Link als PM an tupol)
FHEM/59_Twilight.pm dietmar63 Unterstuetzende Dienste/Wettermodule
FHEM/59_Twilight.pm igami Unterstuetzende Dienste/Wettermodule
FHEM/59_PROPLANTA.pm tupol Unterstuetzende Dienste/Wettermodule (Link als PM an tupol)
FHEM/59_WWO.pm baumrasen Unterstuetzende Dienste/Wettermodule
FHEM/59_Weather.pm neubert Unterstuetzende Dienste/Wettermodule
@ -414,7 +414,7 @@ FHEM/98_EDIPLUG.pm Wzut Sonstige Systeme
FHEM/98_FReplacer.pm stefanstrobel Sonstiges
FHEM/98_GEOFANCY.pm loredo Unterstuetzende Dienste
FHEM/98_HMinfo.pm martinp876 HomeMatic
FHEM/98_Heating_Control.pm dietmar63 Unterstuetzende Dienste
FHEM/98_Heating_Control.pm igami Unterstuetzende Dienste
FHEM/98_HTTPMOD.pm stefanstrobel Sonstiges
FHEM/98_Arducounter.pm stefanstrobel Sonstiges
FHEM/98_Hyperion.pm DeeSPe Beleuchtung
@ -426,14 +426,14 @@ FHEM/98_ModbusAttr.pm stefanstrobel Sonstiges
FHEM/98_ModbusSET.pm stefanstrobel Sonstiges
FHEM/98_ModbusTrovis5576.pm Reinerlein Heizungssteuerung/Raumklima
FHEM/98_PID20.pm John Automatisierung
FHEM/98_RandomTimer.pm dietmar63 Unterstuetzende Dienste/Kalendermodule
FHEM/98_RandomTimer.pm igami Unterstuetzende Dienste/Kalendermodule
FHEM/98_SVG.pm rudolfkoenig Frontends/SVG/Plots/logProxy
FHEM/98_THRESHOLD.pm damian-s Automatisierung
FHEM/98_TRAFFIC.pm jmike Unterstuetzende Dienste
FHEM/98_UbiquitiPM.pm Wzut Sonstige Systeme
FHEM/98_UbiquitiOut.pm Wzut Sonstige Systeme
FHEM/98_Verkehrsinfo.pm martins Unterstuetzende Dienste
FHEM/98_WeekdayTimer.pm dietmar63 Unterstuetzende Dienste
FHEM/98_WeekdayTimer.pm igami Unterstuetzende Dienste
FHEM/98_WOL.pm dietmar63 Unterstuetzende Dienste
FHEM/98_XmlList.pm rudolfkoenig Automatisierung
FHEM/96_allowed.pm rudolfkoenig Automatisierung
@ -464,7 +464,7 @@ FHEM/98_monitoring.pm igami Automatisierung
FHEM/98_notice.pm mfr69bs Sonstiges
FHEM/98_pilight.pm andreas-fey Unterstuetzende Dienste
FHEM/98_ping mattwire Sonstiges
FHEM/98_powerMap loredo Unterstuetzende Dienste
FHEM/98_powerMap igami Unterstuetzende Dienste
FHEM/98_QRCode.pm Benni Unterstuetzende Dienste
FHEM/98_rain.pm baumrasen Sonstiges
FHEM/98_restore.pm rudolfkoenig Sonstiges