uiTable Schaltbares Icon mit Hilfe der Funktion switch mit schönheitsproblem

Begonnen von Stelaku, 18 Dezember 2021, 01:56:36

Vorheriges Thema - Nächstes Thema

Stelaku

Hallo alle zusammen

Das DOIF mit uiTable und Perl mode haben mich jetzt auch erreicht und ich kann es nicht lassen meine vorhandenen Device mit diesen feature umzubauen.
Natürlich stolpert man dann immer wieder über hindernisse weil ja erstmal vermeindlich alles anders ist als im FHEM Modus.
Und jetzt gerade habe ich mich mit der Funktion switch angelegt. Es funktioniert auch schon fast so wie ich es gerne haben möchte nur eben leider nur fast.

In einem perl mode DOIF möchte ich alle meine Stromstoßschalter mit einen Tast Impuls Tasten ( ein Impuls Lampe EIN, noch ein Impuls Lampe wieder AUS ).
Die Ein und Ausgänge werden über mehrer mcp23017 ( I2C Port Expander ) bereitgestellt.
Die Ausgänge werden für das Tasten benötigt und die Eingänge liefern mir den Status der jeweiligen Lampe zurück.

Hier aus meiner RAW das DOIF

defmod Licht_Gesamt DOIF {if ([$SELF:"^Licht_AN:.AN$"]){\
if ([Licht_Status_Flur_Vorne] eq "off") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne EIN\
if ([Licht_Status_Flur_Hinten] eq "off") {fhem_set("Zuimpuls on-for-timer 0.2")};; ## Flur Hinten EIN\
if ([MCP0_A3] eq "off") {fhem_set("MCP1_A2 on-for-timer 0.2")};; ## Küche Mitte EIN\
set_Exec("ICON",2,'set_Reading("Licht_AN","inaktiv",1)');;\
}\
}\
\
{if ([$SELF:"^Licht_AUS:.AUS$"]){\
if ([Licht_Status_Flur_Vorne] eq "on") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne AUS\
if ([Licht_Status_Flur_Hinten] eq "on") {fhem_set("Zuimpuls on-for-timer 0.2")};; ## Flur Vorne AUS\
if ([MCP0_A3] eq "on") {fhem_set("MCP1_A2 on-for-timer 0.2")};; ## Küche Mitte AUS\
set_Exec("ICON1",2,'set_Reading("Licht_AUS","inaktiv",1)');;\
}\
}
attr Licht_Gesamt group Gesamt
attr Licht_Gesamt room Licht_Gesamt
attr Licht_Gesamt uiTable { package ui_Table;;;;\
}\
\
"Licht_AN"|switch([Licht_Gesamt:Licht_AN],"general_an","general_an\@red","inaktiv","AN")\
"Licht_AUS"|switch([Licht_Gesamt:Licht_AUS],"general_aus","general_aus\@red","inaktiv","AUS") \
\
\


setstate Licht_Gesamt initialized
setstate Licht_Gesamt 2021-12-18 00:50:08 Licht_AN inaktiv
setstate Licht_Gesamt 2021-12-18 00:52:08 Licht_AUS inaktiv
setstate Licht_Gesamt 2021-12-18 00:52:18 mode enabled
setstate Licht_Gesamt 2021-12-18 00:52:18 state initialized



Was soll jetzt wie funktionieren.
Ich habe ein icon für AN und ein icon für AUS mit der switch Funktion angelegt.
Damit bekomme ich zwei Readings in diesem DOIF.

Licht_AN  mit den inhalt entweder AN oder inaktiv
Licht_AUS mit den Inhalt entweder AUS oder inaktiv


klicke ich jetzt auf das icon AN wird der erste Block ausgeführt das icon AN wird für zwei Sekunden auf rot gestellt und dann wieder zurück in seine Ursprungsfarbe gesetzt.
In dieser Zeit sollten dann alle Stromstoßschalter geschaltet haben. Jetzt steht das Reading für Licht_AN auf inaktiv.
Klicke ich jetzt nochmal auf das AN Icon wird er Erste Block nicht nochmal ausgelöst und das Icon wird auch nicht rot so wie ich gerne hätte.
Lediglich das Reading für Licht_AN wird erneut auf inaktiv gesetzt.
Erst wenn ich noch einmal auf das Icon AN klicke geht das Reading Licht_AN auf AN das Icon wird rot und der erste Block wird ausgeführt.
Wenn ich nach jeden klick auf das Icon AN einen Browser refresh mit F5 mache habe ich dieses Verhalten nicht.
Es sieht so aus als ob die switch Funktion den letzten wert behält und dann erst den nächsten Wert nimmt. Sprich so wie in meiner Funktion AN => inaktiv => AN
Kommt jetzt ein inaktiv von einer anderen Seite, hier aus den set_Reading("Licht_AN","inaktiv",1) scheint die switch Funktion intern immer noch auf AN zu stehen.
Es läst sich auch schön reproduzieren wenn man auf AN klick wartet bis Icon nicht mehr rot ist.
Dann auf AUS klickt wartet bis Icon AUS nicht mehr rot ist.
Wenn jetz auf AN geklickt wird passiert erst was wenn man nochmal auf AN klickt und so weiter.

Was mache ich da nur wieder nicht Richtig.
Ich freue mich auf Tips.

Viele Grüsse

Stephan






Damian

Ich befürchte, du hast nichts falsch gemacht.

