[gelöst] Eventmonitor für HTML erweitern?

Begonnen von Torxgewinde, 13 Oktober 2024, 13:34:19

Vorheriges Thema - Nächstes Thema

Torxgewinde

Hi,
Die Werte von Readings werden direkt in dem Eventmonitor und in FHEMWEB dargestellt, außer man schließt den Wert mit "<html>Inhalt</html>" ein, dann lässt FHEMWEB den Browser den Inhalt des Readings als HTML interpretieren und rendert es in den DOM.

Ich fände es sinnvoll, wenn auch der Eventmonitor das gleiche Verhalten anbietet. Soll heißen, dass ein Eintrag im Eventmonitor:
2024-10-13 13:26:51 MQTT2_DEVICE ArbeitszimmerThermostat2.device historyGraph: <html>...</html>Das eingebettete HTML nicht einfach nur als Text darstellt, sondern den Browser den Inhalt rendern ließe. Es müssten also die einrahmenden Tags entfernt werden und dem Browser der Inhalt als DOM-Fragment zum Rendern übergeben werden.

Da ich mit einigen HTML-Readings arbeite, sind diese im Eventmonitor schnell unübersichtlich. Würden diese als HTML gerendert, wäre es IMHO besser lesbar. Deswegen die Frage bzw. die Anregung, ob man das ändern möchte.

Beste Grüße!

Ellert

Ich möchte Events unverfälscht sehen, damit ich weiß worauf ich zu triggern habe und nicht raten muss.
Ich denke das ist der Sinn des Eventmonitors.

Torxgewinde

Zitat von: Ellert am 13 Oktober 2024, 19:18:20Ich möchte Events unverfälscht sehen, damit ich weiß worauf ich zu triggern habe und nicht raten muss.
Ich denke das ist der Sinn des Eventmonitors.
Ich würde sagen, dass ist AUCH ein Anwendungsfall und wie sovieles bei FHEM nutzt der Eine es so, der Andere so. Falls das Feature hinzugefügt werden würde, dann wäre es vermutlich sinnvoll es aktivieren und deaktivieren zu können. Mein Anwendungsfall im Eventmonitor ist die Dinge in ihrer zeitlichen Abfolge beobachten zu können und da wäre ein schneller Überblick sinnvoll. Es kann aber durchaus sein, dass der Anteil der HTML-Readings bei euch anderen zu gering ist, um den Aufwand einer Implementation zu rechtfertigen ¯\_(ツ)_/¯.

rudolfkoenig

Ich werde ueber eine Implementierung nachdenken (optional aktivierbar), falls zwei weitere Benutzer diesen Wunsch hier melden.

Torxgewinde


rudolfkoenig

Kannst du bitte einen "Copy for forum.fhem.de" Datensatz von einer Beispielinstanz hier anhaengen, damit ich mit etwas Sinnvolles ueben kann?

Torxgewinde

Klar,
Real habe ich gefallen an Balkendiagrammen der letzten 24h gefunden. Damit statte ich gerne Bewegungsmelder und dergleichen aus: https://wiki.fhem.de/wiki/Letzte_Werte_als_Reading_und_Balkendiagramm

Das dies aber vermutlich zu sehr vom eigentlichen Thema ablenkt, habe ich ein Testdevice, basierend auf einem AT gemacht. Das Reading "meinReading" ändert sich alle 10 Sekunden in ein neues HTML Snippet. Als Demo habe ich es auch bei Cooltux hochgeladen: https://demo-fhem.cooltux.net/fhem?detail=HTML_Testdevice&fw_id=

