Hallo,
ich habe meine ersten Gehversuche mit DOIF gemacht, und Zeit bis zur Müllabfuhr aus dem Wiki (https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Anzahl_der_Tage_bis_zur_Abfall-Entsorgung) realisiert (Bildchen im Anhang).
Jetzt möchte ich mir jeden Tag diesen Status mit den Tonnenbildchen per TelegramBot schicken.
So weit bin ich gekommen:
defmod diAbfall DOIF ([+00:01]) (set telegram send @meinHandle Status: [dbAbfall:state])
Der schickte mir nach einer Minute zuverlässig Status: initialized.
Wie bekomme ich denn bitte das Bildchen mit den drei Tonnen?
Viele Grüße
Boris
Versuche es mit der neuen Funktion ui_Table::get_uiTable("diAbfall") siehe: https://forum.fhem.de/index.php?topic=144559.0
Diese liefert den HTML-Code, den du benötigst. Sollte auch mit get diAbfall html gehen
Danke, Damian.
ui_Table::get_uiTable("dbAbfall") liefert mir HTML-Kode, und zwar <table>...</table>.
Der Befehl zum Senden ist
set telegram cmdSend @meinHandle { ui_Table::get_uiTable("dbAbfall") }
wobei attr telegram parseModeSend 2_HTML gesetzt ist.
Das führt jedoch zu der Meldung, dass der Start-Tag <table> nicht geparst werden kann. <table> wird von Telegram grundsätzlich nicht verarbeitet. Das steht in der API-Referenz (https://core.telegram.org/bots/api#formatting-options) und lässt sich auch leicht mit
set telegram message @meinHandle <table><tr><td>foo</td></tr></table>
verifizieren.
Dann muss ich wohl noch einen Befehl ohne Table programmieren.
Zitat von: Damian am 03 Mai 2026, 12:21:30Dann muss ich wohl noch einen Befehl ohne Table programmieren.
Allerdings sind fast alle Beispiele als Tabelle definiert - auch dieses Abfall-Beispiel. Die müsste man erst mal umschreiben. Dann kann man auch gleich selbst mit Hilfe der vordefinierten uiTable-Funktionen (hier ui_Table::style und ui_Table::ic) sich seinen HTML-Code zusammen bauen.
Da hänge ich mich dran.
plotAsPng funktioniert mit SVGs.
Zitat von: Damian am 03 Mai 2026, 13:18:36Allerdings sind fast alle Beispiele als Tabelle definiert - auch dieses Abfall-Beispiel. Die müsste man erst mal umschreiben. Dann kann man auch gleich selbst mit Hilfe der vordefinierten uiTable-Funktionen (hier ui_Table::style und ui_Table::ic) sich seinen HTML-Code zusammen bauen.
Habe mich ein wenig in DOIF und sein uiTable-Attribut eingelesen. Mir ist jedoch nicht klar, welche Funktion ich aufrufen muss, um den HTML-Kode im Inneren der Tabelle herauszubekommen, also das Äquivalent von
{ ui_Table::get_uiTable("dbAbfall") }.
Beim Mini-Dashboard für PV-Anlage (https://wiki.fhem.de/wiki/Mini-Dashboard_f%C3%BCr_PV-Anlage) habe ich
ui_Table::ring2() benutzt, das SVG zurückgibt, was ich mit dem im RSS-Modul in ein PNG-Bild plotten konnte. Ohne Verrenkungen können wir aber meines Wissens nach kein HTML in ein Grafikformat rendern, um statt HTML-Kode ein Bild per Telegram zu senden.
Die Alternative wäre dann ein Bild mit dem RSS-Modul zu bauen (die Tonnen sind ja SVG-Grafiken) und mit Telegram zu versenden.
ui_Table definiert eine Tabelle in HTML. Einzelne Zellen der Tabelle könnnen wiederum aus weiteren Elementen bestehen. Dabei wird erkannt, wo die Trigger definiert sind (Angaben der Art [<device>:<reading>]). Es werden dann entsprechende Trigger-Mechanismen aufgesetzt, die beim passenden Event den HTML-Code für das jeweilige Element aktualisieren.
Funktionen wie ring, bar, card, usw. erzeugen HTML-Code insb. SVG-Tags, um vektorbasierte Grafiken zu erzeugen. Man kann sie von überall aufrufen, um den passenden HTML-SVG-Code zu erhalten. So kann man z. B. im Attribut devStateIcon eines Dummys eine uiTable-Funktion aufrufen, um im Status des Dummys die passende Grafik darzustellen.
Der Zugriff auf die einzelnen Tabellenzellen ist nicht vorgesehen, da sie zum Zeitpunkt der Definition andere Funktion nutzen, als bei einem Update einer Zelle durch ein Event. Zusätzlich kann eine Zelle aus beliebig vielen weiteren Elementen bestehen. So sieht alleine eine Zellendefinition der Energy_Card aus, die aus 10 einzelnen Elementen besteht (kann man sich per list des DOIF-Devices unter table anschauen):
...
table:
0:
0:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_0',grid(::ReadingValDoIf($hash,'di_energy_card','grid_power','','144col1d'),::ReadingValDoIf($hash,'di_energy_card','grid_energy_feed'),::ReadingValDoIf($hash,'di_energy_card','grid_energy_consum')),"")
1 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_1',grid_power(::ReadingValDoIf($hash,'di_energy_card','grid_power')),"")
2 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_2',solar(::ReadingValDoIf($hash,'di_energy_card','solar_power','','144col1d'),::ReadingValDoIf($hash,'di_energy_card','solar_energy'),::ReadingValDoIf($hash,'di_energy_card','solar_self_energy')),"")
3 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_3',solar_power(::ReadingValDoIf($hash,'di_energy_card','solar_power')),"")
4 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_4',battery(::ReadingValDoIf($hash,'di_energy_card','battery_power','','144col1d'),::ReadingValDoIf($hash,'di_energy_card','battery_capa','','144col1d')),"")
5 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_5',battery(::ReadingValDoIf($hash,'di_energy_card','battery_power','','144col1d'),::ReadingValDoIf($hash,'di_energy_card','battery_capa','','144col1d')),"")
6 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_6',battery_power(::ReadingValDoIf($hash,'di_energy_card','battery_power')),"")
7 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_7',home (::ReadingValDoIf($hash,'di_energy_card','home_power','','144col1d'),::ReadingValDoIf($hash,'di_energy_card','home_energy')),"")
8 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_8',home_power(::ReadingValDoIf($hash,'di_energy_card','home_power')),"")
9 package ui_Table;::DOIF_Widget($hash,$reg,'di_energy_card_uiTable_c_0_0_0_9',self(::ReadingValDoIf($hash,'di_energy_card','autarchy'),::ReadingValDoIf($hash,'di_energy_card','scr')),"")
Es ist also eine recht komplexe Geschichte, die viele interne Mechanismen des DOIFs nutzt und über vier ineinander liegende for-Schleifen abgearbeitet wird. Es macht aus meiner Sicht keinen Sinn den internen Aufbau nach außen zu publizieren. Dann ist es besser die einzelnen uiTable SVG-Funktionen aufrufen, die jede für sich den passenden HTML-SVG-Code erzeugt, den man überall zur Ausgabe bringen kann, wo HTML-Code in FHEM vorgesehen ist z. B. im Attribut devStateIcon oder diesen selbst wie auch immer verarbeiten möchte.
Ich habe da doch was gebastelt.
Die Funktion ui_Table::get_cell(<Tabelle>,<DOIF-Devicename>,Zeile,Spalte) liefert den HTML-Inhalt einer Tabellenzelle eines DOIF-Devices. Unter Tabelle kann man uiTable oder uiState angeben, je nachdem welches Attribut verwendet wurde, der Rest sollte selbsterklärend sein.
Beispiel:
defmod di_get_cell DOIF ##
attr di_get_cell uiTable {package ui_Table}\
get_cell("diAbfall","uiTable",0,0)\
get_cell("diAbfall","uiTable",0,1)\
get_cell("diAbfall","uiTable",0,2)\
get_cell("diAbfall","uiTable",0,3)\
get_cell("diAbfall","uiTable",0,4)
Nebeneinander (mit Punkt aneinander gehängt) gibt es allerdings einen Versatz, weil die Tabelle als solche fehlt, wo die Elemente in den Zellen sauber voneinander getrennt waren. Die angepasste DOIF-Version ist im Anhang. Kannst du gerne ausprobieren.
Funktioniert auch im Dummy:
defmod cell_dummy dummy
attr cell_dummy devStateIcon {ui_Table::get_cell("diAbfall","uiTable",0,0)}
Danke Damian.
{ ui_Table::get_cell("dbAbfall","uiTable",0,0) } liefert HTML-Kode.
Dummerweise akzeptiert Telegram auch kein div. Damit scheidet selbst icon_label() aus.
:-(
Zitat von: Dr. Boris Neubert am 11 Mai 2026, 20:23:17Danke Damian.
{ ui_Table::get_cell("dbAbfall","uiTable",0,0) } liefert HTML-Kode.
Dummerweise akzeptiert Telegram auch kein div. Damit scheidet selbst icon_label() aus.
:-(
ja, dann bleibt nur der Aufruf der DOIF-SVG-Funktionen selbst. Diese haben nur das <svg>-tag. Hier nützt das aber nicht viel.
Zitat von: Dr. Boris Neubert am 10 Mai 2026, 17:53:44Die Alternative wäre dann ein Bild mit dem RSS-Modul zu bauen (die Tonnen sind ja SVG-Grafiken) und mit Telegram zu versenden.
Setzt ein DOIF-Device namens
dbAbfall (dashboard-Abfall) wie aus dem Wiki (https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Anzahl_der_Tage_bis_zur_Abfall-Entsorgung) voraus.
Definition:
defmod infofeed1 RSS jpg fhem.example.com /opt/fhem/conf/infofeed1.layout
attr infofeed1 room Gewerke->Anzeige,Systeme->RSS
attr infofeed1 size 240x240Layout:
font /opt/fhem/conf/DejaVuSans-Bold.ttf
tvalign "center"
ivalign "center"
rgb 'cccccc'
pt 12
img 5 35 h60 svg data { FW_makeImage("Abfalltonne-Recycling-Logo\@blue") }
text 70 35 { ReadingsVal("dbAbfall", "altpapier", "") }
text 120 35 { ReadingsVal("dbAbfall", "altpapier_date", "") }
img 5 105 h60 svg data { FW_makeImage("Abfalltonne\@gray") }
text 70 105 { ReadingsVal("dbAbfall", "restmuell", "") }
text 120 105 { ReadingsVal("dbAbfall", "restmuell_date", "") }
img 5 175 h60 svg data { FW_makeImage("Abfalltonne-Recycling-Logo\@yellow") }
text 70 175 { ReadingsVal("dbAbfall", "gelbe_tonne", "") }
text 120 175 { ReadingsVal("dbAbfall", "gelbe_tonne_date", "") }
date 10 230
time 120 230Kommando:
set telegram cmdSend { RSS_returnIMG("infofeed1", "jpg") }Ergebnis:
siehe Anhang