Verzögerungswerte dynamisch setzen

Begonnen von Sirel, 12 April 2020, 17:33:42

Vorheriges Thema - Nächstes Thema

Sirel

Hallo zusammen,
ich habe ein etwas kniffeliges Problem:
Für eine spezielle Konstruktion, eine Art Rollladensteuerung, möchte ich unterschiedliche Positionen ansteuern können.
Damit eine bestimmte Postion agefahren wird, muss jedoch eine spezielle Schaltfrequenz eingeahlten werden. Zum Öffnen muss bspw. zunächst der öffnen, und dann verzögert der schließen und ein weiteres Mal verzögert der Stop Befehl abgesetzt werden.
D.h., es zunächst die richtigen Wait-Timer errechnet und gesetzt werden, bevor die eigentliche "Ansteuerung" erfolgen kann. Zudem muss eine Fallunterscheidung möglich sein, abhängig ob die Lamellen auf, oder zu gehen sollen.

Für die Fallunterscheidung errechne ich zunächst die jeweilige Positionsdifferenz. Abhängig vom Fall wird die Rechnung der Laufzeit so ausgeführt, dass der Wert immer positiv ist.
Die Werte errechne ich jeweils über ein DOIF_Reading.

Nun habe ich testweise probiert, erstmal einen Wert zu dynamisieren. Es wird aber kein Timer gesetzt.


Internals:
   CFGFN     
   DEF        ([$SELF:open:d] > OldReadingsNum("di_lamellendach","open",0))
(set lamellendach open) (set lamellendach close) (set lamellendach stop)

DOELSE
(set lamellendach close) (set lamellendach open) (set lamellendach stop)
   FUUID      5e91be5d-f33f-f340-96f3-09039e4ac3de544b
   MODEL      FHEM
   NAME       di_lamellendach
   NOTIFYDEV  di_lamellendach,global
   NR         3671
   NTFY_ORDER 50-di_lamellendach
   STATE      initialized
   TYPE       DOIF
   VERSION    21224 2020-02-18 18:45:49
   CHANGED:
     pos_diff_dwn: -7.5
     pos_diff_up: 7.5
   CHANGEDWITHSTATE:
     pos_diff_dwn: -7.5
     pos_diff_up: 7.5
   DOIF_Readings:
     pos_diff_dwn  ((OldReadingsNum("di_lamellendach","open",0)) -  ::ReadingValDoIf($hash,'di_lamellendach','open','','d'))*.15
     pos_diff_up {((::ReadingValDoIf($hash,'di_lamellendach','open','','d') - (OldReadingsNum("di_lamellendach","open",0)))*.15)}
   OLDREADINGS:
     2020-04-12 17:09:36   open            0
   READINGS:
     2020-04-12 17:12:53   cmd             0
     2020-04-11 19:55:50   direction       close
     2020-04-12 17:12:53   mode            enabled
     2020-04-12 17:10:06   open            50
     2020-04-12 17:12:53   pos_diff_dwn    -7.5
     2020-04-12 17:12:53   pos_diff_up     7.5
     2020-04-12 17:12:53   state           initialized
   Regex:
     DOIF_Readings:
       di_lamellendach:
         pos_diff_dwn:
           open       ^di_lamellendach$:^open:
         pos_diff_up:
           open       ^di_lamellendach$:^open:
     accu:
     cond:
       di_lamellendach:
         0:
           open       ^di_lamellendach$:^open:
   attr:
     cmdState:
     wait:
       0:
         0
         [$SELF:pos_diff_up:d0]
         1
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'di_lamellendach','open','','d') > OldReadingsNum("di_lamellendach","open",0)
   do:
     0:
       0          set lamellendach open
       1          set lamellendach close
       2          set lamellendach stop
     1:
       0          set lamellendach close
       1          set lamellendach open
       2          set lamellendach stop
   helper:
     DEVFILTER  ^global$|^di_lamellendach$
     NOTIFYDEV  global|di_lamellendach
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev
     triggerEvents
     triggerEventsState
   readings:
     all         di_lamellendach:open
   uiState:
   uiTable:
Attributes:
   DOIF_Readings pos_diff_up:{(([$SELF:open:d] - (OldReadingsNum("di_lamellendach","open",0)))*.15)},
pos_diff_dwn: ((OldReadingsNum("di_lamellendach","open",0)) -  [$SELF:open:d])*.15,
   do         always
   oldreadings open,time
   readingList open
   setList    open:slider,0,10,100
   wait       0,[$SELF:pos_diff_up:d0],1
   webCmd     open


In einer anderen Version (hier nicht gepostet), hatte ich für den "Hochfall" im Ausführungsteil noch folgende Anweisung der eigentlichen Ansteuerung vorgeschaltet:


(Bedingung)
((attr di_lamellendach wait 0,[$SELF:pos_diff_up:d0],1))
(set lamellendach open) (set lamellendach close) (set lamellendach stop)


Das Wait Attribut wurde zwar mit dem richtig aufgerundeten Werten gesetzt, der Timer wurde aber nicht mehr korrekt berücksichtig.

Hat jemand eine Idee, wie ich das Prolem lösen kann?

Besten Dank und frohe Ostern,

Max

amenomade

Ein Timer wird erst gesetzt, wenn das DOIF getriggert wird (Änderung von $SELF:open ), und die Bedingung wahr ist. Im Moment steht er auf "initialized".
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Sirel

Achso, das heißt in dem Fall nichts. Das habe ich per Hand gemacht.

Die Frage ist aber, wie die Abarbeitung läuft:
wann werden die Readings berechnet? Darauf greift der Timer ja zurück .

Viele Grüße,

Max

Damian

Die Auswertungsreihenfolge ist normalerweise:

DOIF_Readings
DOIF-Bedingungen
Wait-Attribut
DOIF-Ausführungen


Du kannst also nicht im gleichen DOIF-Zweig in der Ausführung etwas berechnen, was den Wait-Timer für diesen Zweig beeinflusst.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sirel

Hi Damian,
besten Dank! Das hatte ich mir dann auch gedacht  ::)

Kann ich beim Wait denn eine IF Bedingung einbauen? IF CMD 1 then pos_diff_up else pos_diff_dwn?

Wichtig ist auch, dass die Rundung wie bei [xxx:yyyy:d0] funktioniert oder kann wait mit Millisekunden umgehen?

Besten Dank und Gruß,

Max

Damian

Beim Wait kannst du mit Perlanweisungen arbeiten:

if (...) {...}

Wait kann auch mit Millisekunden umgehen, ob das dein System allerdings so genau schafft, ist eine andere Frage.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sirel

Hi Damian,
so richtig will es nicht bei mir funktionieren.

Ich habe jetzt folgendes beim Attr. Wait stehen:
0,{if (ReadingsNum("di_lamellendach","direction",120) > 0) {ReadingsNum("di_lamellendach","pos_diff_up",120)} else {ReadingsNum("di_lamellendach","pos_diff_up",120)*-1+10}}

So eingegebene, bekomme ich die richtigen Werte angezeigt.

Woran liegt das?

Viele Grüße und Dank vorab,

Max

Anbei noch mal das ganze Listing:
Internals:
   CFGFN     
   DEF        ([$SELF:open:d] > OldReadingsNum("di_lamellendach","open",0))
(set Test an) (set Test aus) (set Test an)

DOELSE
(set Test an) (set Test aus) (set Test an)
   FUUID      5e91be5d-f33f-f340-96f3-09039e4ac3de544b
   MODEL      FHEM
   NAME       di_lamellendach
   NOTIFYDEV  di_lamellendach,global
   NR         3671
   NTFY_ORDER 50-di_lamellendach
   STATE      cmd_2
   TYPE       DOIF
   VERSION    21224 2020-02-18 18:45:49
   CHANGED:
     pos_diff_dwn: 1.5
     direction: -10
     pos_diff_up: -1.5
     pos_diff_dwn: -6
     direction: 40
     pos_diff_up: 6
     pos_diff_dwn: 3
     direction: -20
     pos_diff_up: -3
     pos_diff_dwn: -6
     direction: 40
     pos_diff_up: 6
     pos_diff_dwn: 3
     direction: -20
     pos_diff_up: -3
   CHANGEDWITHSTATE:
     pos_diff_dwn: 1.5
     direction: -10
     pos_diff_up: -1.5
     pos_diff_dwn: -6
     direction: 40
     pos_diff_up: 6
     pos_diff_dwn: 3
     direction: -20
     pos_diff_up: -3
     pos_diff_dwn: -6
     direction: 40
     pos_diff_up: 6
     pos_diff_dwn: 3
     direction: -20
     pos_diff_up: -3
   DOIF_Readings:
     direction   ::ReadingValDoIf($hash,'di_lamellendach','open','','d') - (OldReadingsNum("di_lamellendach","open",0))
     pos_diff_dwn  ((OldReadingsNum("di_lamellendach","open",0)) -  ::ReadingValDoIf($hash,'di_lamellendach','open','','d'))*.15
     pos_diff_up {((::ReadingValDoIf($hash,'di_lamellendach','open','','d') - (OldReadingsNum("di_lamellendach","open",0)))*.15)}
   OLDREADINGS:
     2020-04-13 00:44:56   open            60
   READINGS:
     2020-04-13 00:48:04   cmd             2.3
     2020-04-13 00:48:04   cmd_event       di_lamellendach
     2020-04-13 00:48:04   cmd_nr          2
     2020-04-13 00:48:04   cmd_seqnr       3
     2020-04-13 00:48:04   direction       -20
     2020-04-13 00:48:04   e_di_lamellendach_open 40
     2020-04-12 23:42:44   mode            enabled
     2020-04-13 00:48:04   open            40
     2020-04-13 00:48:04   pos_diff_dwn    3
     2020-04-13 00:48:04   pos_diff_up     -3
     2020-04-13 00:48:04   state           cmd_2
     2020-04-13 00:45:01   wait_timer      no timer
   Regex:
     DOIF_Readings:
       di_lamellendach:
         direction:
           open       ^di_lamellendach$:^open:
         pos_diff_dwn:
           open       ^di_lamellendach$:^open:
         pos_diff_up:
           open       ^di_lamellendach$:^open:
     accu:
     cond:
       di_lamellendach:
         0:
           open       ^di_lamellendach$:^open:
   attr:
     cmdState:
     wait:
       0:
         0
         {if (ReadingsNum("di_lamellendach","direction",120) > 0) {ReadingsNum("di_lamellendach","pos_diff_up",120)} else {ReadingsNum("di_lamellendach","pos_diff_up",120)*-1+10}}
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'di_lamellendach','open','','d') > OldReadingsNum("di_lamellendach","open",0)
   do:
     0:
       0          set Test an
       1          set Test aus
       2          set Test an
     1:
       0          set Test an
       1          set Test aus
       2          set Test an
   helper:
     DEVFILTER  ^global$|^di_lamellendach$
     NOTIFYDEV  global|di_lamellendach
     event      open: 40,e_di_lamellendach_open: 40,cmd_nr: 2,cmd_seqnr: 1,cmd: 2.1,cmd_event: di_lamellendach,cmd_2_1,cmd_nr: 2,cmd_seqnr: 2,cmd: 2.2,cmd_event: di_lamellendach,cmd_2_2,cmd_nr: 2,cmd_seqnr: 3,cmd: 2.3,cmd_event: di_lamellendach,cmd_2,pos_diff_dwn: 3,direction: -20
     globalinit 1
     last_timer 0
     sleepdevice di_lamellendach
     sleepsubtimer -1
     sleeptimer -1
     timerdev   di_lamellendach
     timerevent open: 40
     triggerDev di_lamellendach
     timerevents:
       open: 40
       e_di_lamellendach_open: 40
       cmd_nr: 2
       cmd_seqnr: 1
       cmd: 2.1
       cmd_event: di_lamellendach
       cmd_2_1
       cmd_nr: 2
       cmd_seqnr: 2
       cmd: 2.2
       cmd_event: di_lamellendach
       cmd_2_2
       cmd_nr: 2
       cmd_seqnr: 3
       cmd: 2.3
       cmd_event: di_lamellendach
       cmd_2
       pos_diff_dwn: 3
       direction: -20
       pos_diff_up: -3
     timereventsState:
       open: 40
       e_di_lamellendach_open: 40
       cmd_nr: 2
       cmd_seqnr: 1
       cmd: 2.1
       cmd_event: di_lamellendach
       cmd_2_1
       cmd_nr: 2
       cmd_seqnr: 2
       cmd: 2.2
       cmd_event: di_lamellendach
       cmd_2_2
       cmd_nr: 2
       cmd_seqnr: 3
       cmd: 2.3
       cmd_event: di_lamellendach
       cmd_2
       pos_diff_dwn: 3
       direction: -20
       pos_diff_up: -3
     triggerEvents:
       open: 40
       e_di_lamellendach_open: 40
       cmd_nr: 2
       cmd_seqnr: 1
       cmd: 2.1
       cmd_event: di_lamellendach
       cmd_2_1
       cmd_nr: 2
       cmd_seqnr: 2
       cmd: 2.2
       cmd_event: di_lamellendach
       cmd_2_2
       cmd_nr: 2
       cmd_seqnr: 3
       cmd: 2.3
       cmd_event: di_lamellendach
       cmd_2
       pos_diff_dwn: 3
       direction: -20
       pos_diff_up: -3
     triggerEventsState:
       open: 40
       e_di_lamellendach_open: 40
       cmd_nr: 2
       cmd_seqnr: 1
       cmd: 2.1
       cmd_event: di_lamellendach
       cmd_2_1
       cmd_nr: 2
       cmd_seqnr: 2
       cmd: 2.2
       cmd_event: di_lamellendach
       cmd_2_2
       cmd_nr: 2
       cmd_seqnr: 3
       cmd: 2.3
       cmd_event: di_lamellendach
       cmd_2
       pos_diff_dwn: 3
       direction: -20
       pos_diff_up: -3
   internals:
   readings:
     all         di_lamellendach:open
   trigger:
   uiState:
   uiTable:
Attributes:
   DOIF_Readings pos_diff_up:{(([$SELF:open:d] - (OldReadingsNum("di_lamellendach","open",0)))*.15)},
pos_diff_dwn: ((OldReadingsNum("di_lamellendach","open",0)) -  [$SELF:open:d])*.15,
direction: [$SELF:open:d] - (OldReadingsNum("di_lamellendach","open",0))
   do         always
   oldreadings open,time
   readingList open
   setList    open:slider,0,10,100
   wait       0,{if (ReadingsNum("di_lamellendach","direction",120) > 0) {ReadingsNum("di_lamellendach","pos_diff_up",120)} else {ReadingsNum("di_lamellendach","pos_diff_up",120)*-1+10}}
   webCmd     open

Damian

Die if-Anweisung sollte so im wait funktionieren, warum es konkret in deinem DOIF nicht funktioniert, kann ich dir nicht sagen. Für wiederholende Ausführung musst du das Attribut do always setzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF