mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 05:06:35 +00:00
MAINTAINER: Maintainer changes
git-svn-id: https://svn.fhem.de/fhem/trunk@16005 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
acd4e7eee3
commit
7a07a71b0f
@ -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ür die Berechnung der Dämmerung innerhalb von Rämen genutzt werden kann. Minimalwert ist -6 (ergibt gleichen Wert wie Zivile Dämmerung). Bei 0 fallen
|
||||
indoor- und realer Dämmerungswert zusammen. Werte grösser 0 ergeben frühere Werte für den Abend bzw. spätere für den Morgen.
|
||||
Der Parameter <b>indoor_horizon</b> bestimmt einen virtuellen Horizont, der für die Berechnung der Dämmerung innerhalb von Rämen genutzt werden kann. Minimalwert ist -6 (ergibt gleichen Wert wie Zivile Dämmerung). Bei 0 fallen
|
||||
indoor- und realer Dämmerungswert zusammen. Werte grösser 0 ergeben frühere Werte für den Abend bzw. spätere für den Morgen.
|
||||
<br><br>
|
||||
<b>Weather_Position</b>
|
||||
<br>
|
||||
@ -925,7 +926,7 @@ Example:
|
||||
<b>Azimut, Elevation, Twilight (Seitenwinkel, Höhenwinkel, Dämmerung)</b>
|
||||
<br>
|
||||
Das Modul berechnet zusätzlich Azimuth und Elevation der Sonne. Diese Werte können zur Rolladensteuerung verwendet werden.<br><br>
|
||||
|
||||
|
||||
Das Reading <b>Twilight</b> wird als neuer "(twi)light" Wert hinzugefügt. Er wird aus der Elevation der Sonne mit folgender Formel abgeleitet: (Elevation+12)/18 * 100). Das erlaubt eine detailliertere Kontrolle der Lampen während Sonnenauf - und untergang. Dieser Wert ist zwischen 0% und 100% wenn die Elevation zwischen -12° und 6°
|
||||
|
||||
<br><br>
|
||||
@ -990,7 +991,7 @@ Wissenswert dazu ist, dass die Sonne, abhägnig vom Breitengrad, bestimmte E
|
||||
<li><b>useExtWeather <device>:<reading></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>
|
||||
|
||||
|
@ -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>[<weekdays>|]<time>|<parameter></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ührt.
|
||||
Für 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öglich $we or !$we in der Tagesliste zu definieren.
|
||||
Es ist möglich $we or !$we in der Tagesliste zu definieren.
|
||||
So ist es auf einfache Art möglich die Schaltzeitpunkte für das Wochenende oder Wochetage zu definieren.
|
||||
$we und!$we werden als 7 bzw. 8 spezifiziert, wenn die numerische Variante der Tagesliste gewählt 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ählt 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ärung:
|
||||
<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ür 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 <name> <value></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ängiges Gerät in der Start- oder Definitionsphase mit einem Wert aus der Vergangheit geschaltet wird auch wenn das Gerät 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
|
||||
|
||||
|
@ -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
@ -1,5 +1,6 @@
|
||||
###############################################################################
|
||||
# $Id$
|
||||
# Maintained by igami since 02-2018
|
||||
#
|
||||
# TODO
|
||||
# - document how to include powerMap for other module maintainers
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user