Pausing the Debug window

Why not display in your own browser window
Here is a subflow you can attach any where like a debug, it will send the msg to the browser.

You can pause the incoming by clicking Pause in title, you can also copy values and delete them individually, to clear all refresh the browser.
Open web page at http://ip_to_node-red:1880/debug

[{"id":"3decb5f518882686","type":"subflow","name":"live debug","info":"","category":"","in":[{"x":240,"y":160,"wires":[{"id":"45dbf990.ba2408"}]}],"out":[{"x":560,"y":160,"wires":[{"id":"45dbf990.ba2408","port":1}]}],"env":[{"name":"debug_name","type":"str","value":"Debug","ui":{"label":{"en-US":"Name"},"type":"input","opts":{"types":["str"]}}},{"name":"debug_property","type":"str","value":"msg","ui":{"label":{"en-US":"Property Path"},"type":"input","opts":{"types":["str"]}}},{"name":"pass_debug_property","type":"bool","value":"false","ui":{"label":{"en-US":"Pass Property Path"},"type":"input","opts":{"types":["bool"]}}}],"meta":{},"color":"#DDAA99"},{"id":"45dbf990.ba2408","type":"function","z":"3decb5f518882686","name":"format time nicely","func":"let msg1 = {payload: RED.util.cloneMessage(msg)};\nmsg1.payload.debug_property = msg.debug_property || env.get(\"debug_property\") || \"msg\"\ntry {\n  msg1.payload.debug_property_array = RED.util.normalisePropertyExpression(msg1.payload.debug_property)\n}\ncatch(error){\n  msg.payload = error;\n  msg1.payload.error = error;\n}\nmsg1.payload.debug_name = env.get(\"debug_name\") || msg._msgid || \"name error\"\nmsg1.payload.pass_debug_property = env.get(\"pass_debug_property\") || false\nreturn [msg1,msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":120,"wires":[["50da04b3.af25fc"],[]]},{"id":"50da04b3.af25fc","type":"websocket out","z":"3decb5f518882686","name":"","server":"985ecbc7.67a138","client":"","x":680,"y":120,"wires":[]},{"id":"1787be40.e87842","type":"http in","z":"3decb5f518882686","name":"","url":"/debug","method":"get","upload":false,"swaggerDoc":"","x":330,"y":40,"wires":[["1857548e.e7a8ab"]]},{"id":"1857548e.e7a8ab","type":"template","z":"3decb5f518882686","name":"Simple Web Page","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n    <head>\n        <style>\n            span.debug_name {\n                color: black;\n            }\n            span.debug_error{\n                color: red;\n            }\n            span.debug_date{\n                color:blue;\n            }\n            pre[id^='json_data_']{\n                font-size:20px;\n                background-color: ghostwhite;\n                border: 1px solid silver;\n                padding: 10px 20px;\n                margin: 20px; \n            }\n            .json-key {\n                color: olive;\n            }\n            .json-value {\n                color: navy;\n            }\n            .json-string {\n                color: brown;\n            }\n\n        </style>\n    <title>Debug Messages</title>\n    <script type=\"text/javascript\">\n        var ws;\n        var wsUri = \"ws:\";\n        var loc = window.location;\n        console.log(loc);\n        if (loc.protocol === \"https:\") { wsUri = \"wss:\"; }\n        // This needs to point to the web socket in the Node-RED flow\n        wsUri += \"//\" + loc.host + loc.pathname.replace(\"debug\",\"ws/debug\");\n\n        function wsConnect() {\n            console.log(\"connect\",wsUri);\n            ws = new WebSocket(wsUri);\n            ws.onmessage = function(msg) {\n                segments = document.getElementById('json_data').innerHTML;\n                var paused = document.getElementById('paused').innerText === \"Pause\";\n                var data;\n                var line = \"\";\n                var error = \"\";\n                var date = new Date().toISOString();\n                // parse the incoming message as a JSON object\n                try { \n                    data = JSON.parse(msg.data);\n                } catch (json_error) {\n                    data = {error: [\"json parse error\", json_error]};\n                };   \n                if(!data.error){\n                    var debug_name = data.debug_name ;\n                    var debug_property = data.debug_property_array;\n                    var original_property = data.debug_property;\n                    if(!data.pass_debug_property) delete data.debug_property;\n                    delete data.pass_debug_property;\n                    delete data.debug_property_array;\n                    delete data.debug_name;\n                    debug_property.slice(1).forEach((prop, index) => {\n                        if(data[prop]) {                    \n                            data = data[prop];\n                        }else{\n                           error = \"Property path Error on or after - \" + debug_property[index];\n                        }\n                    });\n\n                    line = `<div id=\"element${date}\">\n                    <hr/>\n                    <span class=\"debug_name\">${debug_name}</span> <span class=\"debug_date\">${date}</span> \n                    <span class=\"debug_orginal\">${original_property}</span> <span class=\"debug_error\">${error}</span> \n                     <button title=\"copy\" alt=\"copy\" onclick=\"copy_text('json_data_${date}')\"> &#10066; </button>\n                    <button title=\"delete\" alt=\"delete\" onclick=\"delete_text('element${date}')\"> &#10060; </button> \n                    <span class=\"json_data\">\n                    <pre id=\"json_data_${date}\"><code id=data>${library.json.prettyPrint(data)}</code></pre></span> \n                    </div>`;\n                }else{\n                    line = `<div id=\"element${date}\">\n                    <hr/>\n                    <span class=\"debug_error\">Error: ${JSON.stringify(data.error)}</span> <span class=\"debug_date\">${date}</span>                  \n                    <button title=\"delete\" alt=\"delete\" onclick=\"delete_text('element${date}')\"> &#10060; </button> \n                    </div>`;\n                }\n            // append line to segment\n            if(paused){\n                document.getElementById('json_data').innerHTML = line + segments;\n            }\n            }\n            ws.onopen = function() {\n                // update the status div with the connection status\n                document.getElementById('status').innerHTML = \"connected\";\n                //ws.send(\"Open for data\");\n                console.log(\"connected\");\n            }\n            ws.onclose = function() {\n                // update the status div with the connection status\n                document.getElementById('status').innerHTML = \"not connected\";\n                // in case of lost connection tries to reconnect every 3 secs\n                setTimeout(wsConnect,3000);\n            }\n        }\n        function copy_text(input) {\n            // Get the text field\n            var copyText = document.getElementById(input).innerText;\n            var dummy = document.createElement(\"textarea\");\n            document.body.appendChild(dummy);\n            dummy.value = copyText;\n            dummy.select();\n            document.execCommand(\"copy\");\n            document.body.removeChild(dummy);\n            alert(\"Copied  Data to Clipboard\\n\\n\" + copyText)\n        }\n        function delete_text(input) {\n            // Get the text field\n            document.getElementById(input).innerHTML = \"\";\n        }\n        if (!library) var library = {};\n            library.json = {\n                replacer: function(match, pIndent, pKey, pVal, pEnd) {\n                    var key = '<span class=json-key>\"';\n                    var val = '<span class=json-value>';\n                    var str = '<span class=json-string>';\n                    var r = pIndent || '';\n                    if (pKey)\n                        r = r + key + pKey.replace(/[\": ]/g, '') + '\"</span>: ';\n                    if (pVal)\n                        r = r + (pVal[0] == '\"' ? str : val) + pVal + '</span>';\n                        return r + (pEnd || '');\n                    },\n                    prettyPrint: function(obj) {\n                        var jsonLine = /^( *)(\"[\\w]+\": )?(\"[^\"]*\"|[\\w.+-]*)?([,[{])?$/mg;\n                        return JSON.stringify(obj, null, 4)\n                            .replace(/&/g, '&amp;').replace(/\\\\\"/g, '&quot;')\n                            .replace(/</g, '&lt;').replace(/>/g, '&gt;')\n                            .replace(jsonLine, library.json.replacer);\n                    }\n                    \n                };\n        function pause() {\n            var element_paused = document.getElementById(\"paused\");\n            paused = (element_paused.innerText === \"Resume\") ? \"Pause\" : \"Resume\";\n            element_paused.innerText = paused;\n        }\n    \n    </script>\n    </head>\n    <body onload=\"wsConnect();\" onunload=\"ws.disconnect();\">\n        <font face=\"Arial\">\n        <h1>Debug Messages <button id=\"paused\" value=\"pause\" onclick=\"pause()\">Pause</button> </h1>\n        <div id=\"json_data\"></div>\n        <hr/>\n        <div id=\"status\">unknown</div>\n        </font>\n    </body>\n</html>\n","x":550,"y":40,"wires":[["42a28745.bd5d78"]]},{"id":"42a28745.bd5d78","type":"http response","z":"3decb5f518882686","name":"","x":730,"y":40,"wires":[]},{"id":"985ecbc7.67a138","type":"websocket-listener","z":"65617ffeb779f51c","path":"/ws/debug","wholemsg":"false"},{"id":"a89494ddb77304ef","type":"subflow:3decb5f518882686","z":"65617ffeb779f51c","name":"","env":[{"name":"debug_name","value":"debug","type":"str"}],"x":540,"y":3740,"wires":[["22d7b380a2a7a696"]],"info":"open web page http://ip_node_red:port/debug"}]

2 Likes