[GELÖST] DOIF_Readings mit readingList

Begonnen von SirBen, 17 Oktober 2019, 07:00:38

Vorheriges Thema - Nächstes Thema

SirBen

Moin,
ich habe ein Problem mit DOIF_Readings.
Ich möchte in ein internes Reading eine Zeit setzen (im HH:MM:SS Format) und das in einem weiteren Reading die gleiche Zeit in Sekunden setzen.
Ich habe im Forum die Funktion hms2secs gefunden und implementiert. Die Funktion ist auch gegeben. Allerdings werden die Sekunden nur beim einrichten des DOIF_Readings berechnet. Danach nicht mehr.
Im readingList steht Waittime, im DOIF_Readings WaitSec:{hms2secs(ReadingsVal("$SELF","Waittime",0))}
Beim set DOIF... Waittime 01:00:00 bleibt der Wert bei WaitSec der alte Wert.
Das DOIF reagiert selbst nicht auf eine Änderung von Waittime.

Hier der Hintergrund:
Ich möchte über FTUI meine Klingel deaktivieren und mit einen Datetimepicker in FTUI eine Wartezeit zum Reaktivieren der Klingel mittels at setzen.
Das DOIF ist erstmal zum Testen:
DEF        ([$SELF:Klingel] eq "on")
(set $SELF KameraURL http://192.168.0.5/camera/httppreview , IF ([Kodi:playStatus] eq "playing") (set Kodi pause all , set Kodi msg 'fhem' 'Es hat geklingelt!' 10000 info) , IF ([$SELF:Status] eq "off") (set FritzBox call [$SELF:TelNr])) (set $SELF KameraURL 0)
DOELSEIF
([$SELF:Status] eq "off")
({ Log 1, "Klingel aus" } , defmod a2 at +[$SELF:Waittime] set DOIF_Klingel Status on)
DOELSEIF
([$SELF:Status] eq "on")
({ Log 1, "Klingel an" } , set $SELF Waittime 02:00:00)
DOELSE
   FUUID      5da5585f-f33f-2b06-5167-a6416d7bd94bbac6
   MODEL      FHEM
   NAME       DOIF_Klingel
   NOTIFYDEV  global,DOIF_Klingel
   NR         143
   NTFY_ORDER 50-DOIF_Klingel
   STATE      initialized
   TYPE       DOIF
   VERSION    20268 2019-09-28 21:00:39
   CHANGED:
     WaitSec: 7200
   CHANGEDWITHSTATE:
     WaitSec: 7200
   DOIF_Readings:
     WaitSec    {hms2secs(ReadingsVal("DOIF_Klingel","Waittime",0))}
   READINGS:
     2019-10-15 21:22:18   KameraURL       0
     2019-10-15 21:21:48   Klingel         on
     2019-10-16 21:51:51   Status          on
     2019-10-15 08:51:56   TelNr           01xxxxxxxxxx
     2019-10-17 06:38:32   WaitSec         7200
     2019-10-16 21:51:51   Waittime        02:00:00
     2019-10-17 06:38:32   cmd             0
     2019-10-17 06:38:32   mode            enabled
     2019-10-17 06:38:32   state           initialized
   Regex:
     accu:
     cond:
       DOIF_Klingel:
         0:
           Klingel    ^DOIF_Klingel$:^Klingel:
         1:
           Status     ^DOIF_Klingel$:^Status:
         2:
           Status     ^DOIF_Klingel$:^Status:
   attr:
     cmdState:
     wait:
       0:
         0
         30
       1:
         0
       2:
         0
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'DOIF_Klingel','Klingel') eq "on"
     1          ::ReadingValDoIf($hash,'DOIF_Klingel','Status') eq "off"
     2          ::ReadingValDoIf($hash,'DOIF_Klingel','Status') eq "on"
   do:
     0:
       0          set DOIF_Klingel KameraURL http://192.168.0.5/camera/httppreview , IF ([Kodi:playStatus] eq "playing") (set Kodi pause all , set Kodi msg 'fhem' 'Es hat geklingelt!' 10000 info) , IF ([DOIF_Klingel:Status] eq "off") (set FritzBox call [DOIF_Klingel:TelNr])
       1          set DOIF_Klingel KameraURL 0
     1:
       0          { Log 1, "Klingel aus" } , defmod a2 at +[DOIF_Klingel:Waittime] set DOIF_Klingel Status on
     2:
       0          { Log 1, "Klingel an" } , set DOIF_Klingel Waittime 02:00:00
     3:
       0         
   helper:
     DEVFILTER  ^global$|^DOIF_Klingel$
     NOTIFYDEV  global|DOIF_Klingel
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev
     triggerEvents
     triggerEventsState
   readings:
     all         DOIF_Klingel:Klingel DOIF_Klingel:Status
   uiState:
   uiTable:
Attributes:
   DOIF_Readings WaitSec:{hms2secs(ReadingsVal("$SELF","Waittime",0))}
   do         always
   genericDeviceType MotionSensor
   homebridgeMapping MotionDetected=Klingel,values=on:1;off:0
   readingList Klingel KameraURL Status TelNr Waittime
   room       Homebridge
   siriName   Klingel
   wait       0,30:0:0


Meine Vermutung ist, dass DOIF nicht auf die Änderung von Waittime reagiert, weil das ein internes Reading ist.

Habt ihr einen Tipp für mich?

Danke und Gruß
Ben

rabehd

ZitatIch möchte über FTUI meine Klingel deaktivieren und mit einen Datetimepicker in FTUI eine Wartezeit zum Reaktivieren der Klingel mittels at setzen.
Fangen wir mal hier an.
Ist die Klingel ein Device? wie wäreein List davon?
"deaktivieren über FTUI" - wie willst Du das tun?
"mittels at" - wo ist das?
Wofür ist dann das DOIF?
Reading Klingel <-> Status Wert, wann warum?

Vielleicht kann ich es dann durchschauen.
Auch funktionierende Lösungen kann man hinterfragen.

SirBen

Die Klingel ist noch kein Device. Das wird aber ein ESPEasy mit angeschlossenem Relais.
Relais angezogen, Klingel deaktiviert. Am Eingang vom ESP kommt der Klingeltaster, damit der an FHEM weitergeleitet wird. Momentan simuliere ich das über das Klingel Reading im DOIF, welches ich manuell setze.

Über FTUI mache ich das Deaktivieren mittels Switch und der integrierten countdown Anzeige.
Schaltet man den switch im FTUI, wird im DOIF das Reading Status auf off gesetzt.
Darauf reagiert das DOIF und setzt entsprechend die Klingel auf off (in meinem Test erstmal nur den Logeintrag) und halt das at: defmod a2 at +[$SELF:Waittime] set DOIF_Klingel Status on)

Damit der Countdown im Switch widget angezeigt werden kann (data-countdown="DOIF_Klingel:WaitSec"), muss die Wartezeit in Sekunden vorliegen.
Daher die Umrechnung von HH:MM:SS in Sekunden.

Außerdem kann man über FTUI die Wartezeit verändern, mittels datetimepicker widget. Das widget sendet die Zeit an das DOIF Reading Waittime, das Reading WaitSec wird allerdings nicht geändert. Auch nicht, wenn ich das Reading Waittime direkt ändere.

rabehd

Bei FTUI bin ich raus. Hier ist noch jemand der dort einen Counter will https://forum.fhem.de/index.php/topic,104551.msg984278.html#msg984278

Was habe ich verstanden?
Es wird ein Device Klingel geben (state on = jemand Klingelt) und Reading Status (on aktiviert; off deaktiviert).
Wenn jemand klingelt, dann wird etwas getan, egal ob aktiv oder nicht.
Wenn die Klingel deaktivert ist, dann soll nach einer Zeit der Status wieder auf aktiviert gesetzt werden. Das sollte ohne at im DOIF mit wait gehen.
Wenn die Klingel aktiviert wird, dann soll waittime auf einen Standardwert gesetzt werden.

Ich würde estmal das Klingeldevice anlegen, z.B. als Dummy. Dort sehe ich auch das Reading Status.
Dann käme das DOIF mit den Reaktionen auf die Klingel und ohne Änderung der Zeit.
Wenn das klappt würde ich versuchen waittime variabel zu gestalten. Was soll bei einer Anpassung während der Deaktivierung passieren?
Wenn das alles klappt, dann käme bei mir die Darstellung in FTUI.
Auch funktionierende Lösungen kann man hinterfragen.

SirBen

ZitatWas habe ich verstanden?
Es wird ein Device Klingel geben (state on = jemand Klingelt) und Reading Status (on aktiviert; off deaktiviert).
Wenn jemand klingelt, dann wird etwas getan, egal ob aktiv oder nicht.
Wenn die Klingel deaktivert ist, dann soll nach einer Zeit der Status wieder auf aktiviert gesetzt werden.
Genau so soll es sein.

ZitatDas sollte ohne at im DOIF mit wait gehen.
Wenn ich das richtig verstanden habe, dann wartet DOIF bei wait so lange mit der Ausführung, bis entweder die Zeit abgelaufen ist, oder eine andere Bedingung wahr wird.
Was bedeutet, betätigt jemand den Klingeltaster während der Wartezeit zum Reaktivieren, wird wait abgebrochen und somit die Klingel nicht reaktiviert.

