FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Spartacus am 23 Februar 2015, 20:57:40

Titel: DOIF: Triggerproblem
Beitrag von: Spartacus am 23 Februar 2015, 20:57:40
Hallo,
ich habe hier folgendes DOIF aufgebaut:
nternals:
   CFGFN      config/05-Garten.cfg
   DEF        ([16:30-{OffTimeLicht()}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)
   NAME       di.01.GA.ss.SA.Licht
   NR         498
   NTFY_ORDER 50-di.01.GA.ss.SA.Licht
   STATE      on
   TYPE       DOIF
   Readings:
     2015-02-23 18:03:07   cmd_event       state.TW.Tageslicht.dum
     2015-02-23 18:03:07   cmd_nr          1
     2015-02-23 18:03:07   e_state.TW.Tageslicht.dum_STATE dunkel
     2015-02-23 18:03:07   state           on
     2015-02-23 16:30:00   timer_1_c1      24.02.2015 16:30:00
     2015-02-22 22:00:00   timer_2_c1      23.02.2015 22:00:00
   Condition:
     0          DOIF_time($hash->{realtime}{0},$hash->{realtime}{1},$wday,$hms,"") and  InternalDoIf('state.TW.Tageslicht.dum','STATE','') eq "dunkel" and  ReadingValDoIf('state.TW.Tageslicht.dum','SU','') lt {TimeOffset (OffTimeLicht(),'-30')}
   Days:
   Devices:
     0           state.TW.Tageslicht.dum
     all         state.TW.Tageslicht.dum
   Do:
     0          set GA.ss.SA.Licht on
     1          set GA.ss.SA.Licht off
   Helper:
     last_timer 2
     sleeptimer -1
   Internals:
     0           state.TW.Tageslicht.dum:STATE
     all         state.TW.Tageslicht.dum:STATE
   Readings:
   Realtime:
     0          16:30:00
     1          22:00:00
   State:
   Time:
     0          16:30:00
     1          {OffTimeLicht()}
   Timecond:
     0          0
     1          0
   Timer:
     0          0
     1          0
   Timerfunc:
   Timers:
     0           0  1
   Trigger:
Attributes:
   alias      autom. Gartenlicht
   cmdState   on|off
   devStateIcon .*on:light_light_dim_100@lightgreen .*off:light_light_dim_00@red
   do         always
   group      Scripte
   room       05-Garten
   sortby     01

Getriggert wird hier jeweils um 16:30 und um die Zeit, die in der SUB "OffTimeLicht" berechnet wird. Dass heißt, meine Offtime basiert immer auf den Berechnungen des Vortages. (Timer2 ist von gestern 22:00). Das ist aber schlecht, da ich mit dem Trigger der Einschaltzeit eigentlich auch die aktuelle Ausschaltzeit benötige. gibt es hier eine Methode, wie ich das realisieren kann?
Spartacus
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 17:51:32
Hi,
ich habe nun versucht, die Berechnung der OffTimeLicht in dem Trigger um 16:30 zu berechnen und in einer Variablen zu speichern. my $OffTime= OfftimeLicht() um dann einen Trigger für die Ausschaltzeit zu generieren.
([16:30] {my $OffTime= OfftimeLicht()}) (set Aktor on)
DOELSEIF
([$OffTime)]) (set Aktor off)

Aber diese Logik funzt nicht! Offenbar kann man auf diese variable Zeit nicht triggern!

Hat jemand eine Idee?
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 18:22:52
Zitat von: Spartacus am 24 Februar 2015, 17:51:32
Hi,
ich habe nun versucht, die Berechnung der OffTimeLicht in dem Trigger um 16:30 zu berechnen und in einer Variablen zu speichern. my $OffTime= OfftimeLicht() um dann einen Trigger für die Ausschaltzeit zu generieren.
([16:30] {my $OffTime= OfftimeLicht()}) (set Aktor on)
DOELSEIF
([$OffTime)]) (set Aktor off)

Aber diese Logik funzt nicht! Offenbar kann man auf diese variable Zeit nicht triggern!

Hat jemand eine Idee?
Christian

Wie sieht OfftimeLicht() aus?

Ich würde die Zeitangabe ganz in der perl-fuction berechen, sodass der Returnwert wie folgt aussieht:

hh:mm-hh:mm

und DOIF Define:

([{TimeLicht()}]) (set Aktor on) DOELSE (set Aktor off)
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 19:13:38
Hallo flurin,
das ist ein guter Tipp! Vielen Dank! Allerdings nutze ich die Routine noch dazu um die Schaltschwelle für das Ausschalten einzustellen.

Die Sub TimeOffset ist geklaut und subtrahiert 30min von der Ausschaltzeit. Das soll im Sommer verhindern (?state.TW.Tageslicht.dum:SU=> Zeit des Sonnenuntergangs), dass die Einschaltzeit mindestens 30min vor der Ausschaltzeit liegt um ein zu kurzes Einschalten des Aktors zu vermeiden. Etwas Besseres ist mir hier nicht eingefallen. Wenn ich jetzt in meiner Zeitberechnung "TimeOffLicht" [Start-Ende] zurückgebe, funktioniert mein Offset nicht mehr, oder?

DOIF:
([16:30-{OffTimeLicht()}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)


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

if (ReadingsVal("hl.01.Feiertag","today","") =~ m/Silvester/)
{
  return ("02:30:00")
}
elsif ((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")
}
}


SUB 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);
}

Gruß,
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 19:35:20
Versuchs mal so:

sub OffTimeLicht ($)
{
my ($start_time) = @_;
my $ret;
 
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

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

if (defined($start_time)) {
  $ret = $start_time."-".$ret;
}

return $ret;
}


und

([{OffTimeLicht("16:30")}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(""),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)


ungetestet!
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 20:10:38
Hallo flurin,
Nicht schlecht! Das hätte ich im Leben nicht hingekriegt! Wenn ich die Sub ohne Startzeit aufrufe, dann soll die Endzeit zurückgegeben werden.

Der Aufruf von {OffTimeLicht("16:30")} liefert mir nun den kompletten String!
16:30-22:00. Das ist perfekt!

Der Aufruf  {OffTimeLicht("")} liefert mir "-22:00". Müsste hier nicht nur "22:00" ausgegeben werden? Sorry, ich verstehe nicht genau, was der Code hier macht!
if (defined($start_time)) {
  $ret = $start_time."-".$ret;


Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 20:22:31
Zitat von: Spartacus am 24 Februar 2015, 20:10:38
Der Aufruf  {OffTimeLicht("")} liefert mir "-22:00". Müsste hier nicht nur "22:00" ausgegeben werden? Sorry, ich verstehe nicht genau, was der Code hier macht!
if (defined($start_time)) {
  $ret = $start_time."-".$ret;


OK, ändere diesen Code wie folgt:

if ($start_time ne "") {
  $ret = $start_time."-".$ret;
}
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 20:47:27
Hallo,
es funzt! Du setzt die Startzeit in diesem Code zusammen;
$ret = $start_time."-".$ret;
"Übergabeparameter" - "berechnete EndeZeit".

Danke,
jetzt habe ich es gerafft!
Christian.
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 20:54:14
uups!
zu früh gefreut! Das DOIF scheint es nicht zu fressen!


di.01.GA.ss.SA.Licht DOIF: the at function "OffTimeLicht("16:30")" must return a timespec and not 16:30 - 22:00.: {OffTimeLicht("16:30")}

Das heißt, die Rückgabe wird nicht als Zeit interpretiert, oder?
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 21:13:20
Gemäss Dokumentation

+ Zeitangaben in der Bedingung: [HH:MM:SS] oder [HH:MM] oder [{<perl-function>}]
+ Zeitintervalle: [<begin>-<end>] für <begin> bzw. <end> kann das obige Zeitformat gewählt werden


hätte eigentlich Deine ursprüngliche Fassung funktionieren müssen.

Ich bin nicht sicher ob, es nur so geht:

[HH:MM-HH:MM]

aber so nicht:

[HH:MM-{<perl-function>}]


Ev. kann Damian hier weiterhelfen.

Titel: Antw:DOIF: Triggerproblem
Beitrag von: Damian am 24 Februar 2015, 21:20:45
Zitat von: flurin am 24 Februar 2015, 21:13:20
Gemäss Dokumentation

+ Zeitangaben in der Bedingung: [HH:MM:SS] oder [HH:MM] oder [{<perl-function>}]
+ Zeitintervalle: [<begin>-<end>] für <begin> bzw. <end> kann das obige Zeitformat gewählt werden


hätte eigentlich Deine ursprüngliche Fassung funktionieren müssen.

Ich bin nicht sicher ob, es nur so geht:

[HH:MM-HH:MM]

aber so nicht:

[06:30-{<perl-function>}]


Ev. kann Damian hier weiterhelfen.

lt. der zitierten Doku geht:

[HH:MM-HH:MM]

oder

[{perl-fkt}-HH:MM]

oder

[HH:MM-{perl-fkt}]

oder

[{perl-fkt}-{perl-fkt}]

statt HH:MM kann überall auch HH:MM:SS stehen.

perl-fkt, die "HH:MM-HH:MM" liefert, geht nicht, ist auch nicht mit der obigen Doku konform.

Gruß

Damian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 21:27:31
Zitat von: Damian am 24 Februar 2015, 21:20:45

perl-fkt, die "HH:MM-HH:MM" liefert, geht nicht, ist auch nicht mit der obigen Doku konform.

Gruß

Damian

OK, Danke!
Es wäre aber schön, wenn es gehen würde  :)

Ich nehme an, dass sowas auch kein Problem ist:

[HH:MM-HH:MM:SS]

Gruss
flurin

Titel: Antw:DOIF: Triggerproblem
Beitrag von: Damian am 24 Februar 2015, 21:30:11
Zitat von: flurin am 24 Februar 2015, 21:27:31
OK, Danke!
Es wäre aber schön, wenn es gehen würde  :)

Die Zeitfunktion wird nicht von DOIF ausgewertet, sondern ist eine Funktion aus fhem.pl, die auch at benutzt. Daher eine andere Baustelle ;)

