HM-PB-6-WM55 <-FHEM-> HM-LC-Sw4-DR: "Echte" Rückmeldung an Taster?

Begonnen von M_I_B, 21 November 2015, 22:59:44

Vorheriges Thema - Nächstes Thema

M_I_B

... so, nächste Aufgabe bezgl. Long/Short ...

define TA_EG_FL_01 notify EG_FL_6CH_CH1 set KG_ZS_4CH_CH1 toggle
define TA_EG_FL_11 notify EG_FL_6CH_CH1:Long.* set KG_ZS_4CH_CH1 on-for-timer 10

Das funktioniert erstaunlicher Weise schmerzfrei wie gewollt. Aber das möchte ich natürlich eleganter lösen. Also habe ich ...
define TA_EG_FL DOIF ([EG_FL_6CH_CH1:?Short.*]) (set KG_ZS_4CH_CH1 toggle) DOELSEIF ([EG_FL_6CH_CH1:?Long.*]) (set KG_ZS_4CH_CH1 on-for-timer 10)
... und ...
define TA_EG_FL DOIF ([EG_FL_6CH_CH1] =~ "Short") (set KG_ZS_4CH_CH1 toggle) DOELSEIF ([EG_FL_6CH_CH1]  =~ "Long") (set KG_ZS_4CH_CH1 on-for-timer 10)
Versucht. Funktioniert leider nur zum Teil...

Mit kurzem Druck geht der Kanal an, aber nicht wieder aus. Sehr wohl kann ich aber mit einem langen Druck den Timer Setzen und retriggern. Also wird offensichtlich der ELSE- Teil abgearbeitet bei langem Tastendruck, aber beim zweiten kurzen Tastendruck der IF-Teil nicht mehr.

Ist vermutlich ein ganz simpler (Denk-) Fehler, aber ich komme einfach nicht drauf.

Das ganze Konstrukt sieht im Übrigen jetzt so aus:
## 6fach Taster Haustür <-> 4fach AKtor Zählerschrank Aussenlicht ##

#define TA_EG_FL_01 notify EG_FL_6CH_CH1 set KG_ZS_4CH_CH1 toggle
#define TA_EG_FL_11 notify EG_FL_6CH_CH1:Long.* set KG_ZS_4CH_CH1 on-for-timer 10

define TA_EG_FL DOIF ([EG_FL_6CH_CH1:?Short.*]) (set KG_ZS_4CH_CH1 toggle) DOELSEIF ([EG_FL_6CH_CH1:?Long.*]) (set KG_ZS_4CH_CH1 on-for-timer 10)

define TA_EG_FL_02 notify EG_FL_6CH_CH2 set KG_ZS_4CH_CH2 toggle
define TA_EG_FL_03 notify EG_FL_6CH_CH3 set KG_ZS_4CH_CH3 toggle
define TA_EG_FL_04 notify EG_FL_6CH_CH4 set KG_ZS_4CH_CH4 toggle
define TA_EG_FL_05 notify EG_FL_6CH_CH5 set KG_ZS_4CH_(CH1|CH2|CH3|CH4) on;
define TA_EG_FL_06 notify EG_FL_6CH_CH6 set KG_ZS_4CH_(CH1|CH2|CH3|CH4) off;

M_I_B

... bin selber drauf gekommen; das ist, zumindest für mich, in der CommandRef etwas missverständlich ausgedrückt... Da fehlt ein "do always" ^^

define TA_EG_FL DOIF ([EG_FL_6CH_CH1:?Short.*]) (set KG_ZS_4CH_CH1 toggle) DOELSEIF ([EG_FL_6CH_CH1:?Long.*]) (set KG_ZS_4CH_CH1 on-for-timer 10)
attr TA_EG_FL do always


Und man kann es weiter vereinfachen, da nur Short und Long ausgewertet werden müssen:
define TA_EG_FL DOIF ([EG_FL_6CH_CH1:?Short.*]) (set KG_ZS_4CH_CH1 toggle) DOELSE (set KG_ZS_4CH_CH1 on-for-timer 10)
attr TA_EG_FL do always


Jetzt fehlt mir nur noch das Hinzuzählen von Zeitblöcken, wenn der Timer noch nicht abgelaufen ist nach dem Basic-like Schema:

SET $t0 = 0, $t1 = 30
IF
  TimerRun AND Long AND $t0 = 0 OR TimerOff AND Long
    SET on-for-timer $t1
    SET $t0 = 1
ELSEIF
  TimerRun AND Long AND $t0 > 0
    SET on-for-timer ($t1 * $t0)
    SET $t0 = $t0 + 1
ENDIF
   
... ich Hoffe, mann kann meinen wirren Gedanken folgen?!

frank

Zitatwenn der Timer noch nicht abgelaufen
das actor reading timedOn=running/off.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

M_I_B

... suppi; Dank für den Hinweis!
Gibt's da vielleicht was zu lesen zu, ausser ComRef/Einsteiger.pdf?

M_I_B

... jetzt hänge ich bei einem RegEx  >:(

Ich möchte "Long 13_324" auswerten. Allerdings nicht das ganze Ding, sondern lediglich den Null- Durchgang des Zählers vor dem Unterstrich.
Meine ersten Versuche mit der Reaktion auf lange Drücke sahen so aus:
blablub ... EG_FL_6CH_CH1:?Long 10.* ... blubbla
Da habe ich stumpf abgefragt, ob eine 10 oder eine 20 oder was auch immer da auftaucht. Das funktioniert super und erfüllt seine Zweck. Nun möchte ich aber einen kleinen Schritt weiter. Das Problem was ich nun mit RegEx habe ist, das die Länge sich ja bei jedem Potenzsprung ändert, also bis 9 einstellig, bis 99 zweistellig u.s.w.. Ich müsste also zum einen wissen, das "Long" auftaucht und zum anderen vom Unterstrich eine Stelle nach links auf "0" abfragen.
Da bin ich einfach mangels Erfahrung mit RegEx zu doof zu... Wie geht man an so eine Aufgabe in Verbindung mit RegEx ran?


M_I_B

... auch nicht schlecht und besser erklärt als das was ich kenne; gespeichert. Bringt mich aber zum gleichen Ergebnis...
Long.*0_.*
... funktioniert nicht wie gedacht.
Aber erst recht laufe ich gegen die Wand bei:
... set KG_ZS_4CH_CH1 on-for-timer 180 * EG_FL_6CH_CH1:?.*(Zehnerstelle).*) ...
Da weiß ich zum einen nicht, ob das überhaupt geht, das ich stumpf eine Wert (hinter on-for-timer) mit einem anderen Wert (Zehnerstelle) multiplizieren kann und weiß ebenfalls nicht, wie ich dann die Zehnerstelle da mit RegEx heraus bekomme als Operand...

Ich denke, was ich erreichen möchte ist klar, aber ich hänge da geistig vollkommen fest...

justme1968

#67
du kannst nicht auf fhem ebene multiplizieren das geht 'nur' auf perl ebene.

in einem notify würde das etwa so aussehen: define myNotify notify EG_FL_6CH_CH1:Long.* { if( $EVTPART1 =~ m/(\d+)0_/ ) {fhem("set KG_ZS_4CH_CH1 on-for-timer ". 180 * $1)} }

gruss
  andre

ps: das ? zwischen : und Long das du verwendest ist überflüssig.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

M_I_B

... auha ... Auf die perl- Ebene wollte ich mich eigentlich noch nicht ranwagen; mir qualmt ja so schon die Omme ^^

Aber so wie's ausschaut, komme ich da wohl nicht umhin... ich trau mich mal... Morgen, wenn ich halbwegs ausgeschlafen bin ;)

Erstmal vielen Dank; ich werde berichten, was bei meinem Murks rausgekommen ist...

Zitatps: das ? zwischen : und Long das du verwendest ist überflüssig.
Nich? Stand so in der Doku und habe es somit als gegeben hingenommen, quasi als Äquivalent zu =~

justme1968

nicht nur überflüssig sondern sogar falsch...

der : an dieser stelle trennt den device namen vom reading namen. d.h. nach dem doppelpunkt fängt die regex an die auf das reading matched. ein quantifier wie ? ist aber direkt am anfang einer regex sinnlos weil es kein zeichen davor gibt das mit einer bestimmten anzahl vorkommen könnte.

schau mal ins log. eigentlich müsstest du da auch einen entsprechenden fehler sehen der dann der grund ist warum deine regex nicht funktioniert.

das gilt zumindest für notify und regex im allgemeinen. ob es bei DOIF eine andere sinnvolle bedeutung hat weiss ich nicht. das verwende ich nicht.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

M_I_B

... da hast Du recht. Ich hatte das aus dem HowTo bezgl DOIF her und angenommen, das es bei notify ebenso ist ...

Bevor ich ins Bettchen schleiche, konnte ich es nicht lassen und habe das mal eben noch schnell alleine eingebaut (alles andere auskommentiert).
Ich habe Deine Zeile natürlich noch nicht verstanden, aber so funktioniert sie nicht. Als Test habe ich mal den Multiplikator $1 am Ende weggenommen; dann geht's. Es scheint mir, das in $1 immer NULL oder 0 steht oder was anderes in dem Zusammenhang nicht klappt.

define di_1 notify EG_FL_6CH_CH1:Long.* { if( $EVTPART1 =~ m/\d+0_/ ) {fhem("set KG_ZS_4CH_CH1 on-for-timer ". 3 * $1)} }
Da passiert nüscht

define di_1 notify EG_FL_6CH_CH1:Long.* { if( $EVTPART1 =~ m/\d+0_/ ) {fhem("set KG_ZS_4CH_CH1 on-for-timer ". 3 )} }
Da wird der Timer auf 3 Sekunden gesetzt, natürlich ohne hochzuzählen

BTW: Vorhin stand da doch $EVTPART1 und nicht wie jetzt $EVENT ?!?

Ich hab's jetzt noch mal schnell mit $EVENT probiert. Dann geht nix mehr ...

justme1968

sorry. aus irgend einem grund haben in meinem post zwei klammern gefehlt die in die regex gehören. ohne die klammern wird nichts gecaptured.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

M_I_B

... ja super; funktioniert perfekt! Vielen Dank!
Jetzt werde ich die Tage mal versuchen, Deinen RegEx zu analysieren und zu verstehen. Immerhin hatte ich den richtigen Riecher mit der leeren Variable; wenn ich das richtig verstanden habe, "merkt" sich RegEx das, was innerhalb von Klammern auf das Muster passt und legt es in $1, $2, ...$+n ab?!

Mag sein, das ich heute wegen Fieber & Co. nicht so ganz klarf im Kopf bin... Also bitte ggf. meinen Dummfug vergessen^^

So wie ich das sehe, funktioniert DOIF nicht mehr wirklich, sobald man auf die perl- Ebene springt; zumindest wird es dann ziemlich verwirrend mit der ganzen Klammerung... Also wäre es wohl schlauer, die von mir gewünschten Funktionen komplett auf perl-Ebene (Basic oder Pascal wäre mir lieber *DuckUndWeg*) zu verwirklichen, oder?

Letztlich will ich da hin kommen:

Bei einem kurzen Druck soll der Aktor toggeln.
Bei einem langen Druck soll der Aktor erstmal einschalten.
  Dann Rausfusseln des Zählers auf Nulldurchgang als Multiplikator für on-for-timer (tut ja schon)
  Parallel bei jedem Nulldurchgang kurz Aktor OFF/ON als optische Rückmeldung (nur Leuchtmittel!)
  Bei "LongRelease.*" on-for-timer mit dem errechneten Wert setzen


Anm.: Das mit der optischen Rückmeldung funktioniert nicht oder nur eingeschränkt mit Leuchtstofflampen, wozu auch die s.g. Energiesparlampen gehören. Klassische Leuchtmittel und LED haben damit kein Problem.

Vielleicht könnte man das komplett als perl- Funktion bosseln, die man unabhängig vom Sensor- und Aktor aus FHEM aufrufen kann? Damit habe ich mich noch gar nicht beschäftigt, aber ich meine irgendwo gelesen zu haben, das sowas geht und bei Euch Profis gängige Praxis ist? Also in etwa so:


define di_1 DOIF ([EG_FL_6CH_CH1:?Short.*]) (set KG_ZS_4CH_CH1 toggle) \
          DOELSE (set KG_ZS_4CH_CH1 {call perl-funktion})
attr di_1 do always


... ist vermutlich Blödsinn und/oder nicht so realisierbar?

justme1968

ja. genau. mit den klammern kannst du einzelne teile extrahieren und zwischenspeichern.

wie gesagt: ich verwende DOIF nicht und sehe gerade wegen der klammern und mancher syntax besonderheiten die sich dann mit fhem oder perl beissen keinen vorteil darin noch mal eine zwischenstufe zu lernen. es gibt aber viele die sehen das anders.

unabhängig davon ist es immer sinnvoll so etwas in eine 99_myUtils routine auszulagern und diese nur aufzurufen wenn es mehr als ein paar ganz wenige zeilen sind. wenn die ereignisse unabhängig voneinander sind muss es auch nicht das gleiche notify oder die gleiche routine sein.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

M_I_B

... ich habe den Quatsch mal gelöscht, den ich vorhin verzapft habe ^^

Ich versuche das jetzt "zeilenweise":

define di_1 notify EG_FL_6CH_CH1 {\
{ fhem ( "set KG_ZS_4CH_CH1 on" ) }\
}

Das funktioniert schon mal...

define di_1 notify EG_FL_6CH_CH1 {\
{ fhem ( "set KG_ZS_4CH_CH1 on" ) };; \
if ( $EVTPART1 =~ m/(\d+)0_/ ) { fhem ( "set KG_ZS_4CH_CH1 off" );; fhem ( "set KG_ZS_4CH_CH1 on" ) }
}

Das im Prinzip auch. Allerdings ist die Auswertung soooo langsam, das FHEM/RPi nicht hinterher kommt. Da kann ich nach einem langen DRuck mit Zähler über 50 schon lange losgelassen haben, und der Aktor macht immer noch ne ganze Weise klickklack, wenn die AUswerung über 0 gekommen ist. Das geht so also nicht ohne weitere Optimierung bezgl. Aufführungszeit. Damit bin ich aber derzeit vollkommen überfordert, weil ich nicht den leisesten Schimmer habe, was in welcher Kombination wie viel Rechenzeit beansprucht.

Auch fehlt mir noch das Verständnis, was z.B. $EVTPARTx macht und für was das m im RegEx gut ist; ich habe es mal stumpf übernommen...

Nachtrag:

define blablub notify EG_FL_6CH_CH1 set KG_ZS_4CH_CH1 off;; set KG_ZS_4CH_CH1 on

... ist so schnell, das man zwangsweise zwischen die OFF/ON Sequenzen ein Sleep setzen muss. SOmald man aber gleiche Sequenz im perl nutzt ala ...

... { fhem ( "set KG_ZS_4CH_CH1 off;; set KG_ZS_4CH_CH1 on" ) }\

ist es viel zu langsam... Kann mich mal wer schlau machen?