ZitatWenn die Klingel aktiviert wird, dann soll waittime auf einen Standardwert gesetzt werden.
Auch richtig.

ZitatIch würde estmal das Klingeldevice anlegen, z.B. als Dummy. Dort sehe ich auch das Reading Status.
Das hatte ich bisher nicht gemacht, weil ich der Meinung bin, dass DOIF so komplex geworden ist, dass man dafür kein Dummy mehr braucht. Dafür gibt es ja die readingList usw...
Außerdem ist der ESP später ein eigenes Device, auf dessen Event man reagieren muss. Ich könnte das ins DOIF mit einbinden, dass bei einem Klingeltaster Event der on-off Wert in einen Dummy geschrieben wird. Aber auch hierfür gibt es eigentlich readingList etc.

ZitatWas soll bei einer Anpassung während der Deaktivierung passieren?
Wenn man während der Deaktivierung die Waittime ändert? Nichts weiter, außer natürlich, dass WaitSec den Sekundenwert von Waittime annimmt.

In FTUI ist das leider nicht so leicht mit einem Countdown. Die countdown Funktion vom Switch widget benötigt leider einen Sekundenwert, der einmalig eingelesen wird und dann einfach runter läuft.
Andernfalls müsste man ein Reading haben, welches sich ständig aktualisiert um einen Countdown zu visualisieren.

Nur um das noch mal zu sagen, die Funktion vom DOIF und das Zusammenspiel vom Switch widget und dem DOIF funktionieren genau so wie gewünscht. Nur die Änderung des Waittime Readings resultiert nicht in einer Änderung des WaitSec Readings.

rabehd

Zitataußer natürlich, dass WaitSec den Sekundenwert von Waittime annimmt.
Darauf zielte die Frage. Also doch nicht nichts. :)

ZitatAußerdem ist der ESP später ein eigenes Device,
Solange Du das nicht hast brauchst Du einen Ersatz zur Simulation. Das wäre z.B. ein Dummy.
Jetzt versuchst Du die Klingel als DOIF zu betrachten, das geht eher nicht.

Zitatbetätigt jemand den Klingeltaster während der Wartezeit zum Reaktivieren, wird wait abgebrochen
stimmt, das muss man berücksichtigen.
Auch funktionierende Lösungen kann man hinterfragen.

Damian

Wenn du die gesamte Logik in einem DOIF unterbringen willst, dann würde ich dir den Perl-Modus empfehlen, dort kannst du unabhängige Zweige definieren und ebenfalls mit "wait"-Timern arbeiten.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

SirBen

Wenn du die gesamte Logik in einem DOIF unterbringen willst, dann würde ich dir den Perl-Modus empfehlen, dort kannst du unabhängige Zweige definieren und ebenfalls mit "wait"-Timern arbeiten.
Wie würde das denn konkret aussehen, in dem Fall, dass bei einer Änderung von Waittime das DOIF_Reading WaitSec aktualisiert?
Das at muss nicht unbedingt in mein DOIF integriert werden.

SirBen

#8
ZitatSolange Du das nicht hast brauchst Du einen Ersatz zur Simulation. Das wäre z.B. ein Dummy.
Jetzt versuchst Du die Klingel als DOIF zu betrachten, das geht eher nicht.
Naja, ich betrachte als Dummy momentan "DOIF_Klingel:Klingel". Das DOIF reagiert auf sich selbst mit ([$SELF:Klingel] eq "on"). Attr do always ist auch gesetzt.

Das einzige was vielleicht in einen Dummy muss wäre Waittime. Also define DUMMY dummy mit readingList Waittime. Damit das DOIF_Reading WaitSec:{hms2secs(ReadingsVal("DUMMY","Waittime",0))} auf das externe Event vom DUMMY reagieren kann.

Meine Variante, das DUMMY zu umgehen mit readingList Waittime und:
DOIF_Reading WaitSec:{hms2secs(ReadingsVal("$SELF","Waittime",0))}
scheint nicht zu funktionieren.  :-\

EDIT:
Habe es gerade mal probiert mit dem DUMMY.
Das DOIF_Reading WaitSec ändert sich trotzdem nicht.  ???

Die Funktion in der 99_myutils lautet:
sub hms2secs($){
my ($t) = @_;
return substr($t,0,2) * 3600 + substr($t,3,2) * 60 + substr($t,6,2);
}

rabehd

Ich lasse mich gern belehren, aber bis dahin bleibe ich dabei: Ein ESP kann in FHEM kein Device vom Typ DOIF sein.
Auch funktionierende Lösungen kann man hinterfragen.

SirBen

ZitatIch lasse mich gern belehren, aber bis dahin bleibe ich dabei: Ein ESP kann in FHEM kein Device vom Typ DOIF sein.
Das stimmt natürlich, ich werde später, wenn der ESP existiert, das DOIF ändern von:
([$SELF:Klingel] eq "on")
in
([ESPEasy:Klingel] eq "on")

Momentan reagiert das DOIF ja auf
([$SELF:Klingel] eq "on")
wenn ich in die FHEM Befehlszeile
set DOIF_Klingel Klingel on
eingebe.

SirBen

Ausprobiert habe ich auch
DOELSEIF
([$SELF:Waittime])
(set $SELF WaitSec {hms2secs(ReadingsVal("DOIF_Klingel","Waittime",0))})

Funktioniert auch nicht. Auch nicht, wenn WaitSec kein DOIF_Reading sondern ein readingList ist. Denn dann steht im Reading WaitSec nur {hms2secs(ReadingsVal("DOIF_Klingel","Waittime",0))}
aber halt nicht der Wert.

Per

Zitat von: SirBen am 17 Oktober 2019, 11:17:53ich werde später, wenn der ESP existiert, das DOIF ändern von:
([$SELF:Klingel] eq "on")
in
([ESPEasy:Klingel] eq "on")
Dann ist das auch ein anderes Gerät. Zur Zeit ist es ein Gerät und DOIF braucht dafür die Erlaubnis, sich selbst triggern zu dürfen.

rabehd

Der Dummy als Ersatz für den ESP hat den Vorteil, dass man das DOIF nicht verändern muss, wenn der ESP als Device angelegt wird.
Einfach den Dummy umbenennen und deaktivieren oder gleich löschen. Der ESP bekommt den Namen und ggf. die Userreadings und es geht weiter.
Schon vom Standpunkt des Testens/Rollout sinnvoll. 8)
Auch funktionierende Lösungen kann man hinterfragen.

SirBen

Ich fasse nochmal kurz zusammen:

In meinem DOIF wird ein Reading "Waittime" gesetzt (von außen) mit einer Zeit im Format HH:MM:SS.
Ich habe eine Sub Routine in 99_myUtils:
sub hms2secs($){
my ($t) = @_;
return substr($t,0,2) * 3600 + substr($t,3,2) * 60 + substr($t,6,2);
}

Diese funktioniert, wenn man z.B. in die FHEM Kommandozeile eingibt: {hms2secs(ReadingsVal("DOIF_Klingel","Waittime",0))}, als Ergebnis erhält man die Zeit in Sekunden.
Jetzt möchte ich diese Sub benutzen, um die Umrechnung von HH:MM:SS in Sekunden durchzuführen und das Ergebnis soll in einem weiteren Reading gespeichert werden.
Dazu gibt es laut commandref das Attribut "DOIF_Readings".
Mit
attr DOIF_Klingel DOIF_Readings WaitSec:{hms2secs(ReadingsVal("DOIF_Klingel","Waittime",0))}
wird das Reading in meinem DOIF erstellt (WaitSec) und die Zeit in Sekunden in diesem Reading gespeichert.
Ändert sich das Reading Waittime, ändert sich das Reading WaitSec NICHT.
Selbst wenn ich das Reading Waittime in ein Dummy packe und das DOIF_Reading entsprechend anpasse, ändert sich im Reading WaitSec weiterhin nichts.

Es scheint also der Aufruf der Sub Routine "hms2secs" nicht zu funktionieren.

Die DEF vom DOIF selbst sieht so aus:
DEF        ([$SELF:Klingel] eq "on")
(set $SELF KameraURL http://192.168.0.5/camera/httppreview , IF ([Kodi:playStatus] eq "playing") (set Kodi pause all , set Kodi msg 'fhem' 'Es hat geklingelt!' 10000 info) , IF ([$SELF:Status] eq "off") (set FritzBox call [$SELF:TelNr])) (set $SELF KameraURL 0)
DOELSEIF
([$SELF:Status] eq "off")
({ Log 1, "Klingel aus" } , defmod a2 at +[$SELF:Waittime] set DOIF_Klingel Status on)
DOELSEIF
([$SELF:Status] eq "on")
({ Log 1, "Klingel an" } , set $SELF Waittime 02:00:00)
DOELSE

Es wird also mit dem DOIF nicht auf die Änderung des Readings Waittime reagiert. Das funktioniert mit dem DOIF_Reading normalerweise automatisch.

Das mit dem Dummy Ersatz für den ESP ist richtig und bestimmt auch besser als meine Variante. Ich denke, das hat mit meiner Problematik nur nichts zu tun.  :-\