Gruß

Damian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 21:36:34
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!

Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Damian am 24 Februar 2015, 21:50:01
Zitat von: Spartacus am 24 Februar 2015, 21:36:34
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!

Christian

Wenn deine Ausschaltzeit abhängig ist von der Einschaltzeit, dann ist doch der Ansatz:

[Einschaltzeit-{timeroff("Einschaltzeit")}]


Gruß

Damian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 24 Februar 2015, 21:59:02
Zitat von: Spartacus am 24 Februar 2015, 21:36:34
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!

Christian

Du könntest auch mit zwei DOIF versuchen.

Mit dem ersten DOIF ([06:30]) ... könntest Du die Endzeit berechnen und in ein Dummy speichern.
Mit dem zweiten DOIF die Endzeit vom Dummy benutzen.

Ich komme heute nicht mehr dazu aber ich schaue es mir morgen noch mal an.

Gruss
flurin
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 22:04:34
Hi Damian,
verstehe ich noch nicht ganz!
Bsp.
Einschaltzeit 16:30 Uhr
([16:30-{OffTimeLicht("16:30")}]) set Licht on

würde dann mit dem Trigger auf die Einschaltzeit "16:30" auch gleichzeitig die SUB OffTimeLicht aufgerufen und die aktuelle Ausschaltzeit berechnet?

Bei diesem Aufruf
([16:30-{OffTimeLicht()}]) set Licht on hinkt die Ausschaltzeit immer hinterher und wird nur beim initialisieren korrekt berechnet.

Oder wie meinst Du das?

Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Damian am 24 Februar 2015, 22:21:45
Zitat von: Spartacus am 24 Februar 2015, 22:04:34
Hi Damian,
verstehe ich noch nicht ganz!
Bsp.
Einschaltzeit 16:30 Uhr
([16:30-{OffTimeLicht("16:30")}]) set Licht on

würde dann mit dem Trigger auf die Einschaltzeit "16:30" auch gleichzeitig die SUB OffTimeLicht aufgerufen und die aktuelle Ausschaltzeit berechnet?

Bei diesem Aufruf
([16:30-{OffTimeLicht()}]) set Licht on hinkt die Ausschaltzeit immer hinterher und wird nur beim initialisieren korrekt berechnet.

Oder wie meinst Du das?

