Moinsen, ich komme ja aus der embedded-Ecke, probiere mich aber trotzdem gerne mal an anderen Themen. Folgende Situation habe ich grad: Ich habe ein Python-Skript verbrochen welches sich aus verschiedenen Quellen diverse Daten abholt und diese sammelt. Das Skript läuft dabei dauerhaft als daemon. Nun möchte ich per Flask dem Skript ein Webinterface anflanschen, bzw. das läuft bereits. Mein Skript ist in der Lage, eine html-Seite auszuliefern. In diesem Webinterface sollen die angesammelten Daten visualisiert werden. Zu Beginn würde ich das erstmal in eine simple html-Tabelle packen. Nun stellt sich mir aber die Frage wie ich die Webseite regelmäßig aktualisiere. Nicht nur dass sich die Daten im Laufe der Zeit ändern, es können auch Einträge dazu kommen (sprich: die Tabelle kriegt mehr Zeilen und Spalten). Ich könnte jetzt den html-Code der Seite bereits serverseitig, also im Pythonskript, mit den Daten befüllen. Der Browser würde dann nur eine simple, statische Seite geliefert bekommen. Methode 2 wäre, ein paar Javaskripte in die Seite einzubetten. Per REST-Api könnte die Seite dann die dynamischen Inhalte nachladen (als JSON-Struktur) und dann per jquery die Seite laufend aktualisieren. Methode 1 wäre simpler, hat aber den Nachteil dass der Server nicht nur Daten ausliefert sondern sich auch um so Details wie die graphische Aufbereitung derselbigen kümmern muss. Methode 2 ist etwas aufwendiger, dafür sind Datenschnittstelle und die Anzeige der Daten sauber getrennt. Es wären sogar verschiedene Visualisierungen denkbar. Ich brauch ein paar Denkanstöße. Wie würdet ihr das lösen?
Die Lösung heißt WebSocket, kannst du in deinem Flask auch einbauen. Wenn ein Client deine Seite aufruft, wird zusätzlich eine WS Verbindung aufgebaut. Immer wenn du neue Daten Hast, kannst du diese als Broadcast an deine Clients sicken und dann auf Clientseite mit JavaScript auswerten.
M. M. schrieb: > Nun stellt sich mir aber die Frage wie ich die Webseite regelmäßig > aktualisiere. Eine gängige Methode ist AJAX. Du kannst allen dynamischen Elementen eine eindeutige ID geben. Ein Javascript ruft dann zyklisch Updates vom Server ab. In jedem Update benennt der Server die des zu ändernden Elementes, sowie dessen Inhalt. Tipp: Du kannst das Javascript so schreiben, dass es den Server in einer Endlosschleife abfragt. Der Server muss nicht unbedingt sofort antworten, sondern kann den Browser ruhig warten lassen, bis wirklich neue Daten vorliegen. Das reduziert die CPU Auslastung und Stromaufnahme beim Browser. Ob deine Updates im HTML Format sind (also server-seitig aufbereitet) oder im JSON Format (also browser-seitig aufbereitet) ist dann hauptsächlich eine Geschmacksfrage. Kommt drauf an, auf welcher Seite du lieber den dazu nötigen Strom verbrauchen willst.
:
Bearbeitet durch User
Weist du denn welchen Browser der Client benutzt und ob JS nicht evtl. deaktviert ist? Statisches HTML ist immer der kleinste gemeinsame Nenner.
M. M. schrieb: > Wie würdet ihr das lösen? Ja, es gibt viele Wege. Eine einfache HTML Seite (mit Auto-Refresh) kann nicht nur jeder Browser anzeigen, man kann sie auch einfach (z.B. per Python) auf Empfängerseite auseinandernehmen und ihren Inhalt analysieren. Man könnte sie auch in PDF verwandeln und auf eBookReadern anzeigen. Den Zugriff verbaust du dir mit komplexen Skriptingseiten. Eine einfache Skripting-Seite holt sich den Rahmen, der erhalten bleibt, und updated durch ihren Skrip nur die enthaltene Tabelle. Der Skript braucht nur die Daten zu übertragen, und hält die Füsse still wenn sich nichts verändert hat damit es nicht flackert.
Wer in seinem Browser Javascript deaktiviert, ist selber Schuld bzw. kann das selber umstellen. Ich denke, man muss für diese Leute keine Sonderlocke mehr vorsehen, das ist nicht mehr zeitgemäß. Hier ein altes Beispiel, mit dem ich die "Navigationsleiste" auf meiner Hompepage nachlade:
1 | <html>
|
2 | <body>
|
3 | <div id="navi"></div> |
4 | |
5 | <script type="text/javascript"> |
6 | ajax_load("navi", "navigation.html"); |
7 | </script>
|
8 | |
9 | Hier kommt der eigentliche statische Inhalt der Seite |
10 | |
11 | </body>
|
12 | </html>
|
1 | function ajax_load(id,url) { |
2 | try { |
3 | var request = new XMLHttpRequest(); |
4 | request.open("GET", url, true); |
5 | |
6 | request.onreadystatechange = function () { |
7 | if (request.readyState == 4) { |
8 | document.getElementById(id).innerHTML = request.responseText; |
9 | }
|
10 | };
|
11 | |
12 | request.send(); |
13 | }
|
14 | catch (e) { |
15 | console.error(e, e.stack); |
16 | }
|
17 | }
|
Dieses Beispiel kommt ohne Endlosschleife aus, weil die Navigation nur einmal geladen werden muss. Aber ich denke, du kannst trotzdem davon abgucken. Ich wollte damit nur zeigen, dass AJAX ganz einfach ist.
:
Bearbeitet durch User
Steve van de Grens schrieb: > Eine gängige Methode ist AJAX. "AJAX" ist ein Buzzword aus den 1990ern und 2000ern. Auch wenn das Grundkonzept in etwa gleichgeblieben ist, sollte man das heute nicht mehr so nennen. Dazu ist die Abkürzung zu stark mit den damals üblichen&nötigen Flash-Player-Active-X-XMLHttpRequest-würgarounds verknüpft. Wenn man nach "AJAX" sucht, wird man von veraltetem JS-Code erschlagen, üblicherweise mit XMLHttpRequest & Callback-Hölle, obwohl heute die Browser alle "echtes" asynchrones Javascript (async/await) unterstützen würden... Steve van de Grens schrieb: > Der Server muss nicht unbedingt sofort > antworten, sondern kann den Browser ruhig warten lassen, bis wirklich > neue Daten vorliegen. das sogenannte "longpolling" ist ähnlich alt, inzwischen als ServerSentEvents aber formalisiert und mit einfacher API im Browser zu handhaben. https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events Oder gleich Websockets... Ja, die ganzen Webtechniken aus den 1990ern funktionieren auch heute noch. Aber wenn jemand was Neues entwickeln will, kann er auch aktuelle Techniken einsetzen. Muss ja nicht gleich eine React-Webapp werden.
Steve van de Grens schrieb: > Ich wollte damit nur zeigen, dass AJAX ganz einfach ist. Steve van de Grens schrieb: > function ajax_load(id,url) { Achtung: Dein try-catch ist unvollständig. Exceptions, die aus dem onreadystatechange-Handler geworfen werden, fängt das catch nicht. um dein Beispiel zu aktualisieren:
1 | async function aj_load(id,url) { |
2 | try { |
3 | document.getElementById(id).innerHTML = await (await fetch(url)).text(); |
4 | } catch (e) {...} |
5 | }
|
Zunächst AJAX und jQuery sind out 🫣 Ob dir der Server statische HTML seiten generiert oder du die Daten mittels JavaScript nachlädst, ist erstmal egal. Meine Kriterien wären UX, DX und SEO. UX - User experience Werden die Daten via JavaScript geladen ist das navigieren, sortieren oder filtern meist flüssiger als bei auf dem server generierten seiten. DX - Developer experience Was entspricht ehr deinen Fähigkeiten? Eine brauchbare Lösung gut umgesetzt ist meist besser, als die beste Lösung stümperhaft programmiert. SEO - Search engine optimization Wenn der Inhalt von Suchmaschinen leicht indiziert werden soll, sind statische bzw servergenerierte Seiten besser, da der Bot kein JS ausführen muss um an den Inhalt zu kommen. Die eierlegenden Wollmilchsau: Der Server liefert bei der ersten Anfrage statischen Inhalt und aktualisiert diesen bei Bedarf dynamisch. Eine Bibliothek, die das recht simple umsetzt ist: HTMX Dann muss die REST API aber HTML liefern und kein JSON.
M. M. schrieb: > Folgende Situation habe ich grad: > Ich habe ein Python-Skript verbrochen welches sich aus verschiedenen > Quellen diverse Daten abholt und diese sammelt. Das Skript läuft dabei > dauerhaft als daemon. > > Nun möchte ich per Flask dem Skript ein Webinterface anflanschen, bzw. > das läuft bereits. Mein Skript ist in der Lage, eine html-Seite > auszuliefern. In diesem Webinterface sollen die angesammelten Daten > visualisiert werden. Zu Beginn würde ich das erstmal in eine simple > html-Tabelle packen. Das würde ich persönlich nicht machen, sondern die beiden Komponenten je das tun lassen, was sie am Besten können: das Datensammelskript kümmert sich um Deine Daten, das WSGI-Skript (Flask) kümmert sich darum, die Daten fürs Web aufzubereiten. Die beiden Komponenten können dann entweder direkt miteinander kommunizieren, oder -- je nachdem -- kann es auch sinnvoller sein, noch eine Infrastrukturkomponente dazwischen zu platzieren. Zunächst einmal ist die Frage, was Du mit Deinen Daten nach deren Sammlung zuerst machen möchtest. Sollen Deine Daten verarbeitet, also zum Beispiel umgerechnet oder aggregiert werden? Sollen die Daten in irgendeiner Weise persistiert, also gespeichert werden, und wenn ja: wie? Für sinnvolle Ratschläge wäre es sicherlich sinnvoll, wenn Du etwas zu den Daten sagen könntest, vor allem zu Umfang, Quellen und Struktur, dann etwas dazu sagen könntest, ob und wie sie verarbeitet und ob, wie und wie lange sie gespeichert werden sollen, und wie Du sie am Ende darstellen möchtest, also beispielsweise in Balken- oder Liniendiagrammen, nur in Tabellen, oder... richitg, da gibt es drölfzig Möglichkeiten, statische, interaktive, und so weiter, und so fort. Diese Aspekte erscheinen mir nach der Lektüre Deines Eröffnungsbeitrages noch zu diffus, um etwas Kluges dazu zu sagen.
Alex Z. schrieb: > Die Lösung heißt WebSocket, kannst du in deinem Flask auch einbauen. Ja, also, äh... ja, das kann man machen. Aber dann würde ich eher über das Modul Flask-SocketIO von Miguel Grinberg (ja, der mit den Flask-Tutorials) nachdenken, das auf Websockets aufbaut, aber viele nützliche zusätzliche Features der JavaScript-Bibliothek SocketIO nutzbar macht.
Am einfachsten ist es nur die zu erneuernden Daten als Varieablendeklaration (vorzugsweise als Arrays) in eine JS-Datei zu schreiben. Das ist sehr viel kompakter als Daten in HTML-Form. Im Init-Skript wird ein Timer installiert, der in Abständen die Daten neu anfordert und einige Sekunden danach die Darstellung aktualisiert. Das Anfordern der Daten geschieht durch die Neuerstellung eines <Script>-Elements. Ein schon bestehendes Elelement mit gleicher ID wird vorher entfernt.
1 | //--------------------------------------
|
2 | function NewData(){ |
3 | var script; |
4 | var el; |
5 | |
6 | var old=document.getElementById("newdata"); |
7 | if(old!=null){ |
8 | document.getElementsByTagName('head')[0].removeChild(old); |
9 | // console.log("NewData:script-aufruf entfernt");
|
10 | }
|
11 | |
12 | script = document.createElement("script"); |
13 | |
14 | script.src = "./update.js"; |
15 | script.type = "text/javascript"; |
16 | script.async = "true"; |
17 | script.id = "newdata"; |
18 | |
19 | el=document.getElementsByTagName("head")[0]; |
20 | el.appendChild(script); |
21 | |
22 | //console.log("NewData:script-aufruf"+ script+" erzeugt");
|
23 | }
|
:
Bearbeitet durch User
Jobst Q. schrieb: > Am einfachsten Und dann lieferst du so einen umständlichen und veralteten code? Wo hast du den ausgegraben, stammt wohl noch aus der Zeit vor JSON?
1 | setInterval(async ()=>{ |
2 | data = await (await fetch("update.json")).json(); |
3 | }, 1000); |
:
Bearbeitet durch User
Steve van de Grens schrieb: > Wer in seinem Browser Javascript deaktiviert, ist selber Schuld bzw. Der schont den Akku seines Laptops oder Tabletts und bekommt regelmässig keine Werbung zu sehen. > kann das selber umstellen. Ich denke, man muss für diese Leute keine > Sonderlocke mehr vorsehen, das ist nicht mehr zeitgemäß. Was zeitgemäß ist, bestimmt wohl immer noch der Nutzer. > Hier ein altes Beispiel, mit dem ich die "Navigationsleiste" auf meiner > Hompepage nachlade: Eine von den kaputten Webseiten, die als HTML-Version keine Navigation haben? Der besondere Lacher: Eine Kommerzseite, deren Javascriptnavigation bei einem Zoomfaktor von 150 % einfach vom Bildschirm verschwand, und dann navigationslos daherkam? Was für ein Dreck. Genau wie die "Neue und dynamische" Seite der Fahrplanauskunft der Deutschen Bahn.
Εrnst B. schrieb: > Jobst Q. schrieb: >> Am einfachsten > > Und dann lieferst du so einen umständlichen und veralteten code? > Wo hast du den ausgegraben, stammt wohl noch aus der Zeit vor JSON? > >
1 | > setInterval(async ()=>{ |
2 | > data = await (await fetch("update.json")).json(); |
3 | > }, 1000); |
4 | >
|
Ich habe ihn nicht ausgegraben, sondern aus einfachen Javascript-Funktionen entwickelt. Die Umständlichkeit deines Codes ist nur versteckt, wenn man ihn verstehen will, ist nichts mehr einfach. Nur weil es etwas wie JSON gibt, muss man es nicht verwenden, wenn es ohne besser geht. Es geht um die Einfachheit der Bereitstellung der Daten im Server, was gerade im Embedded-Bereich von Bedeutung ist. Und JS-Variablenzuweisungen sind deutlich einfacher als das JSON-Format. Zum Beispiel:
1 | var AnaV=[19464,6400,18680,22708,16224,124,18888,21956,6584,17904,25104, |
2 | 8,23412,3700,5800,2972,18000,31000,30600,49600,30000,30600,832,12788,13436, |
3 | 13177,13431,3081,4072,0,6600,0,10800,0,0,16318,0,20100,18136,0,0,0,9590, |
4 | 9547,900,41848,4444,2036,4320,0,]; |
5 | var DigV=[1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1, |
6 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0, |
7 | 0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
8 | 0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,]; |
9 | var UnixTime=1707078289; |
Es mag Anwendungen geben, wo JSON Vorteile bringt, sehe ich hier aber nicht als gegeben.
Keiner von euch Spezies kennt die genauen Anforderungen an das Datenformat und ihr kloppt euch... Btw, der TO hat sich noch nie zu irgendeiner Antwort geäußert. Selbst wenn er nochmal wieder hier aufschlägt sind solche DetailKriege doch nichts was ihm (derzeit) weiterhilft. Ich beobachte weiter, warte auf den TO und hoffe auf nicht zu viel vorrauseilende Antworten.
Kolja L. schrieb: > Btw, der TO hat sich noch nie zu irgendeiner Antwort geäußert. Selbst > wenn er nochmal wieder hier aufschlägt sind solche DetailKriege doch > nichts was ihm (derzeit) weiterhilft. Genau, der TO ist nämlich etwas irritiert von den Antworten und musste erst abwägen ob es noch zielführend ist diesen Thread fortzusetzen. Vor allem bin ich aber irritiert dass hier Code gepostet, JSON und Javascript in Frage gestellt und Buzzwörter wie UX, DX und SEO eingesträut werden. Die technische Umsetzung krieg ich hin, bzw. habe ich bereits hinbekommen, sowohl Methode 1 (Server liefert bettet Daten in ein template ein und liefert statisches html) als auch Methode 2 (Browser lädt zyklisch Daten per REST/JSON nach und aktualisiert den html-Code). Ich werde Lösung 2 behalten weil sich die Seite dort selber partiell aktualisieren kann (ja, würde mit Websockets auch gehen) und Datensammlung und deren Darstellung im Frontend sauber getrennt sind. Außerdem kann die REST-Api auch anderweitig (Script, Logger) genutzt werden. Die Frage war wirklich nur zu welcher Methode ihr tendiert und wieso, welche Vor- und Nachteile diese noch haben die ich evtl. nicht sehe.
:
Bearbeitet durch User
Beitrag #7596083 wurde vom Autor gelöscht.
M. M. schrieb: > Buzzwörter wie UX, DX und SEO eingesträut werden. Da ich nicht weiß, wissen kann, wer die Seite programmiert und wer sie nutzen soll, hab ich es halt allgemein formuliert 😉 So hatte ich deine Frage auch verstanden. Den Punkt, den du noch genannt hast, habe ich allerdings vergessen. Mit einer API bist du natürlich flexibler was die Ausgabe der Daten angeht. Dann noch viel Erfolg
Im gesamten Thread sehe ich nichts zum Thema Aktualisierungs-Frequenz, was aber m.E. entscheidend für die Wahl der Mittel wäre. Sollen die fremden Daten jedesmal aktualisiert werden, sobald jemand die HTML-Seite aufrufen wird? Sicher nicht, oder? Mein Vorschlag: Der Sammler-Daemon aktualisiert autonm in einer angemessenen Frequenz die Daten in eine Datenbank hinein. Entweder überschreibt er die alten mit den aktuellen Daten oder er legt jedesmal neue Datensätze an. Dann könnte man im Web-Interface eventuell auch die Historie betrachten oder Diagramme daraus machen ... Die Webseite ist ebenfalls autonom und ezeugt bei Aufruf aus der Datenbank heraus jeweils eine (momentan) statische Ansicht. Das könnte man mit Apache/PHP oder node.js machen. WebSocket oder Ajax/Promises usw. sind m.E. nur sinnvoll, wenn die Aktualiserungsfrequenz sehr hoch ist, während man auf der Webseite verweilt. Aber zur Frequenz wurde ja bisher nichts mitgeteilt.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.