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

    5f405fe3-e328-43ec-b34c-c8c886bbe843-grafik.png


  • Developer

    @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, Thorsten

    Ich 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 unter javascript.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


  • Developer

    @Kueppert

    Das Script erzeugt automatisch einen Datenpunkt unterhalb von javascript.0: javascript.0.html-tables.log-Info. Den kannst du auch umbennen z.B. in javascript.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:
    c58263e8-87ad-4ee6-8523-8c4beaa270a3-grafik.png
    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 🙂



  • @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
    

Log in to reply
 

Suggested Topics

1.7k
Online

32.4k
Users

39.0k
Topics

528.7k
Posts