Christian
OffTimeLicht wird beim Initialisieren des Moduls aufgerufen und immer dann, wenn die errechnete Zeit (hier Ausschaltzeit) zuschlägt. Wenn das nicht ausreicht, gäbe es die Möglichkeit über modify zum Einschaltzeitpunkt, die Ausschaltzeit berechnen zu lassen, siehe:

http://forum.fhem.de/index.php/topic,23833.msg256172.html#msg256172

Gruß

Damian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 24 Februar 2015, 22:43:54
Hallo Damian,
Danke, schaue ich mir noch mal genauer an! Wie am Anfang des Threads beschrieben, reicht es nicht, die Zeit beim Trigger auf die Ausschaltzeit zu berechnen.

@flurin
Danke auch Dir für Deine Unterstützung ! Ich versuche mal parallel eine andere Lösung zu bauen. Vielleicht ist ja weekday-timer eine Option!

Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 25 Februar 2015, 15:05:08
Hi Christian

Eine Zwischenlösung für Dein Problem.

Ansatz: DOIF mit einer Perl-Funktion definieren.

in fhem.cfg eintragen oder noch besser im Eingabefeld eingeben:

define di_define_DOIF DOIF ([06:30]) ( { define_DOIF("di_test_lamp","06:30") } )
attr di_define_DOIF group DOIF


Bei define_DOIF wird der Name des DOIF und die Startzeit übergeben.

99_myUtils.pm: Code copy/paste

sub define_DOIF($$)
{
  my ($doif,$start_time) = @_;
 
  my $end_time = OffTimeLicht();
 
  if (defined($defs{$doif} )) {
    fhem("delete $doif");
  }
  fhem("define $doif DOIF ([$start_time-$end_time]) (set flex_lamp on) DOELSE (set flex_lamp off)");
  fhem("attr $doif group DOIF");
}


define_DOIF entsprechend ändern/ausbauen.

OffTimeLicht() ist Deine ursprüngliche Perl-Funktion.

TODO: define mit modify ersetzen.

Gruss
flurin
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 25 Februar 2015, 16:13:16
Hallo flurin,
ganz lieben Dank für Deine Lösung. Sobald ich daheim bin, werde ich es ausprobieren. Der Code ist ziemlich komplex geworden, für so eine "einfache" Anforderung.

Du schreibst, "Zwischenlösung" was genau meinst Du damit?
Ich werde berichten,
Danke und Gruß,
Christian

Titel: Antw:DOIF: Triggerproblem
Beitrag von: flurin am 25 Februar 2015, 16:52:37
Zitat von: Spartacus am 25 Februar 2015, 16:13:16
Hallo flurin,
ganz lieben Dank für Deine Lösung. Sobald ich daheim bin, werde ich es ausprobieren. Der Code ist ziemlich komplex geworden, für so eine "einfache" Anforderung.

Du schreibst, "Zwischenlösung" was genau meinst Du damit?

Eine einfachere Lösung sehe ich mit 3 (So-Do, Fr-Sa und Silvester) DOIF's, end_time wäre dann fix: 22:00, 23:00 und 02:30.

Zwischenlösung, weil mir das tägliche "delete/define" nicht gefällt. Aber eine Optimierung würde den Code noch mehr aufblasen.

Gruss
flurin
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 25 Februar 2015, 17:08:30
Hallo flurin,
ok, verstanden! Ich versuche gerade noch den Vorschlag von Damian mit dem modify aufzugreifen. Demnach soll das beim Einschalten die Ausschaltzeit in meiner Funktion aufrufen und dann aktualisieren. Aber diese Lösung habe ich noch nicht durchblickt...
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 26 Februar 2015, 22:35:37
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 26 Februar 2015, 22:35:55
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Damian am 26 Februar 2015, 22:37:41
Zitat von: Spartacus am 26 Februar 2015, 22:35:55
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian

Modify brauchst du nicht mehr, siehe Nachbarthread: Schalten mit indirekten Zeitangaben

Gruß

Damian
Titel: Antw:DOIF: Triggerproblem
Beitrag von: Spartacus am 26 Februar 2015, 22:44:33
Wahnsinn!
Das ist ja ein Service! Da guckt man mal einen Tag nicht in den DOIF-Bereich und schon hat Damian was gebaut!
Danke,
Werde ich morgen testen!
Christian