define HTML_Testdevice at +*00:00:10 { \
# Array of colors\
my @colors = qw(red green blue yellow orange purple pink cyan);;\
\
# Randomly pick a color from the array\
my $random_color = $colors[rand @colors];;\
\
# Generate a random number\
my $random_number = int(rand(1000));;\
\
# Get the current timestamp\
my $timestamp = strftime('%Y-%m-%d %H:%M:%S', localtime);;\
\
# Create the HTML snippet\
my $html_snippet = <<"HTML";;\
<div style="color: $random_color;;">\
  Random Number: $random_number<br>\
  Timestamp: $timestamp\
</div>\
HTML\
\
$html_snippet =~ s/\n//g;;\
\
readingsSingleUpdate($defs{"HTML_Testdevice"}, "meinReading", "<html>$html_snippet</html>", 1);;\
}
attr HTML_Testdevice room Experimente
#   CFGFN     
#   COMMAND    {
## Array of colors
#my @colors = qw(red green blue yellow orange purple pink cyan);
#
## Randomly pick a color from the array
#my $random_color = $colors[rand @colors];
#
## Generate a random number
#my $random_number = int(rand(1000));
#
## Get the current timestamp
#my $timestamp = strftime('%Y-%m-%d %H:%M:%S', localtime);
#
## Create the HTML snippet
#my $html_snippet = <<"HTML";
#<div style="color: $random_color;">
#  Random Number: $random_number<br>
#  Timestamp: $timestamp
#</div>
#HTML
#
#$html_snippet =~ s/\n//g;
#
#readingsSingleUpdate($defs{"HTML_Testdevice"}, "meinReading", "<html>$html_snippet</html>", 1);
#}
#   DEF        +*00:00:10 {
## Array of colors
#my @colors = qw(red green blue yellow orange purple pink cyan);
#
## Randomly pick a color from the array
#my $random_color = $colors[rand @colors];
#
## Generate a random number
#my $random_number = int(rand(1000));
#
## Get the current timestamp
#my $timestamp = strftime('%Y-%m-%d %H:%M:%S', localtime);
#
## Create the HTML snippet
#my $html_snippet = <<"HTML";
#<div style="color: $random_color;">
#  Random Number: $random_number<br>
#  Timestamp: $timestamp
#</div>
#HTML
#
#$html_snippet =~ s/\n//g;
#
#readingsSingleUpdate($defs{"HTML_Testdevice"}, "meinReading", "<html>$html_snippet</html>", 1);
#}
#   FUUID      67101949-f33f-ee6b-00c0-20a7e4111a15c26d
#   NAME       HTML_Testdevice
#   NR         1116
#   NTM        22:06:26
#   PERIODIC   yes
#   RELATIVE   yes
#   REP        -1
#   STATE      Next: 22:06:26
#   TIMESPEC   00:00:10
#   TRIGGERTIME 1729109186.13006
#   TRIGGERTIME_FMT 2024-10-16 22:06:26
#   TYPE       at
#   eventCount 63
#   READINGS:
#     2024-10-16 22:06:16   meinReading     <html><div style="color: blue;">  Random Number: 888<br>  Timestamp: 2024-10-16 22:06:16</div></html>
#     2024-10-16 22:06:16   state           Next: 22:06:26
#
setstate HTML_Testdevice Next: 22:06:26
setstate HTML_Testdevice 2024-10-16 22:06:16 meinReading <html><div style="color: blue;;">  Random Number: 888<br>  Timestamp: 2024-10-16 22:06:16</div></html>
setstate HTML_Testdevice 2024-10-16 22:06:16 state Next: 22:06:26

So sieht das Reading dann aus, wobei ich ein wenig Zufall mit eingebaut habe:
Du darfst diesen Dateianhang nicht ansehen.

rudolfkoenig

Danke fuer das Beispiel, ist perfekt zum Testen.

Habe was implementiert, siehe Anhang.
Aktivieren ist es mit dem htmlInEventMonitor Attribut:
Zitatif set to 1, text enclosed in <html>...</html> will not be escaped in the event monitor.

Auf die Ausgabe aus dem FHEM-Log (das sind die gruenen Zeilen im Anhang) hat das Attribut keine Auswirkung.

Torxgewinde

