NEWS
[gelöst]JSON zu HTML und in Datei schreiben/ablegen
-
Hallo in die wissende Runde,
ich habe den LogParser installiert und lese damit mein Log aus. Ausgabe erfolgt in ein JSON(_Objekt).
Jetzt möchte ich aber diese Ausgabe in iQontrol darstellen. Da geht kein JSON. Also möchte ich das JSON via SKript in ein HTML umwandeln und diese HTML irgendwo (Pfadangabe im Skript) ablegen.
Ich hab hier im Forum schon gesucht (und im WWW), aber vermutlich auf Grundlage meines Unwissens was JS betrifft, nix gefunden.
Könnte mir hier jmd weiterhelfen? Denkanstöße geben?
Der Screen ist aus VIS (json Table), aber da konnte ich keinen Code ablesen um den ggf. zu verwenden für mich und mich damit anzulernen.PS: wenn sowas auch per Blockly ginge, wäre das Hammer. Damit kann ich umgehen...aber ne Idee, wie das Projekt umzusetzen sein soll mit den Blöcken...keine Ahnung
Danke euch und vG, Thorsten
-
@Kueppert
Hi,du hattest ja auch im LogParser-Adapter-Thread nachgefragt, weil sich keiner hier keiner meldete.
@Kueppert sagte in Test: Adapter Log Parser v0.x.x GitHub:
Hallo in die Runde,
ich hoffe, die Frage von mir passt hier her Die Ausgabe des Log erfolgt ja in einem JSON-Objekt. Nun bin ich in der JS-Sprache leider nicht bewandert und habe so meine Schwierigkeiten, dieses JSON in eine HTML-Tabellenform zu bekommen. Wäre das etwas, das ggf. im Adapter implementiert werden kann? Oder muss ich hierfür darauf hoffen, dass jmd. ggf. ein kleines Skript dafür bereit stellt?
Ich hab bei JavaSkript schon gefragt, ob jmd so ein Skript hat - bisher leider keine Rückmeldung. Hab auch im Forum gesucht ohne Erfolg - und versucht, selbst was zu bauen über Anleitungen im Netz - leider auch ohne Erfolg. Ist dann wie französisch Sprechen ohne die Vokabeln zu kennen ^^
Danke euch und viele Grüße, ThorstenIch kann deine Anfrage absolut nachvollziehen, und ohne genau zu wissen, wonach man sucht im www, ist man verloren. In deinem Fall findet man schnell Website-basiertes JavaScript, aber das muss dann umgewandelt werden in node.js / ioBroker.
Ich bin ja der Meinung (schon mehrfach hier kund getan ), alle entsprechenden Datenpunkte sollten nur JSON liefern und kein HTML, weil die Zielapplikation (z.B. VIS) sich um die Formatierung kümmern sollte, und das nicht der Job eines Adapters ist
Daher empfehle ich auch, dass du diesbezüglich für den iControl-Adapter ein Issue auf Github aufmachst, damit zukünftig JSON unterstützt wird. HTML ist einfach zu speziell.
Lösung
Hier ein Script, das den Datenpunkt
logparser.0.filters.Info.json
überwacht, und das Ergebnis als HTML unterjavascript.0.html-tables.log-Info
ausgibt.Kann im Prinzip für jeden JSON-Datenpunkt verwendet werden...
/****************************************************************************************************** * JSON-Datenpunkt in HTML umwandeln * -------------------------------------------------------------- * Zweck: Überwacht einen JSON-Datenpunkt und sobald geändert, wird JSON in HTML umgewandelt und * in einem eigenen Datenpunkt ausgegeben * Publiziert: https://forum.iobroker.net/topic/32540/json-zu-html-und-in-datei-schreiben-ablegen * Autor: Mic-M (Github) | Mic (ioBroker) * -------------------------------------------------------------------------------------- * Change Log: * 0.0.1 Mic-M * Initial release ******************************************************************************************************/ /********************************************************************************************* * Einstellungen *********************************************************************************************/ // JSON-Datenpunkt const g_jsonState = 'logparser.0.filters.Info.json'; // Neuer Datenpunkt für HTML-Ausgabe const g_htmlState = 'javascript.0.html-tables.log-Info'; // Spalte entfernen (für Log Parser Adapter 'ts' nehmen, da dieser autmatisch den timestamp hinzufügt), // sonst leer lassen const g_removeColumn = 'ts'; /********************************************************************************************* * Ab hier nichts mehr ändern *********************************************************************************************/ main(); function main() { // Create state for HTML, if not yet existing createState(g_htmlState, {'name':'HTML Table', 'type':'string', 'read':true, 'write':false, 'role':'html', 'def':'' }, () => { // State created, so let's subscribe to the given JSON state on({id: g_jsonState, change:'ne'}, function(obj) { // JSON state changed if(obj.state.val && obj.state.val.length > 10) { // state is not empty const jsonObject = JSON.parse(obj.state.val); if(g_removeColumn) { for (let lpEntry of jsonObject) { delete lpEntry[g_removeColumn]; } } setState(g_htmlState, json2table(jsonObject, '')); } }); }); } /** * Convert JSON to HTML table * Source: https://travishorn.com/building-json2table-turn-json-into-an-html-table-a57cf642b84a * * @param {object} jsonObject The JSON as object. * @param {string} [classes] Optional: You can apply one or multiple classes (space separated) to <table>. * @return {string} The HTML result as string */ function json2table(jsonObject, classes = '') { const cols = Object.keys(jsonObject[0]); let headerRow = ''; let bodyRows = ''; classes = classes || ''; cols.map(function(col) { headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>'; }); jsonObject.map(function(row) { bodyRows += '<tr>'; cols.map(function(colName) { bodyRows += '<td>' + row[colName] + '</td>'; }) bodyRows += '</tr>'; }); const addClasses = (classes && classes.length > 1) ? ' class="' + classes + '"' : ''; return '<table' + addClasses + '><thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>'; function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } }
-
@Mic Suuuuper, vielen Dank. Das sieht viel einfacher aus als die Sachen, die ich gefunden habe im Netz Und ich denke, dieser Thread wird dem einen oder anderen sehr helfen.
Vielen Dank, Thorsten -
@Mic sorr, gerade das Skript getestet. Leider erhalte ich einige Fehlermeldungen im LOG. Ich habe manuell einen Datenpunkt für die Ausgabe erzeugt und den Input-JSON-Datzenpunkt an meine Struktur angepasst. Kannst du ggf. erkennen, was ich ggf. falsch gemacht habe?
javascript.0 2020-04-29 09:12:28.292 error (5683) at processTicksAndRejections (internal/process/task_queues.js:97:5) javascript.0 2020-04-29 09:12:28.292 error (5683) at runMicrotasks (<anonymous>) javascript.0 2020-04-29 09:12:28.292 error (5683) at /opt/iobroker/node_modules/standard-as-callback/built/index.js:19:49 javascript.0 2020-04-29 09:12:28.292 error (5683) at tryCatcher (/opt/iobroker/node_modules/standard-as-callback/built/utils.js:11:23) javascript.0 2020-04-29 09:12:28.292 error (5683) at /opt/iobroker/node_modules/iobroker.js-controller/lib/states/statesInRedis.js:616:17 javascript.0 2020-04-29 09:12:28.291 error (5683) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1055:17 javascript.0 2020-04-29 09:12:28.291 error (5683) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1464:17 javascript.0 2020-04-29 09:12:28.291 error (5683) at prepareScript (/opt/iobroker/node_modules/iobroker.javascript/main.js:1411:37) javascript.0 2020-04-29 09:12:28.291 error (5683) at compile (/opt/iobroker/node_modules/iobroker.javascript/main.js:1188:28) javascript.0 2020-04-29 09:12:28.291 error (5683) at Object.createScript (vm.js:249:10) javascript.0 2020-04-29 09:12:28.291 error (5683) at new Script (vm.js:99:7) javascript.0 2020-04-29 09:12:28.291 error (5683) SyntaxError: Unexpected token '**' javascript.0 2020-04-29 09:12:28.291 error (5683) ^^ javascript.0 2020-04-29 09:12:28.291 error (5683) ****************************************************************************************************** javascript.0 2020-04-29 09:12:28.290 error at script.js.common.Sonstiges.LogParser_-_JSON_zu_HTML:1 javascript.0 2020-04-29 09:12:28.290 error (5683) script.js.common.Sonstiges.LogParser_-_JSON_zu_HTML compile failed: javascript.0 2020-04-29 09:12:28.289 info (5683) Start javascript script.js.common.Sonstiges.LogParser_-_JSON_zu_HTML javascript.0 2020-04-29 09:12:28.152 info (5683) Stop script script.js.common.Sonstiges.LogParser_-_JSON_zu_HTML
Danke dir und vG, Thorsten
-
@Mic habs...erste Zeile ein "/" vergessen reinzukopieren ^^ alles gut
-
@Mic sorry, hab jetzt das Skript laufen. Bei einem Update im LogParser wird leider mein manuell erzeugter Datenpunkt nicht befüllt...ist im Skript irgendwo ein Befehl, der das Update des JSON-Datenpunktes vom LogParster hernimmt, um das Java-Skript zu starten?
RAW meines Datenpunktes:
{ "from": "system.adapter.admin.0", "user": "system.user.admin", "ts": 1588144153506, "common": { "name": "HTMLTable", "role": "", "type": "string", "desc": "Manuell erzeugt", "read": true, "write": true, "def": false }, "native": {}, "acl": { "object": 1636, "owner": "system.user.admin", "ownerGroup": "system.group.administrator", "state": 1636 }, "_id": "0_userdata.0.LogParser.HTMLTable", "type": "state" }
Danke dir und vG, Thorsten
-
Das Script erzeugt automatisch einen Datenpunkt unterhalb von javascript.0:
javascript.0.html-tables.log-Info
. Den kannst du auch umbennen z.B. injavascript.0.LogParser.HTMLTable
Siehe diese Zeile im Script:const g_htmlState = 'javascript.0.html-tables.log-Info';
Das obige Script unterstützt derzeit nicht 0_userdata.0.
-
@Mic sooo, habs jetzt glaube ich alles so, wie es für iQontrol sein muss (wurde in dem Thread dort auf ein "kleines Skript bauen" verwiesen).
Da iQontrol ein file haben muss, habe ich jetzt also dein Skript in Nutzung und parallel noch ein Blockly laufen, womit dann ein HTML geschrieben wird (habs nicht gepackt, das in das JS-Skript zu bekommen).
Blockly sieht für alle suchenden wie folgt aus:
und als Export in einer txt anbei. Die Datenpunkte müssen im Blockly manuell angepasst werden.
Blockly_writeHTML.txt
Das angepasste JS-Skript zur Umwandlung von JSON zu HTML sieht wie folgt aus:/****************************************************************************************************** * JSON-Datenpunkt in HTML umwandeln * -------------------------------------------------------------- * Zweck: Überwacht einen JSON-Datenpunkt und sobald geändert, wird JSON in HTML umgewandelt und * in einem eigenen Datenpunkt ausgegeben * Publiziert: https://forum.iobroker.net/topic/32540/json-zu-html-und-in-datei-schreiben-ablegen * Autor: Mic-M (Github) | Mic (ioBroker) * -------------------------------------------------------------------------------------- * Change Log: * 0.0.1 Mic-M * Initial release ******************************************************************************************************/ /********************************************************************************************* * Einstellungen *********************************************************************************************/ // JSON-Datenpunkt const g_jsonState = 'logparser.0.filters.Warn.json'; // Neuer Datenpunkt für HTML-Ausgabe const g_htmlState = 'LogParser.LogParser_Warn_JSONzuHTML'; // Spalte entfernen (für Log Parser Adapter 'ts' nehmen, da dieser autmatisch den timestamp hinzufügt), // sonst leer lassen const g_removeColumn = 'ts'; /********************************************************************************************* * Ab hier nichts mehr ändern *********************************************************************************************/ main(); function main() { // Create state for HTML, if not yet existing createState(g_htmlState, {'name':'HTML Table', 'type':'string', 'read':true, 'write':false, 'role':'html', 'def':'' }, () => { // State created, so let's subscribe to the given JSON state on({id: g_jsonState, change:'ne'}, function(obj) { // JSON state changed if(obj.state.val && obj.state.val.length > 10) { // state is not empty const jsonObject = JSON.parse(obj.state.val); if(g_removeColumn) { for (let lpEntry of jsonObject) { delete lpEntry[g_removeColumn]; } } setState(g_htmlState, json2table(jsonObject, '')); } }); }); } /** * Convert JSON to HTML table * Source: https://travishorn.com/building-json2table-turn-json-into-an-html-table-a57cf642b84a * * @param {object} jsonObject The JSON as object. * @param {string} [classes] Optional: You can apply one or multiple classes (space separated) to <table>. * @return {string} The HTML result as string */ function json2table(jsonObject, classes = '') { const cols = Object.keys(jsonObject[0]); let headerRow = ''; let bodyRows = ''; classes = classes || ''; cols.map(function(col) { headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>'; }); jsonObject.map(function(row) { bodyRows += '<tr>'; cols.map(function(colName) { bodyRows += '<td>' + row[colName] + '</td>'; }) bodyRows += '</tr>'; }); const addClasses = (classes && classes.length > 1) ? ' class="' + classes + '"' : ''; return '<table' + addClasses + '><thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>'; function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } }
Viele Grüße, Thorsten und vielen Dank Mic
-
wollte mich mal hier anhängen ;-),
wurde gerne den JSON vom Tankerkönig umwandeln
Leider wird der DP HTML nicht gefüllt ;-(
/****************************************************************************************************** * JSON-Datenpunkt in HTML umwandeln * -------------------------------------------------------------- * Zweck: Überwacht einen JSON-Datenpunkt und sobald geändert, wird JSON in HTML umgewandelt und * in einem eigenen Datenpunkt ausgegeben * Publiziert: https://forum.iobroker.net/topic/32540/json-zu-html-und-in-datei-schreiben-ablegen * Autor: Mic-M (Github) | Mic (ioBroker) * -------------------------------------------------------------------------------------- * Change Log: * 0.0.1 Mic-M * Initial release ******************************************************************************************************/ /********************************************************************************************* * Einstellungen *********************************************************************************************/ // JSON-Datenpunkt const g_jsonState = 'tankerkoenig.0.json'; // Neuer Datenpunkt für HTML-Ausgabe const g_htmlState = 'javascript.0.html-tables.tankerkoenigHTML'; // Spalte entfernen (für Log Parser Adapter 'ts' nehmen, da dieser autmatisch den timestamp hinzufügt), // sonst leer lassen const g_removeColumn = 'ts'; /********************************************************************************************* * Ab hier nichts mehr ändern *********************************************************************************************/ main(); function main() { // Create state for HTML, if not yet existing createState(g_htmlState, {'name':'HTML Table', 'type':'string', 'read':true, 'write':false, 'role':'html', 'def':'' }, () => { // State created, so let's subscribe to the given JSON state on({id: g_jsonState, change:'ne'}, function(obj) { // JSON state changed if(obj.state.val && obj.state.val.length > 10) { // state is not empty const jsonObject = JSON.parse(obj.state.val); if(g_removeColumn) { for (let lpEntry of jsonObject) { delete lpEntry[g_removeColumn]; } } setState(g_htmlState, json2table(jsonObject, '')); } }); }); } /** * Convert JSON to HTML table * Source: https://travishorn.com/building-json2table-turn-json-into-an-html-table-a57cf642b84a * * @param {object} jsonObject The JSON as object. * @param {string} [classes] Optional: You can apply one or multiple classes (space separated) to <table>. * @return {string} The HTML result as string */ function json2table(jsonObject, classes = '') { const cols = Object.keys(jsonObject[0]); let headerRow = ''; let bodyRows = ''; classes = classes || ''; cols.map(function(col) { headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>'; }); jsonObject.map(function(row) { bodyRows += '<tr>'; cols.map(function(colName) { bodyRows += '<td>' + row[colName] + '</td>'; }) bodyRows += '</tr>'; }); const addClasses = (classes && classes.length > 1) ? ' class="' + classes + '"' : ''; return '<table' + addClasses + '><thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>'; function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } }
jemand eine Idee?
javascript.0 2020-06-07 22:19:48.513 error (30189) at process.topLevelDomainCallback (domain.js:137:15) javascript.0 2020-06-07 22:19:48.512 error (30189) at processImmediate (internal/timers.js:456:21) javascript.0 2020-06-07 22:19:48.512 error (30189) at Immediate._onImmediate (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:5384:37) javascript.0 2020-06-07 22:19:48.511 error (30189) at Object.stateChange (/opt/iobroker/node_modules/iobroker.javascript/main.js:451:25) javascript.0 2020-06-07 22:19:48.510 error (30189) at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1052:38) javascript.0 2020-06-07 22:19:48.509 error (30189) at Object.<anonymous> (script.js.Vis-Scripte.HTML_JSON_Tankerkoenig:42:41) javascript.0 2020-06-07 22:19:48.506 error (30189) Error in callback: TypeError: jsonObject is not iterable
-
seit der Umstellung auf admin 5.1.23 und js aktuell wirft mir dein Skript Fehler ins LOG.
2021-08-23 08:28:06.911 - warn: javascript.0 (17826) Read-only state "javascript.0.LogParser.LogParser_Warn_JSONzuHTML" has been written without ack-flag with value "
Aktuelles Skript von dir:
/****************************************************************************************************** * JSON-Datenpunkt in HTML umwandeln * -------------------------------------------------------------- * Zweck: Überwacht einen JSON-Datenpunkt und sobald geändert, wird JSON in HTML umgewandelt und * in einem eigenen Datenpunkt ausgegeben * Publiziert: https://forum.iobroker.net/topic/32540/json-zu-html-und-in-datei-schreiben-ablegen * Autor: Mic-M (Github) | Mic (ioBroker) * -------------------------------------------------------------------------------------- * Change Log: * 0.0.1 Mic-M * Initial release ******************************************************************************************************/ /********************************************************************************************* * Einstellungen *********************************************************************************************/ // JSON-Datenpunkt const g_jsonState = 'logparser.0.filters.Warn.json'; // Neuer Datenpunkt für HTML-Ausgabe const g_htmlState = 'LogParser.LogParser_Warn_JSONzuHTML'; // Spalte entfernen (für Log Parser Adapter 'ts' nehmen, da dieser autmatisch den timestamp hinzufügt), // sonst leer lassen const g_removeColumn = 'ts'; /********************************************************************************************* * Ab hier nichts mehr ändern *********************************************************************************************/ main(); function main() { // Create state for HTML, if not yet existing createState(g_htmlState, {'name':'HTML Table', 'type':'string', 'read':true, 'write':false, 'role':'html', 'def':'' }, () => { // State created, so let's subscribe to the given JSON state on({id: g_jsonState, change:'ne'}, function(obj) { // JSON state changed if(obj.state.val && obj.state.val.length > 10) { // state is not empty const jsonObject = JSON.parse(obj.state.val); if(g_removeColumn) { for (let lpEntry of jsonObject) { delete lpEntry[g_removeColumn]; } } setState(g_htmlState, json2table(jsonObject, '')); } }); }); } /** * Convert JSON to HTML table * Source: https://travishorn.com/building-json2table-turn-json-into-an-html-table-a57cf642b84a * * @param {object} jsonObject The JSON as object. * @param {string} [classes] Optional: You can apply one or multiple classes (space separated) to <table>. * @return {string} The HTML result as string */ function json2table(jsonObject, classes = '') { const cols = Object.keys(jsonObject[0]); let headerRow = ''; let bodyRows = ''; classes = classes || ''; cols.map(function(col) { headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>'; }); jsonObject.map(function(row) { bodyRows += '<tr>'; cols.map(function(colName) { bodyRows += '<td>' + row[colName] + '</td>'; }) bodyRows += '</tr>'; }); const addClasses = (classes && classes.length > 1) ? ' class="' + classes + '"' : ''; return '<table' + addClasses + '><thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>'; function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } }
@Mic Könntest du dir das vielleicht mal anschauen? Was müsste ich im Skript ändern?
Lieben Gruß und vielen Dank