Schleifen in ftui-code

Begonnen von Marko1976, 08 August 2025, 23:31:56

Vorheriges Thema - Nächstes Thema

Guybrush

Das mit dem doif ist klar. Aber woher weis man dann im Vorfeld wieviele Einträge darzustellen sind? Wenn es immer eine feste gleiche Anzahl gäb - ok. Aber das ist ja bei den gewünschten Szenarien nicht gegeben

juemuc

#16
In dem Du eine generische Abfrage definierst.

Ich habe hier nur Sensoren fest "verdratet", da ich Tür und Fenster unterscheiden wollte und die gleiche Art von Sensoren verwende. Wäre eventuell auch anders gegangen.

Internals:
   DEF        ## Visualisierung offener Türen und Fenster
   FUUID      652ee6da-f33f-a57c-8697-7b3137d7c19e6c3c
   MODEL      FHEM
   NAME       di_uiTable_windows
   NOTIFYDEV  global,.*(0007DF29950D53$).*,di_uiTable_windows,.*(^HMIP|^HM_Sec_RHS|OEQ0424862$).*,.*(HM|HmIP_SRH).*
   NR         259
   NTFY_ORDER 50-di_uiTable_windows
   STATE      initialized
   TYPE       DOIF
   VERSION    29460 2024-12-29 20:25:48
   eventCount 166
   READINGS:
     2024-05-09 12:23:24   cmd             0
     2025-08-10 17:57:16   count           0
     2025-08-10 13:23:42   doors           alles zu
     2024-05-09 12:23:24   mode            enabled
     2024-05-09 12:23:24   state           initialized
     2025-08-10 15:05:00   windows         alles zu
   Regex:
     accu:
     bar:
     barAvg:
     collect:
     event_Readings:
       :
         count:
           "HM|HmIP_SRH" HM|HmIP_SRH
         doors:
           "0007DF29950D53$:^state|OEQ0223456$:^state" 0007DF29950D53$:^state|OEQ0223456$:^state
         windows:
           "^HMIP|^HM_Sec_RHS|OEQ0424862$:^state" ^HMIP|^HM_Sec_RHS|OEQ0424862$:^state
     uiTable:
       di_uiTable_windows:
         di_uiTable_windows_uiTable_c_0_1_0_0:
           windows    ^di_uiTable_windows$:^windows:
         di_uiTable_windows_uiTable_c_0_2_0_0:
           windows    ^di_uiTable_windows$:^windows:
         di_uiTable_windows_uiTable_c_1_1_0_0:
           doors      ^di_uiTable_windows$:^doors:
         di_uiTable_windows_uiTable_c_1_2_0_0:
           doors      ^di_uiTable_windows$:^doors:
         di_uiTable_windows_uiTable_c_2_1_0_0:
           count      ^di_uiTable_windows$:^count:
   condition:
   do:
     0:
   event_Readings:
     count      ::AggregateDoIf($hash,'#','HM|HmIP_SRH','state','"open|tilted"','"0"')
     doors      ::AggregateDoIf($hash,'@as(<br>)','0007DF29950D53$','state','"open|tilted"','"alles zu"')
     windows    ::AggregateDoIf($hash,'@as(<br>)','^HMIP|^HM_Sec_RHS|OEQ0424862$','state','"open|tilted"','"alles zu"')
   helper:
     NOTIFYDEV  global,.*(0007DF29950D53$).*,di_uiTable_windows,.*(^HMIP|^HM_Sec_RHS|OEQ0424862$).*,.*(HM|HmIP_SRH).*
     event      2.POWER: 0.02
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev HM_ES_PMSw1_Pl_DN_R1_NEQ1662710
     triggerEvents:
       2.POWER: 0.02
     triggerEventsState:
       2.POWER: 0.02
   perlblock:
   uiState:
   uiTable:
     dev        di_uiTable_windows
     header    
<table uitabid='DOIF-di_uiTable_windows' class=' block wide uiTabledoif doif-di_uiTable_windows ' style='border-top:none;'>
     package    package ui_Table;
     reading    count
     table:
       0:
         0:
           0:
             0          package ui_Table;"Fenster"
         1:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'di_uiTable_windows_uiTable_c_0_1_0_0',icon(::ReadingValDoIf($hash,'di_uiTable_windows','windows'),"fts_window_roof_open_2\@red","fts_window_roof\@black",".*","alles zu"),'','di_uiTable_windows','windows')
         2:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'di_uiTable_windows_uiTable_c_0_2_0_0',::ReadingValDoIf($hash,'di_uiTable_windows','windows'),"")
       1:
         0:
           0:
             0          package ui_Table;"Türen"
         1:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'di_uiTable_windows_uiTable_c_1_1_0_0',icon(::ReadingValDoIf($hash,'di_uiTable_windows','doors'),"fts_door_open\@red","fts_door\@black",".*","alles zu"),'','di_uiTable_windows','doors')
         2:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'di_uiTable_windows_uiTable_c_1_2_0_0',::ReadingValDoIf($hash,'di_uiTable_windows','doors'),"")
       2:
         0:
           0:
             0          package ui_Table;"Anzahl"
         1:
           0:
             0          package ui_Table;::DOIF_Widget($hash,$reg,'di_uiTable_windows_uiTable_c_2_1_0_0',::ReadingValDoIf($hash,'di_uiTable_windows','count'),"")
     tc:
       1          align='center'
       2          align='left'
     td:
       0:
       1:
       2:
     tr:
Attributes:
   addStateEvent 1
   alias      Fenster- und Türstatus
   devStateStyle style="text-align:right"
   event-on-change-reading .*
   event_Readings windows:[@as(<br>)"^HMIP|^HM_Sec_RHS|OEQ0424862$:^state":state:"open|tilted","alles zu"],
doors:[@as(<br>)"0007DF29950D53$:^state|OEQ0223456$:^state":state:"open|tilted","alles zu"],
count:[#"HM|HmIP_SRH":state:"open|tilted","0"]
   group      Fenster-/Türkontakte
   room       Statuszentrale
   uiTable    {
package ui_Table;
$TC{1}="align='center'";
$TC{2}="align='left'";
}
"Fenster"|icon([$SELF:windows],"fts_window_roof_open_2\@red","fts_window_roof\@black",".*","alles zu")|[$SELF:windows]
"Türen"|icon([$SELF:doors],"fts_door_open\@red","fts_door\@black",".*","alles zu")|[$SELF:doors]
"Anzahl"|[$SELF:count]
3x Sonos Play 1, 1x Sonos Arc + Sub, 1 Sonos-One, 1x Sonos Playbar
FB6690 + FB7490 mit 4x Dect 200 und 3 Dect-ULE-Thermostate,  raspberry3B+, HM Funkmodul HM-MOD-RPI-PCB, HM Klingelsensor HM-Sen-DB-PCB, HM (IP) Fensterkontakte und  Amazon Echo Dot,  piVCCU, pi OS (bookworm).

Prof. Dr. Peter Henning

#17
Es ist einfach Unsinn, in einer solchen Abfrage alle Türen und Fenster gleich behandeln zu wollen. Beispiel: Bei schlechtem Wetter ist es hoch relevant, ob ein Dachfenster geöffnet ist. Bei einer Sicherheitsabfrage eher nicht.

Der beste Weg ist eine Liste, die jedem Fenster und jeder Tür Attribute zuordnet - z.B. "RS" für "Regen" und "Sicherheit", oder nur "S" für Sicherheit, oder ein "T" darin bei Türen.

Diese Liste kann man entweder in einer Perl-sub fest anlegen - zumindest für den Anfang ist das der richtige Weg. Und dann bei Funktionsfähigkeit des Codes in ein userAttr auslagern. Jedes Fenster "weiß" damit, für welche Abfragen es in Frage kommt.

Natürlich kann man das dann mit einer einzigen Abfrage
list .*:FILTER=usw machen. Allerdings kommt jetzt noch ein Punkt hinzu: Eine Ausgabe als triviale Liste aller Devices ist etwas für Unwissende. Um das in eine lesbare Form umzuwandeln, muss man schon manuell nacharbeiten. Also in jedem Fall eine nette kleine Perl-sub anlegen. Im Bild sieht man einen Ausschnitt aus dem Feld in FTUI3, das ich mit einem Rotor-Device belegt habe.
<ftui-rotor animation="fade" interval="5">
        <ftui-cell>
                <ftui-label style="font-weight:bold" size="18px">Haus</ftui-label>
                <ftui-label [text]="secProfileC:weblink | ftui_linebreaker()" scroll size="15px">
                </ftui-label>
        </ftui-cell>
        <ftui-cell>
                <ftui-label style="font-weight:bold" size="18px">System</ftui-label>
                <ftui-label [text]="secProfileC:weblink2 | ftui_linebreaker()" scroll size="15px">
                </ftui-label>
        </ftui-cell>
      ... mehrere weitere Zellen
</ftui-rotor>
Ach ja: die Funktion zum Zeilenumbruch muss man natürlich im FTUI3 auch noch hinzufügen
//-- helper function for linebreak

function linebreaker(lines) {
    let linea = lines.split('<br>');
    let num = linea.length;
    let ret = '<ul style="list-style-type:none;margin-left:0px;">';
    for (var i = 0; i < num; i++) {
        ret += '<li>' + linea[i] + '</li>';
    }
    ret += '</ul>';
    return ret;
}

LG

pah