diff --git a/fhem/FHEM/99_MyUtils.pm b/fhem/FHEM/99_MyUtils.pm index 790b35fb3..fc52e6b74 100644 --- a/fhem/FHEM/99_MyUtils.pm +++ b/fhem/FHEM/99_MyUtils.pm @@ -13,9 +13,9 @@ sub MyUtils_Initialize($$) use constant { STATE_IDLE => 0, - STATE_HOCH => 1, - STATE_RUNTER => 2, - STATE_SCHLITZ => 3, + STATE_UP => 1, + STATE_DOWN => 2, + STATE_SLOT => 3, }; use constant { @@ -26,7 +26,7 @@ use constant { TEMP_HOT => 4, }; my $tempIn_offset = +0; -my $tempOut_offset = +5; +my $tempOut_offset = +2; my $tempOutForecastLimit = 27; # CheckSkip @@ -102,9 +102,10 @@ sub SetRollSlot($) { Dbg("SetRollSlot $name"); my $r = findRoll($name); if (defined $r) { - Dbg("found $r->{name}"); - RollRunterSchlitz($r, SKIP_NO); + Dbg("found $r->{roll}"); + RollSlot($r, SKIP_NO, 0); } + return undef } #------------------------------------------ @@ -119,21 +120,42 @@ 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") { up sec } + # else { down, at +30sec: RollUpSec +} + +#------------------------------------------ + +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." set ".$r->{roll}." up 6"); + myfhem("define ru".$i." at +".$t2." {RollUpSec(\"".$r->{roll}."\",6);;}"); +} + +#------------------------------------------ + +sub RollSlotState($$$) { - my ($r, $skipRunter, $ndelay) = @_; + my ($r, $skipDown, $ndelay) = @_; $ndelay ||= 0; - if ($skipRunter==SKIP_NO || $skipRunter==SKIP_DOWN ) { - if ($r->{state}!=STATE_SCHLITZ) { - my $t1=getDelayTime($ndelay*$delaySec); - my $t2=getDelayTime($ndelay*$delaySec+39); - my $i=$tc++; - - 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; + if ($skipDown==SKIP_NO || $skipDown==SKIP_DOWN ) { + if ($r->{state}!=STATE_SLOT) { + RollSlot($r, $ndelay); + $r->{state}=STATE_SLOT; + SlotBlockStart($r); return 1; } } @@ -142,19 +164,19 @@ sub RollRunterSchlitz($$$) #------------------------------------------ -sub RollHoch($$$) +sub RollUpState($$$) { - my ($r, $skipHoch, $ndelay) = @_; + my ($r, $skipUp, $ndelay) = @_; $ndelay ||= 0; - if ($skipHoch==SKIP_NO) { - if ($r->{state}!=STATE_HOCH) { + if ($skipUp==SKIP_NO) { + if ($r->{state}!=STATE_UP) { my $t1=getDelayTime($ndelay*$delaySec); my $i=$tc++; Dbg("RollChg: $r->{roll} - hoch($ndelay)\n"); myfhem("define ro".$i." at +".$t1." set ". $r->{roll} ." opens"); - $r->{state}=STATE_HOCH; + $r->{state}=STATE_UP; return 1; } } @@ -163,19 +185,19 @@ sub RollHoch($$$) #------------------------------------------ -sub RollRunter($$$) +sub RollDownState($$$) { - my ($r, $skipRunter, $ndelay) = @_; + my ($r, $skipDown, $ndelay) = @_; $ndelay ||= 0; - if ($skipRunter==SKIP_NO) { - if ($r->{state}!=STATE_RUNTER) { + if ($skipDown==SKIP_NO) { + if ($r->{state}!=STATE_DOWN) { my $t1=getDelayTime($ndelay*$delaySec); my $i=$tc++; Dbg("RollChg: $r->{roll} - runter($ndelay)\n"); myfhem("define rc".$i." at +".$t1." set ".$r->{roll}." closes"); - $r->{state}=STATE_RUNTER; + $r->{state}=STATE_DOWN; return 1; } } @@ -238,7 +260,7 @@ sub IsWetterSonneWait($) return(0); } -sub SchlitzBlockStart($) +sub SlotBlockStart($) { my ($r) = @_; @{$r->{bt}}=localtime; @@ -248,7 +270,7 @@ sub SchlitzBlockStart($) Dbg("Schlitzblockstart $r->{roll}"); } -sub SchlitzBlockCheck($) +sub SlotBlockCheck($) { my ($r) = @_; if($r->{btr}) { @@ -299,18 +321,19 @@ sub getTempMaxForecast() #------------------------------------------ # Temperaturen klassifizieren -sub checkTemps($$$) +sub checkTemps($$$$) { - my ($temp, $tempOut, $tempSoll)=@_; - my $tempI=TEMP_OK; my $tempO=TEMP_OK; + my ($temp, $tempOut, $tempFore, $tempSoll)=@_; + my $tempI=TEMP_OK; my $tempO=TEMP_OK; my $tempF=TEMP_OK; - if ($temp > $tempSoll+$tempIn_offset+3.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+4.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 ($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); } @@ -331,9 +354,14 @@ sub checkSunDir($$$) } # Sonne scheint ? -sub checkSun($$$) +sub checkSun($$) { - my($twil, $sunblock, $sunny)=@_; + 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; } @@ -353,31 +381,31 @@ sub checkSkip($) my $wach=Value("wach"); my $winstate=Value($r->{win}); 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; + $skipDown=SKIP_ALL; + $skipUp=SKIP_ALL; } if ($winstate eq "Open") { # Offene Fenster nicht mit Rollaeden verschliessen - $skipRunter=SKIP_ALL; + $skipDown=SKIP_ALL; } elsif (index($typ, "o") != -1) { # bei typ o nur auf schlitz schliessen - #Dbg("Skip0: t:$typ w:$winstate r:$skipRunter h:$skipHoch"); - $skipRunter=SKIP_DOWN; + #Dbg("Skip0: t:$typ w:$winstate r:$skipRunter h:$skipUp"); + $skipDown=SKIP_DOWN; } if (index($typ, "s") != -1) { # Typ s: zur Schlafzeit nicht oeffnen - #Dbg("Skip1: t:$typ w:winstate r:$skipRunter h:$skipHoch"); + #Dbg("Skip1: t:$typ w:winstate r:$skipRunter h:$skipUp"); if($wach eq "0") { - #Dbg("Skip2: t:$typ w:winstate r:$skipRunter h:$skipHoch"); + #Dbg("Skip2: t:$typ w:winstate r:$skipDown h:$skipUp"); - $skipHoch=SKIP_ALL; + $skipUp=SKIP_ALL; } } - #Dbg("Skip: t:$typ w:winstate r:$skipRunter h:$skipHoch"); - return($skipRunter, $skipHoch); + #Dbg("Skip: t:$typ w:winstate r:$skipDown h:$skipUp"); + return($skipDown, $skipUp); } #------------------------------------------ @@ -396,14 +424,12 @@ sub RollCheck() my $wett = ReadingsVal("wetter", "code", 99); my $sr = Value("sonnenrichtung"); - my $sunny = IsSunny($wett); my $dawn = 0; setTagHell($twil, $light); my $tag=Value("tag"); my $wach=Value("wach"); - # Nach wechsel von sonne auf !sonne blockert ? - my $sonneblock=IsWetterSonneWait($wett); + my $sun = checkSun($twil, $wett); # Sonne scheint (bleibt true für best. Zeit) ? if($twil>=7) { # ss-weather $dawn=1; } @@ -411,37 +437,36 @@ sub RollCheck() #Dbg("--------r:g ".$r->{roll}." / ".$r->{temp}); my $run=0; my $tempIn = ReadingsVal($r->{temp},"temperature", 99); - my($tempI, $tempO) = checkTemps($tempIn, $tempOut, $r->{tempSoll}); # Temperatur klassifizieren - my $sun = checkSun($twil,$sonneblock, $sunny); # Sonne scheint (bleibt true für best. Zeit) ? - my $sunDir =checkSunDir($twil, $sr, $r->{dir}); # Sonne scheint ins Fenster ? + my($tempI, $tempO, $tempF) = checkTemps($tempIn, $tempOut, $tempOutForecastLimit, $r->{tempSoll}); # Temperatur klassifizieren + my $dirIn = checkSunDir($twil, $sr, $r->{dir}); # Sonne scheint ins Fenster ? # Offene Fenster nicht mit Rollaeden verschliessen, zur Schlafenszeit nicht öffnen - my ($skipRunter, $skipHoch)=checkSkip($r); - # Bedingungen zum Fahren - my $Hot = $tempO>=TEMP_HOT; - my $WarmSun = $sun && $sunDir && $tempO>=TEMP_HIGH; - my $WarmHotIn = $sunDir && $tempO>=TEMP_HIGH && $tempI>=TEMP_HOT; - my $ForecastHotSun = $sun && $sunDir && $tempOutMaxForecast>=$tempOutForecastLimit; - my $ForecastHotWarmIn = $sunDir && $tempOutMaxForecast>=$tempOutForecastLimit && $tempI>=TEMP_HIGH; - my $Cold = $tempO<=TEMP_COLD; - my $NoSunNotHot = !$sunDir && ($tempO<=TEMP_OK || $tempI<=TEMP_OK); + 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_OK || $tempI<=TEMP_OK); if (!$tag) { - $run=RollRunter($r, $skipRunter, $ndelay++); + $run=RollDownState($r, $skipDown, $ndelay++); } elsif ($dawn) { # Abenddämmerung - $run=RollHoch($r, $skipHoch, $ndelay++); + $run=RollUpState($r, $skipUp, $ndelay++); } elsif ($Hot || $WarmSun || $WarmHotIn || $ForecastHotSun || $ForecastHotWarmIn) { - $run=RollRunterSchlitz($r, $skipRunter, $ndelay++); - if ($run) { SchlitzBlockStart($r); } + $run=RollSlotState($r, $skipDown, $ndelay++); } elsif ( $Cold || $NoSunNotHot ) { - if(!SchlitzBlockCheck($r)) { $run=RollHoch($r, $skipHoch, $ndelay++); } + if(!SlotBlockCheck($r)) { $run=RollUp($r, $skipUp, $ndelay++); } } elsif ( ($tag && !$tagalt) || ($wach && !$wachalt) ) { # bei Tagesbeginn hoch - $run=RollHoch($r, $skipHoch, $ndelay++); + $run=RollUpState($r, $skipUp, $ndelay++); } if ($run) { Dbg("RollCheck: H:$Hot WS:$WarmSun WHI:$WarmHotIn FHS:$ForecastHotSun FHI:$ForecastHotWarmIn C:$Cold NSNH:$NoSunNotHot " - . "to:$tempOut twil:$twil light:$light wett:$wett sr:$sr block:$sonneblock tomax:$tempOutMaxForecast " - . "$r->{roll}-tempLevI,O:$tempI,$tempO tempI,O:$tempIn,$tempOut sun:$sun/$sunDir wett:$wett sr:$sr " - . "twil:$twil tag:$tag/$tagalt wach:$wach/$wachalt skipR,H:$skipRunter,$skipHoch st:$r->{state}"); + . "to:$tempOut twil:$twil light:$light wett:$wett tomax:$tempOutMaxForecast " + . "$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}"); } } # for $r $tagalt=$tag;