FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Spartacus am 18 Dezember 2019, 17:14:31

Titel: DOIF Zeitsteuerung
Beitrag von: Spartacus am 18 Dezember 2019, 17:14:31
Hallo,
ich versuche gerade sämtliche DOIFs etwas zu verschlanken, da es damals viele Funktionen noch nicht gab. Ich habe auch mit dem Folgenden Konstrukt etwas rumgespielt, aber irgendwie bekomme ich keine Lösung an den Start, die funktioniert:

Hier mal die DOIF-Anweisung, die ich etwas einfacher machen möchte, da es nach langer Zeit sehr schwer ist, hier durchzusteigen!
([16:30-[help.01.GA.ss.SA.Licht.dum]] and [help.Tageslicht.dum] eq "dunkel"
                                      and [?help.Tageslicht.dum:SU] lt TimeOffset (OffTimeLicht(),'-30')
                                      and [?switch.di.01.GA.ss.SA.Licht.dum] eq "on")
(set GA.ss.SA.Licht on, set help.01.GA.ss.SA.Licht.dum {(OffTimeLicht())})


getriggert wird zwischen 16:30 und einer  Ausschaltzeit "help.01.GA.ss.SA.Licht.dum", die über "set help.01.GA.ss.SA.Licht.dum {(OffTimeLicht()"  berechnet wird (siehe unten)

Die Dummy-Variable "help.Tageslicht.dum" stellt neben state "hell" und "dunkel" auch noch die Zeiten für Sonnenauf- und Untergang in Readings bereit (SA/SU).

Der Ausdruck  "and [?help.Tageslicht.dum:SU] lt TimeOffset (OffTimeLicht(),'-30')" verhindert, dass die Beleuchtung in den Sommermonaten nur eingeschaltet wird, wenn  zwischen Sonnenuntergang und Abschaltzeit (22:00 Uhr oder 23:00) mindestens 30min liegen (siehe unten)

Meine Abschaltzeiten habe ich schon mal versucht umzustellen, den vorher würde das einfach über "help.01.GA.ss.SA.Licht.dum" erledigt (mit Ausnahme der Silvester-Abschaltung)
DOELSEIF
  (
    ([22:00|01234]  and  [?hl.01.Feiertag] eq "none") or
    ([23:00|59]     and  [?hl.01.Feiertag] ne "Silvester") or
    ([02:00]        and  [?hl.01.Feiertag] eq "Neujahr") and [?switch.di.01.GA.ss.SA.Licht.dum] eq "on")
  (set GA.ss.SA.Licht off)


OfftimeLicht:
sub OffTimeLicht ()
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

if ((ReadingsVal("hl.01.Feiertag","tomorrow","")=~ m/none/) && ($wday =~ m/[01234]/))
{
  return ("22:00:00")
}
elsif ((ReadingsVal("hl.01.Feiertag","tomorrow","") !~ m/none/) || ($wday =~ m/[56]/))
{
  return ("23:00:00")
}
}
1
;

TimeOffset:
sub TimeOffset($;$)

{
    my $PtimeOrg = shift;
    my $Poffset = shift;

    $PtimeOrg = "" unless(defined($PtimeOrg));
    $Poffset  = 0  unless(defined($Poffset));
    my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;

    if ($PtimeOrg !~ /[0-2][0-9]:[0-5][0-9]/ or substr($PtimeOrg,0,2) >= 24) {$PtimeOrg = $hour.":".$min;}

    my $TimeP     = mktime(0,substr($PtimeOrg,3,2),substr($PtimeOrg,0,2),$mday,$month,$year,$wday,$yday,$isdst);
    my $TimePM    = $TimeP + $Poffset * 60;
    my ($Psec,$Pmin,$Phour,$Pmday,$Pmonth,$Pyear,$Pwday,$Pyday,$Pisdst) = localtime($TimePM);
    my $ReturnText = sprintf("%02d:%02d", $Phour, $Pmin);}


Ob das überhaupt funktioniert, weiß ich noch nicht. Hat jemand eine Idee, wie man das Ganze etwas einfacher umbauen kann? Ich habe verstanden, dass DOIF inzwischen mit Offsets umgehen kann, aber bislang sind meine Versuche gescheitert.

Danke,
Spartacus