Die switch-Funktion basiert auf dem FHEM-Widget iconSwitch.  Dieses Widget wurde von Ellert programmiert.
Dieses Verhalten ist mir seiner Zeit auch aufgefallen. Ellert konnte damals keine Lösung finden.

Das Problem ist offenbar, dass das Widget intern eine Zustandsänderung nicht mitbekommt, wenn sie von außen kommt (bei dir z. B. durch set_Reading("Licht_AN","inaktiv",1)). Dafür ist ein Refresh des Bildschirms nötig, damit das Widget den neuen Zustand mitbekommt.

Bisher habe ich die Finger von der Widget-Programmierung auf der Javascript-Seite gelassen.

Ich plane aber in naher Zukunft (vielleicht reichen die Weihnachtsferien) eigene FHEM-Widgets zu erstellen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Hallo Damian

Vielen dank für die schnelle Antwort.

Dann bin ich ja beruhigt das ich nichts falsch gemacht habe.  :)

Ist das dann vieleicht auch der Grund das wenn ich meine uiTable konfig nach uiState kopiere die Icons nach Betätigung kpl. verschwinden
und erst nach einen refresh wieder da sind ?

Viele Grüsse

Stephan

Damian

Zitat von: Stelaku am 18 Dezember 2021, 11:35:51
Ist das dann vieleicht auch der Grund das wenn ich meine uiTable konfig nach uiState kopiere die Icons nach Betätigung kpl. verschwinden
und erst nach einen refresh wieder da sind ?

Das kann alles damit zusammenhängen. Leider sind das Mechanismen außerhalb des DOIFs, die ich nicht in meiner Hand habe.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Zitat von: Damian am 18 Dezember 2021, 17:28:13
Das kann alles damit zusammenhängen. Leider sind das Mechanismen außerhalb des DOIFs, die ich nicht in meiner Hand habe.

Was in uiTable korrekt funktioniert, ist das Widget iconRadio:

widget([$SELF:Licht_AN],"iconRadio,\@red,AN,general_an")

siehe Animation:
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Hallo Damian

Vielen dank für die coole Lösung das funktioniert einwandfrei. Hatte schon überlegt das mit devStateIcon und webCmdLabel zu Lösen. Aber so ist es um ein vielfaches leichter.

Jetzt hätte ich aber noch eine frage zu meinen DOIF in den ich alle meine Lampen auf einmal ein oder ausschalten möchte. Das íst jetzt schon etwas grösser geworden.

