10 Commits

Author SHA1 Message Date
e28ef48fff ...roll: block 2020-10-25 15:02:15 +01:00
20ed00b896 ...check slot down 2020-10-25 15:02:05 +01:00
712b5e112b ...slot aus web 2020-10-25 15:01:23 +01:00
65136e92a0 ...roll-nosundir:hoch schon bei tempO==TEMP_OK 2020-10-25 15:01:01 +01:00
4c4f42b868 ...setRollSlot, sun und sundir getrennt 2020-10-25 15:00:45 +01:00
965c59ca3d ...Rollladen: auf innen sehr warm berücksichtigen 2020-10-25 09:27:55 +01:00
5178706bdb ...roll zusätzliche Temperaturschwelle TEMP_HOT 2020-10-25 09:27:55 +01:00
1868fdaa5f ...roll nicht mehr abh. vom tempI 2020-10-25 09:27:55 +01:00
e2f9c25ef1 ...forecast/refactor 2020-10-25 09:27:55 +01:00
root
2b2210c126 ... 2020-10-25 09:27:55 +01:00

View File

@@ -1,27 +1,26 @@
package main; package main;
use strict; use strict;
use warnings; use warnings;
use POSIX; use POSIX;
use feature "state"; use feature "state";
sub MyUtils_Initialize($$)
{
my ($hash) = @_;
}
use constant { use constant {
STATE_IDLE => 0, STATE_IDLE => 0,
STATE_HOCH => 1, STATE_UP => 1,
STATE_RUNTER => 2, STATE_DOWN => 2,
STATE_SCHLITZ => 3, STATE_SLOT => 3,
}; };
use constant { use constant {
TEMP_IDLE => 0, TEMP_COLD => 0,
TEMP_COLD => 1, TEMP_LOW => 1,
TEMP_LOW => 2, TEMP_OK => 2,
TEMP_HIGH => 3, TEMP_HIGH => 3,
TEMP_HOT => 4,
}; };
my $tempIn_offset = +0;
my $tempOut_offset = +2;
# CheckSkip # CheckSkip
use constant { use constant {
@@ -40,17 +39,17 @@ use constant {
# dir: Himmelsrichtung des Fensters # dir: Himmelsrichtung des Fensters
# typ: n-normal, s-schlaf bis wecken geschlossen, o-nachts offen # typ: n-normal, s-schlaf bis wecken geschlossen, o-nachts offen
my @rolls = ( my @rolls = (
{ roll => "wohn.rollTerrR", dir=>"W", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"wohn.fenTerr", block=>"", state=>STATE_IDLE, }, { roll => "wohn.rollTerrR", dir=>"W", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"wohn.fenTerr", block=>"", },
{ roll => "wohn.rollTerrL", dir=>"W", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "wohn.rollTerrL", dir=>"W", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", },
{ roll => "wohn.rollSofa", dir=>"S", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "wohn.rollSofa", dir=>"S", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", },
{ roll => "ess.roll", dir=>"S", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "ess.roll", dir=>"S", typ=>"n", temp=>"tempWohn", tempSoll=>20, win=>"", block=>"", },
{ roll => "kuch.rollBar", dir=>"S", typ=>"n", temp=>"tempKueche", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "kuch.rollBar", dir=>"S", typ=>"n", temp=>"tempKueche", tempSoll=>20, win=>"", block=>"", },
{ roll => "kuch.rollStr", dir=>"O", typ=>"n", temp=>"tempKueche", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "kuch.rollStr", dir=>"O", typ=>"n", temp=>"tempKueche", tempSoll=>20, win=>"", block=>"", },
{ roll => "arb.rollTerr", dir=>"W", typ=>"n", temp=>"tempStudio", tempSoll=>20, win=>"", block=>"blockRoll", state=>STATE_IDLE, }, { roll => "arb.rollTerr", dir=>"W", typ=>"n", temp=>"tempStudio", tempSoll=>20, win=>"", block=>"blockRoll", },
{ roll => "arb.rollWeg", dir=>"S", typ=>"n", temp=>"tempStudio", tempSoll=>20, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "arb.rollWeg", dir=>"S", typ=>"n", temp=>"tempStudio", tempSoll=>20, win=>"", block=>"", },
{ roll => "bad.roll", dir=>"S", typ=>"n", temp=>"tempBad", tempSoll=>22, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "bad.roll", dir=>"S", typ=>"n", temp=>"tempBad", tempSoll=>22, win=>"", block=>"", },
{ roll => "schlaf.rollWeg", dir=>"S", typ=>"s", temp=>"tempSchlaf", tempSoll=>18, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "schlaf.rollWeg", dir=>"S", typ=>"s", temp=>"tempSchlaf", tempSoll=>18, win=>"", block=>"", },
{ roll => "schlaf.rollStr", dir=>"O", typ=>"so", temp=>"tempSchlaf", tempSoll=>18, win=>"", block=>"", state=>STATE_IDLE, }, { roll => "schlaf.rollStr", dir=>"O", typ=>"so", temp=>"tempSchlaf", tempSoll=>18, win=>"", block=>"", },
); );
@@ -59,10 +58,15 @@ my @blocktime=localtime;
my $blocktimerRunning=0; my $blocktimerRunning=0;
my $delaySec=11; my $delaySec=11;
my $tempIn_offset=0; sub MyUtils_Initialize($$)
my $tempOut_offset=+3; {
my ($hash) = @_;
for my $r (@rolls) {
$r->{btr}=0;
$r->{state} = STATE_IDLE;
}
}
#------------------------------------------
sub myfhem($) sub myfhem($)
{ {
@@ -72,6 +76,14 @@ sub myfhem($)
#------------------------------------------ #------------------------------------------
sub Dbg($) {
if(Value("DebugRoll") eq "1") {
Log 1,$_[0];
}
}
#------------------------------------------
sub findRoll($) sub findRoll($)
{ {
my($name) = @_; my($name) = @_;
@@ -84,12 +96,18 @@ sub findRoll($)
} }
return undef; return undef;
} }
#------------------------------------------ #------------------------------------------
sub Dbg($) { sub SetRollSlot($) {
if(Value("DebugRoll") eq "1") { my($name) = @_;
Log 1,$_[0]; Dbg("SetRollSlot $name");
my $r = findRoll($name);
if (defined $r) {
Dbg("found $r->{roll}");
RollSlot($r, 0);
} }
return undef
} }
#------------------------------------------ #------------------------------------------
@@ -104,21 +122,47 @@ sub getDelayTime($)
#------------------------------------------ #------------------------------------------
sub RollRunterSchlitz($$$) sub RollUpSec($$) {
my ($name, $sec) = @_;
my $st=Value($name);
Dbg("RollUpSec $name State:$st");
#myfhem("set ".$name." up ".$sec);
if ($st eq "closed") { myfhem("set ".$name." up ".$sec); }
else { # noch nicht geschlossen: nochmal versuchen
Dbg("retry $name");
my $t=getDelayTime(39);
my $i=$tc++;
myfhem("set ".$name." closes");
myfhem("define ru".$i." at +".$t." {RollUpSec(\"".${name}."\",6);;}");
}
}
#------------------------------------------
sub RollSlot($$) {
my ($r, $ndelay) = @_;
$ndelay ||= 0;
my $t1=getDelayTime($ndelay*$delaySec);
my $t2=getDelayTime($ndelay*$delaySec+39);
my $i=$tc++;
Dbg("RollChg: $r->{roll} - schlitz($ndelay)\n");
myfhem("define rc".$i." at +".$t1." set ".$r->{roll}." closes");
myfhem("define ru".$i." at +".$t2." {RollUpSec(\"".$r->{roll}."\",6);;}");
}
#------------------------------------------
sub RollSlotState($$$)
{ {
my ($r, $skipRunter, $ndelay) = @_; my ($r, $skipDown, $ndelay) = @_;
$ndelay ||= 0; $ndelay ||= 0;
if ($skipRunter==SKIP_NO || $skipRunter==SKIP_DOWN ) { if (!Value($r->{block}) && ($skipDown==SKIP_NO || $skipDown==SKIP_DOWN) ) {
if ($r->{state}!=STATE_SCHLITZ) { if ($r->{state}!=STATE_SLOT) {
my $t1=getDelayTime($ndelay*$delaySec); RollSlot($r, $ndelay);
my $t2=getDelayTime($ndelay*$delaySec+39); $r->{state}=STATE_SLOT;
my $i=$tc++; SlotBlockStart($r);
Dbg("RollChg: $r->{roll} - runter schlitz($ndelay)\n");
myfhem("define rc".$i." at +".$t1." set ".$r->{roll}." closes");
myfhem("define ru".$i." at +".$t2." set ".$r->{roll}." up 6");
$r->{state}=STATE_SCHLITZ;
return 1; return 1;
} }
} }
@@ -127,19 +171,19 @@ sub RollRunterSchlitz($$$)
#------------------------------------------ #------------------------------------------
sub RollHoch($$$) sub RollUpState($$$)
{ {
my ($r, $skipHoch, $ndelay) = @_; my ($r, $skipUp, $ndelay) = @_;
$ndelay ||= 0; $ndelay ||= 0;
if ($skipHoch==SKIP_NO) { if (!Value($r->{block}) && $skipUp==SKIP_NO) {
if ($r->{state}!=STATE_HOCH) { if ($r->{state}!=STATE_UP) {
my $t1=getDelayTime($ndelay*$delaySec); my $t1=getDelayTime($ndelay*$delaySec);
my $i=$tc++; my $i=$tc++;
Dbg("RollChg: $r->{roll} - hoch($ndelay)\n"); Dbg("RollChg: $r->{roll} - hoch($ndelay)\n");
myfhem("define ro".$i." at +".$t1." set ". $r->{roll} ." opens"); myfhem("define ro".$i." at +".$t1." set ". $r->{roll} ." opens");
$r->{state}=STATE_HOCH; $r->{state}=STATE_UP;
return 1; return 1;
} }
} }
@@ -148,19 +192,19 @@ sub RollHoch($$$)
#------------------------------------------ #------------------------------------------
sub RollRunter($$$) sub RollDownState($$$)
{ {
my ($r, $skipRunter, $ndelay) = @_; my ($r, $skipDown, $ndelay) = @_;
$ndelay ||= 0; $ndelay ||= 0;
if ($skipRunter==SKIP_NO) { if (!Value($r->{block}) && $skipDown==SKIP_NO) {
if ($r->{state}!=STATE_RUNTER) { if ($r->{state}!=STATE_DOWN) {
my $t1=getDelayTime($ndelay*$delaySec); my $t1=getDelayTime($ndelay*$delaySec);
my $i=$tc++; my $i=$tc++;
Dbg("RollChg: $r->{roll} - runter($ndelay)\n"); Dbg("RollChg: $r->{roll} - runter($ndelay)\n");
myfhem("define rc".$i." at +".$t1." set ".$r->{roll}." closes"); myfhem("define rc".$i." at +".$t1." set ".$r->{roll}." closes");
$r->{state}=STATE_RUNTER; $r->{state}=STATE_DOWN;
return 1; return 1;
} }
} }
@@ -225,6 +269,36 @@ sub IsWetterSonneWait($)
#------------------------------------------ #------------------------------------------
sub SlotBlockStart($)
{
my ($r) = @_;
@{$r->{bt}}=localtime;
@{$r->{bt}}[2]+=2; # +2Std
if(@{$r->{bt}}[2]>23) { @{$r->{bt}}[2]=23; } # da nachts keine sonne scheint egal
$r->{btr}=1;
Dbg("Schlitzblockstart $r->{roll}");
}
#------------------------------------------
sub SlotBlockCheck($)
{
my ($r) = @_;
if($r->{btr}) {
if(!IsLater("@{$r->{bt}}[2]:@{$r->{bt}}[1]")) {
Dbg("Schlitz blocked $r->{roll}");
return(0);
} else {
$r->{btr}=0;
Dbg("Schlitzblock End $r->{roll}");
}
}
return(0);
}
#------------------------------------------
# fhem-Variablen 'tag' und 'hell' abhängig vom Sonnenstand setzen
sub setTagHell($$) sub setTagHell($$)
{ {
my ($twil, $light) = @_; my ($twil, $light) = @_;
@@ -242,36 +316,70 @@ sub setTagHell($$)
#------------------------------------------ #------------------------------------------
# Raum zu warm und aussentemp hoch ? # Die maximal für den aktuellen Tag verhergesagte Temperatur bestimmen
sub checkTemps($$$) sub getTempMaxForecast()
{ {
my($temp, $tempOut, $tempSoll)=@_; # aktuellen Wert auch einbeziehen
my $tempI=TEMP_IDLE; my $tempO=TEMP_IDLE; my $max=ReadingsVal("wetter", "tempHigh", 20);
for (my $i=1; $i<=6; $i++) {
my $temp = ReadingsVal("wetter", "hfc".$i."_tempHigh", 20);
if($temp>$max) { $max=$temp; }
#print("i:$i t:$temp, m=$max\n");
}
return $max;
}
if ($temp > $tempSoll+$tempIn_offset+0.5) { $tempI=TEMP_HIGH; } #------------------------------------------
if ($temp < $tempSoll+$tempIn_offset-0.5) { $tempI=TEMP_LOW; }
if ($tempOut > $tempSoll+$tempOut_offset+0.5) { $tempO=TEMP_HIGH; } # Temperaturen klassifizieren
if ($tempOut < $tempSoll+$tempOut_offset-0.5) { $tempO=TEMP_LOW; } sub checkTemps($$$$)
if ($tempOut < $tempSoll+$tempOut_offset-1.5) { $tempO=TEMP_COLD; } {
return($tempI, $tempO); my ($temp, $tempOut, $tempFore, $tempSoll)=@_;
my $tempI=TEMP_OK; my $tempO=TEMP_OK; my $tempF=TEMP_OK;
if ($temp > $tempSoll+$tempIn_offset+2.0) { $tempI=TEMP_HOT; }
if ($temp > $tempSoll+$tempIn_offset+0.5) { $tempI=TEMP_HIGH; }
if ($temp < $tempSoll+$tempIn_offset-0.5) { $tempI=TEMP_LOW; }
if ($tempOut > $tempSoll+$tempOut_offset+2.0) { $tempO=TEMP_HOT; }
if ($tempOut > $tempSoll+$tempOut_offset+1.0) { $tempO=TEMP_HIGH; }
if ($tempOut < $tempSoll+$tempOut_offset-1.0) { $tempO=TEMP_LOW; }
if ($tempOut < $tempSoll+$tempOut_offset-1.5) { $tempO=TEMP_COLD; }
if ($tempFore > $tempSoll+$tempOut_offset+2.0) { $tempF=TEMP_HOT; }
return($tempI, $tempO, $tempF);
} }
#------------------------------------------ #------------------------------------------
# Sonne scheint ins Fenster ? # Sonne scheint ins Fenster ?
sub checkSunIn($$$$$) sub checkSunDir($$$)
{ {
my($twil, $sun_dir, $win_dir, $sunblock, $sunny)=@_; my($twil, $sun_dir, $win_dir)=@_;
# Sonne scheint ins Fenster ? # Sonnenrichtung scheint ins Fenster ?
my $sonne=0; my $dir_in=0;
if($twil>=5 && $twil<7) { # nur, wenn der Sonnenstand ueber 'weather' liegt if($twil>=5 && $twil<7) { # nur, wenn der Sonnenstand über 'weather' liegt
if (index($sun_dir, $win_dir) != -1) { # Sonnenrichtung ins Fenster if (index($sun_dir, $win_dir) != -1) { # Sonnenrichtung ins Fenster
if ($sunblock) { $sonne=1; } $dir_in=1;
if ($sunny) { $sonne=1; }
#Dbg("son3, $sonne");
} }
} }
return $sonne; return $dir_in;
}
# Sonne scheint ?
sub checkSun($$)
{
my($twil, $wett)=@_;
my $sunny = IsSunny($wett);
# Nach wechsel von sonne auf !sonne blockert ?
my $sunblock=IsWetterSonneWait($wett);
my $sun=0;
if($twil>=5 && $twil<7) { # nur, wenn der Sonnenstand ueber 'weather' liegt
if ($sunblock) { $sun=1; }
if ($sunny) { $sun=1; }
#Dbg("son3, $sonne");
}
return $sun;
} }
#------------------------------------------ #------------------------------------------
@@ -284,32 +392,26 @@ sub checkSkip($)
my $wach=Value("wach"); my $wach=Value("wach");
my $winstate=Value($r->{win}); my $winstate=Value($r->{win});
my $typ=$r->{typ}; my $typ=$r->{typ};
my $skipRunter=SKIP_NO; my $skipHoch=SKIP_NO; my $skipDown=SKIP_NO; my $skipUp=SKIP_NO;
if (Value($r->{block})) {
$skipRunter=SKIP_ALL;
$skipHoch=SKIP_ALL;
}
if ($winstate eq "Open") { if ($winstate eq "Open") {
# Offene Fenster nicht mit Rollaeden verschliessen # Offene Fenster nicht mit Rollaeden verschliessen
$skipRunter=SKIP_ALL; $skipDown=SKIP_ALL;
} elsif (index($typ, "o") != -1) { } elsif (index($typ, "o") != -1) {
#Dbg("Skip0: t:$typ w:$winstate r:$skipRunter h:$skipHoch");
# bei typ o nur auf schlitz schliessen # bei typ o nur auf schlitz schliessen
$skipRunter=SKIP_DOWN; #Dbg("Skip0: t:$typ w:$winstate r:$skipRunter h:$skipUp");
$skipDown=SKIP_DOWN;
} }
# Zur Schlafzeit nicht oeffnen
if (index($typ, "s") != -1) { if (index($typ, "s") != -1) {
#Dbg("Skip1: t:$typ w:winstate r:$skipRunter h:$skipHoch"); # Typ s: zur Schlafzeit nicht oeffnen
#Dbg("Skip1: t:$typ w:winstate r:$skipRunter h:$skipUp");
if($wach eq "0") { if($wach eq "0") {
#Dbg("Skip2: t:$typ w:winstate r:$skipRunter h:$skipHoch"); #Dbg("Skip2: t:$typ w:winstate r:$skipDown h:$skipUp");
$skipUp=SKIP_ALL;
$skipHoch=SKIP_ALL;
} }
} }
#Dbg("Skip: t:$typ w:winstate r:$skipRunter h:$skipHoch"); #Dbg("Skip: t:$typ w:winstate r:$skipDown h:$skipUp");
return($skipRunter, $skipHoch); return($skipDown, $skipUp);
} }
#------------------------------------------ #------------------------------------------
@@ -318,56 +420,64 @@ sub RollCheck()
{ {
state $tagalt=0; state $tagalt=0;
state $wachalt=0; state $wachalt=0;
my $r; my $r;
my $ndelay = 0; my $ndelay = 0;
my $tempOut= ReadingsVal("myWH1080", "Temp-outside", 99); my $tempOut = ReadingsVal("myWH1080", "Temp-outside", 40);
my $twil = Value("twil"); my $tempForecast = getTempMaxForecast();
my $light = ReadingsVal("twil", "light", 0); my $twil = Value("twil");
my $wett = ReadingsVal("wetter", "code", 99); my $light = ReadingsVal("twil", "light", 0);
my $wett = ReadingsVal("wetter", "code", 99);
my $sr = Value("sonnenrichtung"); my $sr = Value("sonnenrichtung");
my $sunny = IsSunny($wett);
my $dawn = 0; my $dawn = 0;
setTagHell($twil, $light); setTagHell($twil, $light);
my $tag=Value("tag"); my $tag=Value("tag");
my $wach=Value("wach"); my $wach=Value("wach");
# Nach wechsel von sonne auf !sonne blockert ? my $sun = checkSun($twil, $wett); # Sonne scheint (bleibt true für best. Zeit) ?
my $sonneblock=IsWetterSonneWait($wett);
if($twil>=7) { # ss-weather if($twil>=7) { # ss-weather
$dawn=1; $dawn=1;
} }
for $r ( @rolls ) { for $r ( @rolls ) {
#Dbg("--------r:g ".$r->{roll}." / ".$r->{temp});
my $run=0; my $run=0;
my $tempIn=ReadingsVal($r->{temp},"temperature", 99); my $tempIn = ReadingsVal($r->{temp},"temperature", 99);
my($tempI, $tempO)=checkTemps($tempIn, $tempOut, $r->{tempSoll}); # Temperatur klassifizieren my($tempI, $tempO, $tempF) = checkTemps($tempIn, $tempOut, $tempForecast, $r->{tempSoll}); # Temperatur klassifizieren
my $sunIn=checkSunIn($twil, $sr, $r->{dir}, $sonneblock, $sunny); # Sonne scheint ins Fenster ? my $dirIn = checkSunDir($twil, $sr, $r->{dir}); # Sonne scheint ins Fenster ?
# Offene Fenster nicht mit Rollaeden verschliessen, zur Schlafenszeit nicht öffnen # Offene Fenster nicht mit Rollaeden verschliessen, zur Schlafenszeit nicht öffnen
my ($skipRunter, $skipHoch)=checkSkip($r); my ($skipDown, $skipUp)=checkSkip($r);
# Bedingungen zum Fahren auf Schlitz
my $Hot = $tempO>=TEMP_HOT;
my $WarmSun = $sun && $dirIn && $tempO>=TEMP_HIGH;
my $WarmHotIn = $dirIn && $tempO>=TEMP_HIGH && $tempI>=TEMP_HOT;
my $ForecastHotSun = $sun && $dirIn && $tempF>=TEMP_HOT;
my $ForecastHotWarmIn = $dirIn && $tempF>=TEMP_HOT && $tempI>=TEMP_HIGH;
# Bedingungen zum öffnen (nach Schlitz)
my $Cold = $tempO<=TEMP_COLD;
my $NoSunNotHot = !$dirIn && ($tempO<=TEMP_HIGH || $tempI<=TEMP_OK);
if (!$tag) { if (!$tag) {
$run=RollRunter($r, $skipRunter, $ndelay++); if (index($r->{typ}, "o") != -1) { $run=RollUpState ($r, SKIP_NO, $ndelay++); }
} elsif ($dawn) { else { $run=RollDownState($r, $skipDown, $ndelay++); }
$run=RollHoch($r, $skipHoch, $ndelay++); } elsif ($dawn) { # Abenddämmerung
} elsif ($tempI==TEMP_HIGH $run=RollUpState($r, $skipUp, $ndelay++);
&& ( ( $sunIn && ($tempO>TEMP_COLD)) } elsif ($Hot || $WarmSun || $WarmHotIn || $ForecastHotSun || $ForecastHotWarmIn) {
|| $tempO==TEMP_HIGH $run=RollSlotState($r, $skipDown, $ndelay++);
) } elsif ( $Cold || $NoSunNotHot ) {
) { if(!SlotBlockCheck($r)) { $run=RollUpState($r, $skipUp, $ndelay++); }
$run=RollRunterSchlitz($r, $skipRunter, $ndelay++);
} elsif ( ($tempI==TEMP_LOW && $tempO==TEMP_LOW)
|| (!$sunIn && ($tempO!=TEMP_IDLE && $tempO<TEMP_HIGH))) {
$run=RollHoch($r, $skipHoch, $ndelay++);
} elsif ( ($tag && !$tagalt) || ($wach && !$wachalt) ) { # bei Tagesbeginn hoch } elsif ( ($tag && !$tagalt) || ($wach && !$wachalt) ) { # bei Tagesbeginn hoch
$run=RollHoch($r, $skipHoch, $ndelay++); $run=RollUpState($r, $skipUp, $ndelay++);
} }
if ($run) { if ($run) {
Dbg("RollCheck to:$tempOut twil:$twil light:$light wett:$wett sr:$sr block:$sonneblock\n"); Dbg("RollCheck: H:$Hot WS:$WarmSun WHI:$WarmHotIn FHS:$ForecastHotSun FHI:$ForecastHotWarmIn C:$Cold NSNH:$NoSunNotHot "
Dbg("RollCheck:$r->{roll}-tempLevI,O:$tempI,$tempO tempI,O:$tempIn,$tempOut so:$sunIn wett:$wett sr:$sr " . "to:$tempOut twil:$twil light:$light wett:$wett tomax:$tempForecast "
. "twil:$twil tag:$tag wach:$wach skipR,H:$skipRunter,$skipHoch st:$r->{state}"); . "$r->{roll}-tempLevI,O:$tempI,$tempO tempI,O:$tempIn,$tempOut sun:$sun/$dirIn wett:$wett sr:$sr "
. "twil:$twil tag:$tag/$tagalt wach:$wach/$wachalt skipR,H:$skipDown,$skipUp st:$r->{state} dawn:$dawn");
} }
} # for $r } # for $r
$tagalt=$tag; $tagalt=$tag;
$wachalt=$wach; $wachalt=$wach;
#$sunDiralt=$sunDir
} }
#------------------------------------------ #------------------------------------------