#8
Genau sowas hatte ich gemeint, toll! Ich habe FHEM ge-updated und es in der FHEMWEB Instanz auf 1 gesetzt (+ "shutdown restart"), aber HTML readings sind weiterhin nur Text. Muss ich noch etwas anderes machen?

Es wird das, was jetzt noch grün ist, aber dann auch nicht noch extra angezeigt, oder? Das würde nämlich sonst doch noch unübersichtlich bleiben, wie ich an dem Realbeispiel eines "historyGraph" Readings zeigen möchte. HTML kann ja auch mal was länger sein, vielleicht nicht wie in dem Extrembeispiel unten, aber tendenziell schon. zum Beispiel könnte es auch ein SVG in einem HTML-Reading sein, das ebenfalls als Text sehr lang ist.

2024-10-18 08:21:24 ModbusAttr Sun2000 PM_ActivePower_A: -80
2024-10-18 08:21:24 ModbusAttr Sun2000 PM_ActivePower_B: 6
2024-10-18 08:21:24 ModbusAttr Sun2000 PM_ActivePower_C: -306
2024-10-18 08:21:24 MQTT2_DEVICE Bewaesserung.device uptime: 1097624065
2024-10-18 08:21:24 MQTT2_DEVICE Bewaesserung.device uptime_hms: 012 days 16:53:44
2024-10-18 08:21:24 MQTT2_DEVICE Bewaesserung.device last_seen: 1729232484513
2024-10-18 08:21:24 MQTT2_DEVICE Bewaesserung.device RSSI: -81
2024-10-18 08:21:24 DOIF Aussenhelligkeit2 PV: 11.0
2024-10-18 08:21:24 DOIF Aussenhelligkeit2 HellDunkel: 0
2024-10-18 08:21:24 DOIF Aussenhelligkeit2 historyGraph: <html><div class="historyGrid" style="border: 1px solid white;border-radius: 5px; display: grid;color: white; text-align: center; align-items: center;width: 500px; grid-template-columns:2463fr 31062fr 52875fr ;" data-startTime=1729146084.63337 data-interval=86400><div style="background: #00bcd4; border-right: white 0px solid; height: 100%; overflow: hidden; white-space: nowrap; text-overflow: clip; min-width: 1px;" class="zoom" data-timestamp=1729095567 title="2024-10-16 18:19:27: Dunkel 🌘">Dunkel 🌘<br>(2024-10-16 18:19:27)</div><div style="background: #9c27b0; border-right: white 0px solid; height: 100%; overflow: hidden; white-space: nowrap; text-overflow: clip; min-width: 1px;" class="zoom" data-timestamp=1729148548 title="2024-10-17 09:02:28: Hell 🔅">Hell 🔅<br>(2024-10-17 09:02:28)</div><div style="background: #00bcd4; border-right: white 0px solid; height: 100%; overflow: hidden; white-space: nowrap; text-overflow: clip; min-width: 1px;" class="zoom" data-timestamp=1729179610 title="2024-10-17 17:40:10: Dunkel 🌘">Dunkel 🌘<br>(2024-10-17 17:40:10)</div></div>    <script>        var styleContent = `                .zoom {                    transition: min-width .5s ease-in, color .5s ease-in !important;                }                .zoom:hover {                    min-width: max-content !important;                    color: white !important;                }                .zoom:hover + div {                    min-width: 16px !important;                }                .historyGrid:hover > :not(.zoom:hover, .zoom:hover ~ .zoom) {                    min-width: 2px !important;                }          `;                /* add or update our CSS to the head */        var styleElement = document.getElementById("historyGridCSS");        if (!styleElement) {            styleElement = document.createElement('style');            styleElement.id = "historyGridCSS";            document.head.appendChild(styleElement);        }        styleElement.textContent = styleContent;            /* just keep one timer for our purposes */        if (window.historyGridIntervalTimer) {            clearInterval(window.historyGridIntervalTimer);        }        /* this function adjusts the div sizes based on time */        var updateValue = function() {            /* there might be several copies of this element, work with classes */            var historyGridItems = document.getElementsByClassName('historyGrid');            var currentTimestamp = Date.now() / 1000;            /* work on each individual historyGrid */            for (var i = 0; i < historyGridItems.length; i++) {                var historyGrid = historyGridItems[i];                var columns = historyGrid.style.gridTemplateColumns.split(' ');                /* 1 fr equals 1 second here, adjust the most recent item */                var timestampLastItem = historyGrid.lastChild.dataset.timestamp;                columns[columns.length - 1] = (currentTimestamp - timestampLastItem) + 'fr';                /* adjust the other item sizes if not whole history is to be shown */                if (historyGrid.dataset.interval != "NaN") {                    var start_at = currentTimestamp - parseInt(historyGrid.dataset.interval);                    /* adjust the first and next child-div, the last has been adjusted above */                    for (var j = 0; j < columns.length-1; j++) {                        var thisEntry = historyGrid.children[j];                        var nextEntry = historyGrid.children[j+1];                        var thisTimestamp = Math.max(0, thisEntry.dataset.timestamp-start_at);                        var nextTimestamp = Math.max(0, nextEntry.dataset.timestamp-start_at);                        /* 0fr is OK for outdated items, item is still in the DOM, but 0-sized */                        columns[j] = Math.max(0, nextTimestamp-thisTimestamp) + 'fr';                                                /* if 0fr then unset min-width inline style of the div */                        if (columns[j] === '0fr') {                            thisEntry.style.minWidth = '';                        }                    }                }                                /* put together the grid-size-info again and apply */                historyGrid.style.gridTemplateColumns = columns.join(' ');            }            /* if the text does not fit, hide the text without deleting it */            var divElements = document.querySelectorAll('.historyGrid > div');            divElements.forEach(function(element) {                if (element.scrollWidth > element.clientWidth) {                    element.style.color = 'transparent';                } else {                    element.style.color = '';                }            });            /* the most recent log entry (the last) is too small to be seen,               so, make it larger and maintain aspect ratio of 1:1             */            var elements = document.querySelectorAll('.historyGrid > div:last-child');            elements.forEach(function(element) {              element.style.minWidth = element.offsetHeight + 'px';              if (element.offsetWidth > parseInt(element.style.minWidth) + 2) {                element.style.borderLeft = '0px solid white';              } else {                element.style.borderLeft = '2px dashed white';              }            });        };        /* immiditaly update sizes right now and set intervalTimer */        updateValue();        window.historyGridIntervalTimer = setInterval(updateValue, 1000);    </script></html>
2024-10-18 08:21:24 ModbusAttr Sun2000 System_time: 2024-10-18 09:21:19
2024-10-18 08:21:24 ModbusAttr Sun2000 Leistung_Stromnetz_Mittelwert: 963.0
2024-10-18 08:21:24 ModbusAttr Sun2000 Leistung_Wechselrichter_Mittelwert: 11.0
2024-10-18 08:21:24 ModbusAttr Sun2000 Leistung_Paneele_Mittelwert: 11.0

rudolfkoenig

Eine Laengenbegrenzung ist mir nicht bekannt.
Ich habe deine lange Zeile per setreading gesezt, das schaut bei mir im Eventmonitor wie im Anhang aus.

Torxgewinde

#10
Ok, kann ich auf Cooltux Webserver auch nachvollziehen, dort klappt es auch. Dann muss ich mal in meiner Instanz gucken was bei mir hakt.

Hier aber schonmal ein dickes Dankeschön für dieses neue Feature!

Edit #1:
Jetzt klappt es auch hier, ich hatte noch was entweder in meinem Browser-Cache und/oder in meinem Reverse-Proxy-Cache. Nachdem ich die nun geleert hatte, kann ich die HTML-readings im Eventlog sehen, perfekt!!!

Hier ein Screenshot mit einem Mix aus SVG, GIFs und dergleichen in den HTML-Readings:
Du darfst diesen Dateianhang nicht ansehen.