Hier eine RAW kopie
defmod Licht_Gesamt DOIF {if ([$SELF:"^Licht_AN:.AN$"]){\
if ([Licht_Status_Flur_Vorne] eq "off") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne EIN\
if ([Licht_Status_Flur_Hinten] eq "off") {fhem_set("Zuimpuls on-for-timer 0.2")};; ## Flur Hinten EIN\
if ([MCP0_A3] eq "off") {fhem_set("MCP1_A2 on-for-timer 0.2")};; ## Küche Mitte EIN\
if ([GPIO12] eq "off") {fhem_set("GPIO16 on-for-timer 0.2")};; ## Schlafzimmer EIN\
if ([MCP0_A6] eq "off") {fhem_set("MCP1_A3 on-for-timer 0.2")};; ## Esszimmer EIN\
if ([MCP0_A4] eq "off") {fhem_set("MCP1_A1 on-for-timer 0.2")};; ## Stube EIN\
if ([MCP0_A0] eq "off") {fhem_set("MCP1_A0 on-for-timer 0.2")};; ## Bad mitte EIN\
if ([GPIO21] eq "off") {fhem_set("GPIO6 on-for-timer 0.2")};; ## Bad links EIN\
if ([GPIO20] eq "off") {fhem_set("GPIO13 on-for-timer 0.2")};; ## Bad rechts EIN\
if ([MCP0_A1] eq "off") {fhem_set("MCP1_A4 on-for-timer 0.2")};; ## Küche rechts EIN\
if ([MCP0_B6] eq "off") {fhem_set("MCP1_A5 on-for-timer 0.2")};; ## Küche links EIN\
if ([MCP2_A7] eq "off") {fhem_set("MCP3_A7 on-for-timer 0.2")};; ## Gäste WC EIN\
if ([MCP2_A6] eq "off") {fhem_set("MCP3_A6 on-for-timer 0.2")};; ## Eingang EIN\
if ([MCP2_A4] eq "off") {fhem_set("MCP3_A4 on-for-timer 0.2")};; ## Gästezimmer EIN\
if ([MCP2_A3] eq "off") {fhem_set("MCP3_A3 on-for-timer 0.2")};; ## Stephan mitte EIN\
if ([MCP6_B3] eq "off") {fhem_set("MCP7_B2 on-for-timer 0.2")};; ## Stephan links EIN\
if ([MCP6_B4] eq "off") {fhem_set("MCP7_B3 on-for-timer 0.2")};; ## Stephan rechts EIN\
if ([MCP2_A5] eq "off") {fhem_set("MCP3_A5 on-for-timer 0.2")};; ## Keller EIN\
if ([MCP2_A2] eq "off") {fhem_set("MCP3_B7 on-for-timer 0.2")};; ## Silke mitte EIN\
if ([MCP2_A1] eq "off") {fhem_set("MCP3_A2 on-for-timer 0.2")};; ## Silke rechts EIN\
if ([MCP6_B0] eq "off") {fhem_set("MCP7_B0 on-for-timer 0.2")};; ## Esszimmer links EIN\
if ([MCP6_B1] eq "off") {fhem_set("MCP7_B1 on-for-timer 0.2")};; ## Esszimmer rechts EIN\
fhem_set("ESPEasy_BueroLampe_Relais on");; ## Stephan Schreibtisch ein\
set_Exec("ICON",2,'set_Reading("Licht_AN","inaktiv",1)');; ## Icon AN wieder auf grün\
}\
}\
\
{if ([$SELF:"^Licht_AUS:.AUS$"]){\
if ([Licht_Status_Flur_Vorne] eq "on") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne AUS\
if ([Licht_Status_Flur_Hinten] eq "on") {fhem_set("Zuimpuls on-for-timer 0.2")};; ## Flur Vorne AUS\
if ([MCP0_A3] eq "on") {fhem_set("MCP1_A2 on-for-timer 0.2")};; ## Küche Mitte AUS\
if ([GPIO12] eq "on") {fhem_set("GPIO16 on-for-timer 0.2")};; ## Schlafzimmer AUS\
if ([MCP0_A6] eq "on") {fhem_set("MCP1_A3 on-for-timer 0.2")};; ## Esszimmer AUS\
if ([MCP0_A4] eq "on") {fhem_set("MCP1_A1 on-for-timer 0.2")};; ## Stube AUS\
if ([MCP0_A0] eq "on") {fhem_set("MCP1_A0 on-for-timer 0.2")};; ## Bad mitt EIN\
if ([GPIO21] eq "on") {fhem_set("GPIO6 on-for-timer 0.2")};; ## Bad links AUS\
if ([GPIO20] eq "on") {fhem_set("GPIO13 on-for-timer 0.2")};; ## Bad rechts AUS\
if ([MCP0_A1] eq "on") {fhem_set("MCP1_A4 on-for-timer 0.2")};; ## Küche rechts AUS\
if ([MCP0_B6] eq "on") {fhem_set("MCP1_A5 on-for-timer 0.2")};; ## Küche links AUS\
if ([MCP2_A7] eq "on") {fhem_set("MCP3_A7 on-for-timer 0.2")};; ## Gäste WC AUS\
if ([MCP2_A6] eq "on") {fhem_set("MCP3_A6 on-for-timer 0.2")};; ## Eingang AUS\
if ([MCP2_A4] eq "on") {fhem_set("MCP3_A4 on-for-timer 0.2")};; ## Gästezimmer AUS\
if ([MCP2_A3] eq "on") {fhem_set("MCP3_A3 on-for-timer 0.2")};; ## Stephan mitte AUS\
if ([MCP6_B3] eq "on") {fhem_set("MCP7_B2 on-for-timer 0.2")};; ## Küche Mitte AUS\
if ([MCP6_B4] eq "on") {fhem_set("MCP7_B3 on-for-timer 0.2")};; ## Stephan rechts AUS\
if ([MCP2_A5] eq "on") {fhem_set("MCP3_A5 on-for-timer 0.2")};; ## Keller AUS\
if ([MCP2_A2] eq "on") {fhem_set("MCP3_B7 on-for-timer 0.2")};; ## Silke mitte AUS\
if ([MCP6_B0] eq "on") {fhem_set("MCP7_B0 on-for-timer 0.2")};; ## Esszimmer links AUS\
if ([MCP2_A1] eq "on") {fhem_set("MCP3_A2 on-for-timer 0.2")};; ## Silke rechts AUS\
if ([MCP6_B1] eq "on") {fhem_set("MCP7_B1 on-for-timer 0.2")};; ## Esszimmer rechts AUS\
fhem_set("ESPEasy_BueroLampe_Relais off");; ## Stephan Schreibtisch AUS\
set_Exec("ICON1",2,'set_Reading("Licht_AUS","inaktiv",1)');; ## Icon AUS wieder auf grün\
}\
}
attr Licht_Gesamt group Gesamt
attr Licht_Gesamt room Licht_Gesamt
attr Licht_Gesamt uiTable { package ui_Table;;;;\
}\
\
"Alle AN"|widget([$SELF:Licht_AN],"iconRadio,\@red,AN,general_an")\
"Alle AUS"|widget([$SELF:Licht_AUS],"iconRadio,\@red,AUS,general_aus")\


setstate Licht_Gesamt initialized
setstate Licht_Gesamt 2021-12-18 20:34:13 Device MCP0_A6
setstate Licht_Gesamt 2021-12-18 12:33:42 Licht_AN inaktiv
setstate Licht_Gesamt 2021-12-18 12:34:22 Licht_AUS inaktiv
setstate Licht_Gesamt 2021-12-18 20:34:13 block_01 executed
setstate Licht_Gesamt 2021-12-18 20:34:13 block_02 executed
setstate Licht_Gesamt 2021-12-18 20:24:05 e_GPIO12_STATE off
setstate Licht_Gesamt 2021-12-18 20:24:06 e_GPIO20_STATE off
setstate Licht_Gesamt 2021-12-18 20:24:05 e_GPIO21_STATE off
setstate Licht_Gesamt 2021-12-18 20:21:20 e_Licht_Status_Flur_Hinten_STATE off
setstate Licht_Gesamt 2021-12-18 20:21:57 e_Licht_Status_Flur_Vorne_STATE off
setstate Licht_Gesamt 2021-12-18 20:23:57 e_MCP0_A0_STATE off
setstate Licht_Gesamt 2021-12-18 19:57:37 e_MCP0_A3_STATE off
setstate Licht_Gesamt 2021-12-18 20:34:13 e_MCP0_A6_STATE on
setstate Licht_Gesamt 2021-12-18 19:45:22 e_MCP2_A1_STATE off
setstate Licht_Gesamt 2021-12-18 19:45:19 e_MCP2_A2_STATE off
setstate Licht_Gesamt 2021-12-18 20:21:24 e_MCP2_A3_STATE on
setstate Licht_Gesamt 2021-12-18 20:15:10 e_MCP2_A4_STATE off
setstate Licht_Gesamt 2021-12-18 20:23:47 e_MCP2_A5_STATE off
setstate Licht_Gesamt 2021-12-18 19:07:18 e_MCP2_A6_STATE off
setstate Licht_Gesamt 2021-12-18 15:46:57 e_MCP6_B0_STATE on
setstate Licht_Gesamt 2021-12-18 15:47:47 e_MCP6_B1_STATE on
setstate Licht_Gesamt 2021-12-18 12:37:21 mode enabled
setstate Licht_Gesamt 2021-12-18 12:37:22 state initialized



Es zeigt sich das Problem beim schalten von 22 Ausgängen der 23017 I2C Port Expander in Abhängigkeit von 22 Eingängen zur selben Zeit, das nicht alle fhem_set Befehle ausgeführt werden.
Das ist auch kein DOIF Problem ich glaube eher das ist ein Zeit Problem.
Ich wollte jetzt versuchen jeden if Zweig etwas zu verzögern damit die Register der verschiedenen MCP´s Zeit haben gelesen und geschrieben zu werden.
sleep Anweisungen habe ich bis jetzt ohne Erfolg versucht  einzubinden.
Habe ich eine andere Möglichkeit die einzelnen if Zweige zu verzögern oder muss ich vor jeden fhem_set Befehl noch einen set_Exec Befehl setzten und diesen dann für jede if Bedingung immer etwas länger verzögern ungefähr so.

{if ([$SELF:"^Licht_AN:.AN$"]){
if ([Licht_Status_Flur_Vorne] eq "off") {set_Exec("timer1",0.2,'fhem_set("Aufimpuls on-for-timer 0.2")')}; ## Flur Vorne EIN
if ([Licht_Status_Flur_Hinten] eq "off") {set_Exec("timer2",0.4,'fhem_set("Zuimpuls on-for-timer 0.2")')}; ## Flur Hinten EIN
if ([MCP0_A3] eq "off") {set_Exec("timer3",0.6,'fhem_set("MCP1_A2 on-for-timer 0.2")')}; ## Küche Mitte EIN
set_Exec("ICON",2,'set_Reading("Licht_AN","inaktiv",1)');
}
}


Konnte es leider noch nicht ausprobieren. Bekomme sonst ärger Zuhause weil ständig das Licht an und aus geht.  :)

Viele Grüsse

Stephan

Damian

Was mir wohl auffällt ist, dass du mit den Angaben der Art:

if ([MCP0_A3] eq "off") {fhem_set("MCP1_A2 on-for-timer 0.2")};;

zusätzliche Trigger definierts, auf die das Modul reagiert. Ganz gefährlich sind die Angaben ohne Reading, wie im oberen Beispiel. Da reagiert das Modul auf alle Events des Devices. Das solltest du bei dieser Menge an Abfragen unbedingt vermeiden. Es reicht ein Fragezeichen davor zu setzen oder konventionell mit ReadingsVal arbeiten.

Du programmiert ja im wesentlichen in Perl. Warum nutzt du nicht die Möglichkeiten einer höheren Programmiersprache, die dir zur Verfügung stehen?

subs {
sub an {
my ($dev)=@_;
if (ReadingsVal($dev,"state","") eq "off") {set_Exec($dev,::rand(5),"fhem_set('$dev on-for-timer 0.2')")};
}
}

Dann brauchst du nur aufrufen:

if ([$SELF:"^Licht_AN:.AN$"]){
  an ("MCP0_A3");
  an ("GPIO12");
  ...

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Hallo Damian

Das ist nochmal ein guter Tip mit den [?] gewehsen. Es funktioniert jetzt auch mit der sehr umständlichen Umsetzung das ich alle Device´s mit einer kleinen Verzögerung on-for-timer setze.

Hier meine kleine Raw  ;D
defmod Licht_Gesamt DOIF {if ([$SELF:"^Licht_AN:.AN$"]){\
if ([?Licht_Status_Flur_Vorne] eq "off") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne EIN\
if ([?Licht_Status_Flur_Hinten] eq "off") {set_Exec("t1",0.2,'fhem_set("Zuimpuls on-for-timer 0.2")')};; ## Flur Hinten EIN\
if ([?MCP0_A3] eq "off") {set_Exec("t2",0.4,'fhem_set("MCP1_A2 on-for-timer 0.2")')};; ## Küche Mitte EIN\
if ([?GPIO12] eq "off") {set_Exec("t3",0.6,'fhem_set("GPIO16 on-for-timer 0.2")')};; ## Schlafzimmer EIN\
if ([?MCP0_A6] eq "off") {set_Exec("t4",0.8,'fhem_set("MCP1_A3 on-for-timer 0.2")')};; ## Esszimmer EIN\
if ([?MCP0_A4] eq "off") {set_Exec("t5",1,'fhem_set("MCP1_A1 on-for-timer 0.2")')};; ## Stube EIN\
if ([?MCP0_A0] eq "off") {set_Exec("t6",1.2,'fhem_set("MCP1_A0 on-for-timer 0.2")')};; ## Bad mitte EIN\
if ([?GPIO21] eq "off") {set_Exec("t7",1.4,'fhem_set("GPIO6 on-for-timer 0.2")')};; ## Bad links EIN\
if ([?GPIO20] eq "off") {set_Exec("t8",1.6,'fhem_set("GPIO13 on-for-timer 0.2")')};; ## Bad rechts EIN\
if ([?MCP0_A1] eq "off") {set_Exec("t9",1.8,'fhem_set("MCP1_A4 on-for-timer 0.2")')};; ## Küche rechts EIN\
if ([?MCP0_B6] eq "off") {set_Exec("t10",1.8,'fhem_set("MCP1_A5 on-for-timer 0.2")')};; ## Küche links EIN\
if ([?MCP2_A7] eq "off") {set_Exec("t11",2,'fhem_set("MCP3_A7 on-for-timer 0.2")')};; ## Gäste WC EIN\
if ([?MCP2_A6] eq "off") {set_Exec("t11",2,'fhem_set("MCP3_A6 on-for-timer 0.2")')};; ## Eingang EIN\
if ([?MCP2_A4] eq "off") {set_Exec("t11",2,'fhem_set("MCP3_A4 on-for-timer 0.2")')};; ## Gästezimmer EIN\
if ([?MCP2_A3] eq "off") {set_Exec("t14",2.6,'fhem_set("MCP3_A3 on-for-timer 0.2")')};; ## Stephan mitte EIN\
if ([?MCP6_B3] eq "off") {set_Exec("t15",2.8,'fhem_set("MCP7_B2 on-for-timer 0.2")')};; ## Stephan links EIN\
if ([?MCP6_B4] eq "off") {set_Exec("t16",3.0,'fhem_set("MCP7_B3 on-for-timer 0.2")')};; ## Stephan rechts EIN\
if ([?MCP2_A5] eq "off") {set_Exec("t17",3.2,'fhem_set("MCP3_A5 on-for-timer 0.2")')};; ## Keller EIN\
if ([?MCP2_A2] eq "off") {set_Exec("t18",3.4,'fhem_set("MCP3_B7 on-for-timer 0.2")')};; ## Silke mitte EIN\
if ([?MCP2_A1] eq "off") {set_Exec("t19",3.6,'fhem_set("MCP3_A2 on-for-timer 0.2")')};; ## Silke rechts EIN\
if ([?MCP6_B0] eq "off") {set_Exec("t20",3.8,'fhem_set("MCP7_B0 on-for-timer 0.2")')};; ## Esszimmer links EIN\
if ([?MCP6_B1] eq "off") {set_Exec("t21",4,'fhem_set("MCP7_B1 on-for-timer 0.2")')};; ## Esszimmer rechts EIN\
fhem_set("ESPEasy_BueroLampe_Relais on");; ## Stephan Schreibtisch ein\
set_Exec("ICON",2,'set_Reading("Licht_AN","inaktiv",1)');; ## Icon AN wieder auf grün\
}\
}\
\
{if ([$SELF:"^Licht_AUS:.AUS$"]){\
if ([?Licht_Status_Flur_Vorne] eq "on") {fhem_set("Aufimpuls on-for-timer 0.2")};; ## Flur Vorne AUS\
if ([?Licht_Status_Flur_Hinten] eq "on") {set_Exec("t30",0.2,'fhem_set("Zuimpuls on-for-timer 0.2")')};; ## Flur Vorne AUS\
if ([?MCP0_A3] eq "on") {set_Exec("t31",0.4,'fhem_set("MCP1_A2 on-for-timer 0.2")')};; ## Küche Mitte AUS\
if ([?GPIO12] eq "on") {set_Exec("t32",0.6,'fhem_set("GPIO16 on-for-timer 0.2")')};; ## Schlafzimmer AUS\
if ([?MCP0_A6] eq "on") {set_Exec("t33",0.8,'fhem_set("MCP1_A3 on-for-timer 0.2")')};; ## Esszimmer AUS\
if ([?MCP0_A4] eq "on") {set_Exec("t34",1,'fhem_set("MCP1_A1 on-for-timer 0.2")')};; ## Stube AUS\
if ([?MCP0_A0] eq "on") {set_Exec("t35",1.2,'fhem_set("MCP1_A0 on-for-timer 0.2")')};; ## Bad mitt EIN\
if ([?GPIO21] eq "on") {set_Exec("t36",1.4,'fhem_set("GPIO6 on-for-timer 0.2")')};; ## Bad links AUS\
if ([?GPIO20] eq "on") {set_Exec("t37",1.6,'fhem_set("GPIO13 on-for-timer 0.2")')};; ## Bad rechts AUS\
if ([?MCP0_A1] eq "on") {set_Exec("t38",1.8,'fhem_set("MCP1_A4 on-for-timer 0.2")')};; ## Küche rechts AUS\
if ([?MCP0_B6] eq "on") {set_Exec("t39",2,'fhem_set("MCP1_A5 on-for-timer 0.2")')};; ## Küche links AUS\
if ([?MCP2_A7] eq "on") {set_Exec("t40",2.2,'fhem_set("MCP3_A7 on-for-timer 0.2")')};; ## Gäste WC AUS\
if ([?MCP2_A6] eq "on") {set_Exec("t41",2.4,'fhem_set("MCP3_A6 on-for-timer 0.2")')};; ## Eingang AUS\
if ([?MCP2_A4] eq "on") {set_Exec("t42",2.6,'fhem_set("MCP3_A4 on-for-timer 0.2")')};; ## Gästezimmer AUS\
if ([?MCP2_A3] eq "on") {set_Exec("t43",2.8,'fhem_set("MCP3_A3 on-for-timer 0.2")')};; ## Stephan mitte AUS\
if ([?MCP6_B3] eq "on") {set_Exec("t44",3,'fhem_set("MCP7_B2 on-for-timer 0.2")')};; ## Küche Mitte AUS\
if ([?MCP6_B4] eq "on") {set_Exec("t45",3.2,'fhem_set("MCP7_B3 on-for-timer 0.2")')};; ## Stephan rechts AUS\
if ([?MCP2_A5] eq "on") {set_Exec("t46",3.4,'fhem_set("MCP3_A5 on-for-timer 0.2")')};; ## Keller AUS\
if ([?MCP2_A2] eq "on") {set_Exec("t47",3.6,'fhem_set("MCP3_B7 on-for-timer 0.2")')};; ## Silke mitte AUS\
if ([?MCP6_B0] eq "on") {set_Exec("t48",3.8,'fhem_set("MCP7_B0 on-for-timer 0.2")')};; ## Esszimmer links AUS\
if ([?MCP2_A1] eq "on") {set_Exec("t49",4.0,'fhem_set("MCP3_A2 on-for-timer 0.2")')};; ## Silke rechts AUS\
if ([?MCP6_B1] eq "on") {set_Exec("t50",4.2,'fhem_set("MCP7_B1 on-for-timer 0.2")')};; ## Esszimmer rechts AUS\
fhem_set("ESPEasy_BueroLampe_Relais off");; ## Stephan Schreibtisch AUS\
set_Exec("ICON1",4,'set_Reading("Licht_AUS","inaktiv",1)');; ## Icon AUS wieder auf grün\
}\
}
attr Licht_Gesamt group Gesamt
attr Licht_Gesamt room Licht_Gesamt
attr Licht_Gesamt uiTable { package ui_Table;;;;\
}\
\
"Alle AN"|widget([$SELF:Licht_AN],"iconRadio,\@red,AN,general_an")\
"Alle AUS"|widget([$SELF:Licht_AUS],"iconRadio,\@red,AUS,general_aus")\


setstate Licht_Gesamt initialized
setstate Licht_Gesamt 2021-12-19 16:39:41 Licht_AN inaktiv
setstate Licht_Gesamt 2021-12-19 16:39:58 Licht_AUS inaktiv
setstate Licht_Gesamt 2021-12-19 16:39:58 block_01 executed
setstate Licht_Gesamt 2021-12-19 16:39:58 block_02 executed
setstate Licht_Gesamt 2021-12-19 16:39:58 e_Licht_Gesamt_events Licht_AUS: inaktiv
setstate Licht_Gesamt 2021-12-19 16:38:32 mode enabled
setstate Licht_Gesamt 2021-12-19 16:38:32 state initialized



Ich muss ja leider gestehen das ich mich noch überhaupt nicht mit den subrotine in Fhem beschäftigt habe.
Irgendwie habe ich es dann immer mit etlich lesen und codesnipsel hinbekommen.
Die 99_myUtils.pm ist für mich noch absolutes Neuland.
Aber die Möglich mit subrotinen direkt im Doif habe ich in der comandref zwar immer gelesen aber nie so richtig beachtet
weil ich ja dachte da musste wieder etwas in der 99_myUtils.pm machen lieber nicht.

Ich hab jetzt Dein Beispiel mal genommen und versucht in meine Instanz mit aufzunehemen.
Leider Funktioniert das noch nicht. Ich bekomme Fehlermeldungen das er die sub nicht kennt sprich den rand Befehl.
wenn ich rand(5) durch 1 ersetzte wird mir die Variable $dev als nicht declariert gemeldet.
condition c01: Undefined subroutine &main::rand called, line 5.
in fhem_set("$dev on-for-timer 1"): Global symbol "$dev" requires explicit package name (did you forget to declare "my $dev"?) at (eval 16210) line 1.


Hier auch mal ein list des DOIF im fehlerfall
Internals:
   CFGFN     
   DEF        subs {
sub AN {
my ($dev)=@_;

if (ReadingsVal($dev,"state","") eq "off"){set_Exec($dev,::rand(5),'fhem_set("$dev on-for-timer 1")');
}
}
}

{if ([Gesamt:"^Licht_AN:.AN$"]){

AN ("Zuimpuls");
AN ("Aufimpuls");
set_Exec("ICON",4,'set_Reading("Licht_AN","inaktiv",1)')
}
}
   FUUID      61bf24c0-f33f-4b4d-47b4-7fed0cc39edae540
   MODEL      Perl
   NAME       Gesamt
   NOTIFYDEV  global,Gesamt
   NR         133
   NTFY_ORDER 50-Gesamt
   STATE      initialized
   TYPE       DOIF
   VERSION    24905 2021-09-01 18:35:54
   READINGS:
     2021-12-19 17:16:05   Licht_AN        AN
     2021-12-19 15:48:09   Licht_AUS       AUS
     2021-12-19 17:16:05   block_01        condition c01: Undefined subroutine &main::rand called, line 5.

     2021-12-19 17:16:05   e_Gesamt_events Licht_AN: AN
     2021-12-19 17:16:02   mode            enabled
     2021-12-19 17:16:02   state           initialized
   Regex:
     accu:
     collect:
     cond:
       Gesamt:
         0:
           &STATE     ^Gesamt$
     uiTable:
       Gesamt:
         Gesamt_uiTable_c_0_1_0_0:
           Licht_AN   ^Gesamt$:^Licht_AN:
         Gesamt_uiTable_c_1_1_0_0:
           Licht_AUS  ^Gesamt$:^Licht_AUS:
   condition:
     0          if (::EventDoIf('Gesamt',$hash,'^Licht_AN:.AN$',1)){

AN ("Zuimpuls");
AN ("Aufimpuls");
set_Exec("ICON",4,'set_Reading("Licht_AN","inaktiv",1)')
}

   helper:
     DEVFILTER  ^global$|^Gesamt$
     NOTIFYDEV  global|Gesamt
     event      Licht_AN: AN
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev Gesamt
     triggerEvents:
       Licht_AN: AN
       e_Gesamt_events: Licht_AN: AN
       block_01: condition c01: Undefined subroutine &main::rand called, line 5.

     triggerEventsState:
       Licht_AN: AN
       e_Gesamt_events: Licht_AN: AN
       block_01: condition c01: Undefined subroutine &main::rand called, line 5.

   internals:
   perlblock:
     0          block_01
   readings:
   trigger:
     all         Gesamt
   uiState:
   uiTable:
     dev        Gesamt
     header     
<table uitabid='DOIF-Gesamt' class=' block wide uiTabledoif doif-Gesamt ' style='border-top:none;'>
     package    package ui_Table;
     reading    Licht_AUS
     table:
       0:
         0:
           0:
             0          package ui_Table;"Alle AN"
         1:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'Gesamt_uiTable_c_0_1_0_0',widget(::ReadingValDoIf($hash,'Gesamt','Licht_AN'),"iconRadio,\@red,AN,general_an"),'Gesamt','Licht_AN')
       1:
         0:
           0:
             0          package ui_Table;"Alle AUS"
         1:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'Gesamt_uiTable_c_1_1_0_0',widget(::ReadingValDoIf($hash,'Gesamt','Licht_AUS'),"iconRadio,\@red,AUS,general_aus"),'Gesamt','Licht_AUS')
     tc:
     td:
       0:
       1:
     tr:
Attributes:
   group      Gesamt
   room       Licht_Gesamt
   uiTable    { package ui_Table;;
}

"Alle AN"|widget([$SELF:Licht_AN],"iconRadio,\@red,AN,general_an")
"Alle AUS"|widget([$SELF:Licht_AUS],"iconRadio,\@red,AUS,general_aus")

Wenn ich den code richtig verstehe wird ja beim AN Aufruf die $dev mit den Device namen zb. im ersten Fall mit Zuimpuls belegt und dann wird sie geprüft ob sie off ist.
danach wird ein timer mit einer Zufallsverzögerung gestellt der nach Ablauf des timers $dev also Zuimpuls on-for-timer 1 stellt.
Das ist wirklich eine schöne Sache und auch viel übersichtlicher. Als meine Mamut def
Es gibt da aber noch eine kleine Sache die so bei mir leider nicht funktionieren wird.
Ich bräuchte da noch eine zweite Variable die das Gerät für den Status on oder off darstellt. Die sind in meiner Hardware getrennt.
Also für den ersten Fall ist Zuimpuls der Ausgang für das Stromstossrelais und der Dazugehörige Eingang mit dem Reading on oder off ist das Device Licht_Status_Flur_Vorne
und so weiter.
Da habe ich jetzt aktuell überhaupt keine idee wie das geht.

Würde mich freuen wenn Du mir da noch ein wenig helfen könntest.

Viele Grüsse

Stephan





Damian

Dieses Beispiel funktioniert bei mir jetzt korrekt:

defmod di_sub DOIF subs {\
sub AN {\
my ($dev,$onoff)=@_;;\
\
if (ReadingsVal($dev,"state","") ne $onoff) \
  {set_Exec($dev,rand(5),"fhem_set('$dev $onoff')")}\
}\
}\
\
{if (1){\
AN ("bla","on");;\
}\
}\
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Hallo Damian

Wirklich vielen dank für die hilfe das funktioniert wie blöde. Bringt schon spaß auf das icon zu klicken und mit anzuhören wie
22 Eltako´s inerhalb von 5 sekunden zufällig losknattern.
meine kpl. fertige Raw packe ich der vollständikeit halber mal noch mit rein. Solche Beispiele sind es die mir in diesen Forum immer wieder weitergeholfen habe.


defmod Gesamt DOIF subs {\
sub AN {\
my ($status,$eltako)=@_;;;;\
\
if (ReadingsVal($status,"state","") eq "off")\
  {set_Exec($eltako,rand(5),"fhem_set('$eltako on-for-timer 0.3')")}\
}\
sub AUS {\
my ($status,$eltako)=@_;;;;\
\
if (ReadingsVal($status,"state","") eq "on")\
  {set_Exec($eltako,rand(5),"fhem_set('$eltako on-for-timer 0.3')")}\
}\
}\
\
{if ([Gesamt:"^Licht_AN:.AN$"]){\
##Status Device Eltako\
AN ("Licht_Status_Flur_Vorne", "Aufimpuls");;\
AN ("Licht_Status_Flur_Hinten", "Zuimpuls");;\
AN ("MCP0_A3", "MCP1_A2");;\
AN ("GPIO12", "GPIO16");;\
AN ("MCP0_A6", "MCP1_A3");;\
AN ("MCP0_A4", "MCP1_A1");;\
AN ("MCP0_A0", "MCP1_A0");;\
AN ("GPIO21", "GPIO6");;\
AN ("GPIO20", "GPIO13");;\
AN ("MCP0_A1", "MCP1_A4");;\
AN ("MCP0_B6", "MCP1_A5");;\
AN ("MCP2_A7", "MCP3_A7");;\
AN ("MCP2_A6", "MCP3_A6");;\
AN ("MCP2_A4", "MCP3_A4");;\
AN ("MCP2_A3", "MCP3_A3");;\
AN ("MCP6_B3", "MCP7_B2");;\
AN ("MCP6_B4", "MCP7_B3");;\
AN ("MCP2_A5", "MCP3_A5");;\
AN ("MCP2_A2", "MCP3_B7");;\
AN ("MCP2_A1", "MCP3_A2");;\
AN ("MCP6_B0", "MCP7_B0");;\
AN ("MCP6_B1", "MCP7_B1");;\
set_Exec("Icon",1,'set_Reading("Licht_AN","inaktiv",1)');;\
}\
}\
{if ([Gesamt:"^Licht_AUS:.AUS$"]){\
##Status Device Eltako\
AUS ("Licht_Status_Flur_Vorne", "Aufimpuls");;\
AUS ("Licht_Status_Flur_Hinten","Zuimpuls");;\
AUS ("MCP0_A3", "MCP1_A2");;\
AUS ("GPIO12", "GPIO16");;\
AUS ("MCP0_A6", "MCP1_A3");;\
AUS ("MCP0_A4", "MCP1_A1");;\
AUS ("MCP0_A0", "MCP1_A0");;\
AUS ("GPIO21", "GPIO6");;\
AUS ("GPIO20", "GPIO13");;\
AUS ("MCP0_A1", "MCP1_A4");;\
AUS ("MCP0_B6", "MCP1_A5");;\
AUS ("MCP2_A7", "MCP3_A7");;\
AUS ("MCP2_A6", "MCP3_A6");;\
AUS ("MCP2_A4", "MCP3_A4");;\
AUS ("MCP2_A3", "MCP3_A3");;\
AUS ("MCP6_B3", "MCP7_B2");;\
AUS ("MCP6_B4", "MCP7_B3");;\
AUS ("MCP2_A5", "MCP3_A5");;\
AUS ("MCP2_A2", "MCP3_B7");;\
AUS ("MCP2_A1", "MCP3_A2");;\
AUS ("MCP6_B0", "MCP7_B0");;\
AUS ("MCP6_B1", "MCP7_B1");;\
set_Exec("Icon",1,'set_Reading("Licht_AUS","inaktiv",1)');;\
}\
}
attr Gesamt group Gesamt
attr Gesamt room Licht_Gesamt
attr Gesamt uiTable { package ui_Table;;;;\
}\
\
"Alle AN"|widget([$SELF:Licht_AN],"iconRadio,\@red,AN,general_an")\
"Alle AUS"|widget([$SELF:Licht_AUS],"iconRadio,\@red,AUS,general_aus")\

attr Gesamt verbose 5

setstate Gesamt initialized
setstate Gesamt 2021-12-19 18:59:36 Licht_AN inaktiv
setstate Gesamt 2021-12-19 18:59:14 Licht_AUS inaktiv
setstate Gesamt 2021-12-19 18:59:36 block_01 executed
setstate Gesamt 2021-12-19 18:59:36 block_02 executed
setstate Gesamt 2021-12-19 18:59:36 e_Gesamt_events Licht_AN: inaktiv
setstate Gesamt 2021-12-19 18:59:08 mode enabled
setstate Gesamt 2021-12-19 18:59:08 state initialized



Ich wünsche Dir noch einen schönen rest Sonntag und eine ruhige vorweihnachts Zeit.

Stephan



Damian

Zitat von: Stelaku am 19 Dezember 2021, 19:08:32
Wirklich vielen dank für die hilfe das funktioniert wie blöde. Bringt schon spaß auf das icon zu klicken und mit anzuhören wie
22 Eltako´s inerhalb von 5 sekunden zufällig losknattern.
meine kpl. fertige Raw packe ich der vollständikeit halber mal noch mit rein. Solche Beispiele sind es die mir in diesen Forum immer wieder weitergeholfen habe.


Schön, dass es funktioniert. Das Besondere an dieser Vorgehensweise ist, dass alles an einer Stelle ist und zwar mit der Mächtigkeit und Performance einer höheren Programmiersprache - keine verstreuten Dummys, keine verstreuten notifys, keine verstreuten Perlfunktionen in irgendwelchen utils, keine webCmdLabels in irgendwelchen Dummys ...
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF