Forked from reversaal / OhmPi
Source project has a limited visibility.
node-red_interface.json 105.76 KiB
        "id": "b19c51e9d4d25a33",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
        "id": "c3dbd6595b0256a9",
        "type": "subflow",
        "name": "Send_commands",
        "info": "",
        "category": "",
        "in": [],
        "out": [
                "x": 1140,
                "y": 240,
                "wires": [
                        "id": "71f435fecd185ab7",
                        "port": 0
        "env": [],
        "meta": {},
        "color": "#DDAA99"
        "id": "1506d9deaa5de120",
        "type": "subflow",
        "name": "Update_settings",
        "info": "",
        "category": "",
        "in": [],
        "out": [
                "x": 1120,
                "y": 120,
                "wires": [
                        "id": "1278358184e5b189",
                        "port": 0
        "env": [],
        "meta": {},
        "color": "#DDAA99"
        "id": "4489e1d51c9522f3",
        "type": "subflow",
        "name": "Data_plots",
        "info": "",
        "category": "",
        "in": [
                "x": 80,
                "y": 300,
                "wires": [
                        "id": "9465b94aca687c9f"
                        "id": "cc84bb5476128ec6"
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
}, { "id": "5bab870fe804aae8" }, { "id": "f655ae35cc8d0036" } ] } ], "out": [], "env": [], "meta": {}, "color": "#DDAA99" }, { "id": "b6b050428bd78f42", "type": "subflow", "name": "Data_table", "info": "", "category": "", "in": [ { "x": 50, "y": 30, "wires": [ { "id": "61a6e472b87b237a" } ] } ], "out": [], "env": [], "meta": {}, "color": "#DDAA99" }, { "id": "2924702c.b33a7", "type": "subflow", "name": "ui-table handler", "info": "# ui-table handler\nUniversal handler for ui-table.\n## features\n- buffer table data\n- add or update individual rows or cells of the table\n- delete rows\n- clear tableData\n- handle column width\n- handle column order\n- hide und unhide columns\n- hide and unhide rows\n- records row order\n- support for nested columns [(column groups)](http://tabulator.info/examples/4.7#column-groups)\n- support for child rows (_children) [(nested data trees)](http://tabulator.info/examples/4.7#tree)\n\nFor real life example see:\n\n**syslog server** for logfile like table with filters\n\n**remote device table** for dynamically updated table with context menues\n\n**irrigation system** for sortable rows\n\n## sending data to ui-tabel\n\n- sending an `array` as discribed in ui-table will replace the complete table and delete all table edits\n \n if `msg.keepEdits=true` is added the existing edits will be kept.\n- send an `object` containing the updated properties of a table row by sending msg.<tableDataProp>.\n\n The table is updated using the `updateOrAddData` command. You can alter the command used by adding the `msg.tabulatorCommand` and `msg.tabulatorParameter`\n\n```\nmsg.tabulatorCommand=\"addData\";\nmsg.tabulatorParameter=[true];\n```\n## configuration\n- `tabulator` json formatted object containing configuration of the table. See ui-table for more details.\n- `property` property of the msg object that contains the data to be passed to ui-table. I.e. *state* `msg.state`\n- `index` index column to identify individual rows. Each message containing data must have a unique `msg.topic` to identify the row. Messages without this `msg.topic` will be droped. It is not nessesary but possible to display the index column in the table. Do not enable editing on this column otherwise you will loose the connection and another row will be added to the table as soon as a new message arrives!\n\n Defaults to *$topic* `msg.state.$topic`\n- `maxRows`maximum number of rows held by table widget. If grater than **0** the amount of rows in ui-table is limited. For this to work the index row must be a Number. ´rows < currentID-maxRows´ will be deleted.\n- `maxStore`maximum number of rows stored by this node for replay if a client connects. If grater than **0** the amount of rows in flow context is limited. for this to work the index row must be a Number. ´rows < currentID-maxStore´ will be deleted.\n- `dashboard` name of the dashboard tab to only update the table if the dashboard is visible. If empty the table will be updated on every tab change and connect.\n- `context` configuration of context data. The subflow will save or cache data in the flows context using `$parent.`. \n **tableData** caches the incoming data to restore it on `ui-control´ *change* messages.\n **tableConfig** saves column width and order to save the interactive table layot\n **tableEdit** saves edits on the table data otherwise it would be overwritten when new data arrives\n```json\n{\n \"tableData\": {\n \"name\": \"tableData\"\n },\n \"tableConfig\": {\n \"name\": \"tableConfig\",\n \"storage\": \"file\"\n },\n \"tableEdit\": {\n \"name\": \"tableEdit\",\n \"storage\": \"file\"\n }\n}\n```\n\n## commands\ncommands can be passed by sending a object as `msg.payload`\n\n```json\n{\n \"command\": \"delete\",\n \"object\": \"columnOrder\"\n}\n```\n\n- `deleteTable` tableCache\n- `deleteRow` delete single row. `object` matching index property\n- `ignoreRow` delete single row and put it on an ignore list. `object` matching index property\n- `unIgnoreRow`remove row from the ignore list. `object` matching index property\n- `unIgnoreRows`delte the ignore list. \n- `deleteRowOrder` delete custom row order\n- `deleteColumnOrder` delete custom column order\n This is important if you add or delete columns in the tabulator config otherwise the columns most likely don`t show up\n- `deleteColumnWidth` delete custom column width\n- `columnHide` hide a column. `object` matching column field\n- `columnUnHide` unhide a column. `object` matching column field\n- `columnsUnHide` unhide all hidden columns.\n- `setMaxStore` set maximum amount of rows in cache\n- `setMaxDisplay` set maximum amout of rows in ui-table\n- `getTable` get table data (as displayed) as an array (on 2nd output)\n \n## background\nui-table warps the powerfull tabluator library. This subflow makes it easier to unleash the powerfull features of ui-table", "category": "dashboard", "in": [ { "x": 54, "y": 85, "wires": [ { "id": "5eb0bd6b.74b794" } ] } ], "out": [ { "x": 360, "y": 85, "wires": [ { "id": "5eb0bd6b.74b794", "port": 1 } ] }, { "x": 360, "y": 136, "wires": [ {
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
"id": "5eb0bd6b.74b794", "port": 2 } ] } ], "env": [ { "name": "tabulator", "type": "json", "value": "{\"tabulator\":{\"responsiveLayout\":\"collapse\",\"responsiveLayoutCollapseStartOpen\":false,\"index\":\"$name\",\"layout\":\"fitColumns\",\"movableColumns\":true,\"groupBy\":\"\",\"columnResized\":\"function(column){ var newColumn = { field: column._column.field, visible: column._column.visible, width: column._column.width, widthFixed: column._column.widthFixed, widthStyled: column._column.widthStyled }; this.send({topic:this.config.topic,ui_control:{callback:'columnResized',columnWidths:newColumn}}); }\",\"columnMoved\":\"function(column, columns){ var newColumns=[]; columns.forEach(function (column) { newColumns.push({'field': column._column.definition.field, 'title': column._column.definition.title}); }); this.send({topic:this.config.topic,ui_control:{callback:'columnMoved',columns:newColumns}}); }\",\"rowFormatter\":\"function(row){ var data = row.getData(); switch (data.$state) { case \\\"lost\\\": row.getElement().style.backgroundColor = \\\"#9e2e66\\\"; row.getElement().style.color = \\\"#a6a6a6\\\"; break; case \\\"sleeping\\\": row.getElement().style.backgroundColor = \\\"#336699\\\"; break; case \\\"disconnected\\\": row.getElement().style.backgroundColor = \\\"#cc3300\\\"; row.getElement().style.color = \\\"#a6a6a6\\\"; break; case \\\"alert\\\": row.getElement().style.backgroundColor = \\\"#A6A6DF\\\"; break; case \\\"init\\\": row.getElement().style.backgroundColor = \\\"#f2f20d\\\"; break; case \\\"ready\\\": row.getElement().style.backgroundColor = \\\"\\\"; row.getElement().style.color = \\\"\\\"; break; } }\",\"columns\":[{\"formatter\":\"responsiveCollapse\",\"width\":30,\"minWidth\":30,\"align\":\"center\",\"resizable\":false,\"headerSort\":false,\"frozen\":true,\"title\":\"expand\",\"field\":\"expand\",\"headerVertical\":\"flip\"},{\"formatter\":\"function(cell, formatterParams, onRendered) { var html = cell.getValue(); return html; }\",\"title\":\"State\",\"field\":\"$stateIcon\",\"width\":100,\"frozen\":true,\"headerVertical\":\"flip\"},{\"formatter\":\"function(cell, formatterParams, onRendered) { var html = cell.getValue(); return html; }\",\"title\":\"Signal\",\"field\":\"signalIcon\",\"width\":100,\"frozen\":true,\"headerVertical\":\"flip\"},{\"title\":\"Name\",\"field\":\"$name\",\"width\":100,\"frozen\":true,\"headerVertical\":\"flip\"},{\"title\":\"State\",\"field\":\"$state\",\"width\":100,\"align\":\"center\",\"headerVertical\":\"flip\"},{\"title\":\"last-ready\",\"field\":\"lastSeenreadyFormatted\",\"width\":100,\"align\":\"left\",\"headerVertical\":\"flip\"},{\"title\":\"Homie\",\"field\":\"$homie\",\"width\":100,\"align\":\"left\",\"headerVertical\":\"flip\"},{\"title\":\"Platform\",\"field\":\"$implementation\",\"width\":100,\"align\":\"left\",\"headerVertical\":\"flip\"},{\"title\":\"Statistics\",\"columns\":[{\"title\":\"Interval\",\"field\":\"interval\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"outputFormat\":\"d hh:mm:ss\",\"inputFormat\":\"seconds\",\"invalidPlaceholder\":\"(unknown)\"},\"title\":\"Uptime\",\"field\":\"uptime\",\"formatter\":\"function(cell, formatterParams, onRendered){ var pad = function (num) { return (\\\"0\\\"+num).slice(-2); }; var secs = Number(cell.getValue()); if (Number.isNaN(secs)) return; var minutes = Math.floor(secs / 60); secs = secs%60; var hours = Math.floor(minutes/60); minutes = minutes%60; var days = Math.floor(hours/24); hours = hours%24; if (days>0) return days+\\\"d \\\"+pad(hours)+\\\":\\\"+pad(minutes); else return pad(hours)+\\\":\\\"+pad(minutes)+\\\":\\\"+pad(secs); }\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"min\":0,\"max\":100,\"color\":[\"red\",\"orange\",\"green\"],\"legend\":\"function (value) {if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+value+\\\" %</span>\\\"; else return; }\",\"legendColor\":\"#FFFFFF\",\"legendAlign\":\"center\"},\"title\":\"Signal\",\"field\":\"signal\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"min\":2.5,\"max\":3.5,\"color\":[\"red\",\"green\",\"red\"],\"legend\":\"function (value) { if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+value+\\\" V</span>\\\"; else return; }\",\"legendColor\":\"#101010\",\"legendAlign\":\"center\"},\"title\":\"Supply\",\"field\":\"supply\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"min\":0,\"max\":100,\"color\":[\"red\",\"orange\",\"green\"],\"legend\":\"function (value) { if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+value+\\\" %</span>\\\"; else return; }\",\"legendColor\":\"#101010\",\"legendAlign\":\"center\"},\"title\":\"Battery\",\"field\":\"battery\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"min\":0,\"max\":100000,\"color\":[\"red\",\"orange\",\"green\"],\"legend\":\"function (value) { if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+(value/1024).toFixed(2)+\\\" kB</span>\\\"; else return; }\",\"legendColor\":\"#101010\",\"legendAlign\":\"center\"},\"title\":\"Memory\",\"field\":\"freeheap\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"target\":\"_blank\",\"min\":0,\"max\":100,\"color\":[\"red\",\"orange\",\"green\"],\"legend\":\"function (value) { if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+value+\\\" %</span>\\\"; else return; }\",\"legendColor\":\"#101010\",\"legendAlign\":\"center\"},\"title\":\"CPU load\",\"field\":\"cpuload\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"},{\"formatterParams\":{\"min\":20,\"max\":60,\"color\":[\"green\",\"orange\",\"red\"],\"legend\":\"function (value) { if (value>0) return \\\"<span style='color:#FFFFFF;'>\\\"+value+\\\" °C</span>\\\"; else return; }\",\"legendColor\":\"#101010\",\"legendAlign\":\"center\"},\"title\":\"CPU temp\",\"field\":\"cputemp\",\"formatter\":\"progress\",\"width\":100,\"headerVertical\":\"flip\"}]},{\"title\":\"Firmware\",\"columns\":[{\"formatter\":\"link\",\"formatterParams\":{\"labelField\":\"$localip\",\"urlPrefix\":\"http://\",\"target\":\"_blank\"},\"title\":\"IP\",\"field\":\"$localip\",\"width\":100},{\"title\":\"mac\",\"field\":\"$mac\",\"width\":100},{\"title\":\"Accsess Point\",\"field\":\"SSID\",\"width\":100},{\"title\":\"Firmware\",\"field\":\"name\",\"width\":100},{\"title\":\"Version\",\"field\":\"version\",\"width\":100},{\"title\":\"Last Boot Cause\",\"field\":\"lastBootCause\",\"width\":100},{\"title\":\"Reset Reason\",\"field\":\"resetReason\",\"width\":100}]}]},\"customHeight\":12}", "ui": { "icon": "font-awesome/fa-table", "label": { "en-US": "Tabulator" }, "type": "input", "opts": { "types": [ "json", "env" ] } } }, { "name": "tableDataProp", "type": "str", "value": "row", "ui": { "icon": "font-awesome/fa-tag", "label": { "en-US": "rowProperty" } } }, { "name": "tableIndex", "type": "str", "value": "$topic", "ui": { "icon": "font-awesome/fa-indent", "label": { "en-US": "Index" }, "type": "input", "opts": { "types": [ "str", "json", "env" ] } } }, { "name": "maxRows", "type": "num", "value": "0", "ui": { "icon": "font-awesome/fa-list-ol", "type": "input", "opts": { "types": [ "num", "bool", "env" ] } }
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
}, { "name": "maxStore", "type": "num", "value": "0", "ui": { "icon": "font-awesome/fa-database", "type": "input", "opts": { "types": [ "num", "env" ] } } }, { "name": "dashboard", "type": "str", "value": "Remote Device Table", "ui": { "icon": "font-awesome/fa-dashboard", "label": { "en-US": "Dashboard" }, "type": "input", "opts": { "types": [ "str", "env" ] } } }, { "name": "tableContext", "type": "json", "value": "{\"tableData\":{\"name\":\"tableData\"},\"tableConfig\":{\"name\":\"tableConfig\",\"storage\":\"file\"},\"tableEdit\":{\"name\":\"tableEdit\",\"storage\":\"file\"}}", "ui": { "icon": "font-awesome/fa-database", "label": { "en-US": "Context" }, "type": "input", "opts": { "types": [ "json", "env" ] } } } ], "color": "#3FADB5", "icon": "node-red-dashboard/ui_slider.png", "status": { "x": 360, "y": 34, "wires": [ { "id": "5eb0bd6b.74b794", "port": 0 } ] } }, { "id": "753d1cb452ebd76e", "type": "subflow", "name": "Set_sequence",
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
"info": "", "category": "", "in": [], "out": [ { "x": 1100, "y": 180, "wires": [ { "id": "8e435b914e061d45", "port": 0 } ] } ], "env": [], "meta": {}, "color": "#DDAA99" }, { "id": "142ad6ae.d55e29", "type": "ui_group", "name": "Commands", "tab": "5d888f29.07334", "order": 1, "disp": true, "width": "8", "collapse": false, "className": "" }, { "id": "5d888f29.07334", "type": "ui_tab", "name": "Control", "icon": "dashboard", "order": 1, "disabled": false, "hidden": false }, { "id": "ea73b76b.ee0738", "type": "ui_base", "theme": { "name": "theme-dark", "lightTheme": { "default": "#0094CE", "baseColor": "#0094CE", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": true, "reset": false }, "darkTheme": { "default": "#097479", "baseColor": "#097479", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": true, "reset": false }, "customTheme": { "name": "Untitled Theme 1", "default": "#4B7930", "baseColor": "#4B7930", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" }, "themeState": { "base-color": { "default": "#097479", "value": "#097479", "edited": true },
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
"page-titlebar-backgroundColor": { "value": "#097479", "edited": false }, "page-backgroundColor": { "value": "#111111", "edited": false }, "page-sidebar-backgroundColor": { "value": "#333333", "edited": false }, "group-textColor": { "value": "#0eb8c0", "edited": false }, "group-borderColor": { "value": "#555555", "edited": false }, "group-backgroundColor": { "value": "#333333", "edited": false }, "widget-textColor": { "value": "#eeeeee", "edited": false }, "widget-backgroundColor": { "value": "#097479", "edited": false }, "widget-borderColor": { "value": "#333333", "edited": false }, "base-font": { "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" } }, "angularTheme": { "primary": "indigo", "accents": "blue", "warn": "red", "background": "grey", "palette": "light" } }, "site": { "name": "OhmPi Node-RED interface", "hideToolbar": "false", "allowSwipe": "true", "lockMenu": "true", "allowTempTheme": "true", "dateFormat": "DD/MM/YYYY", "sizes": { "sx": 48, "sy": 48, "gx": 10, "gy": 10, "cx": 6, "cy": 6, "px": 1, "py": 1 } } }, { "id": "5a09c1ee2a3419c3", "type": "mqtt-broker",
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
"name": "ohmpi_local_broker", "broker": "127.0.0.1", "port": "1880", "clientid": "", "autoConnect": true, "usetls": false, "protocolVersion": "4", "keepalive": "60", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closeQos": "0", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "7792ecc419ecbb59", "type": "ui_group", "name": "Latest reading", "tab": "32170516a52092f8", "order": 2, "disp": true, "width": "6", "collapse": true, "className": "" }, { "id": "b0990b3c5ff3c09a", "type": "ui_group", "name": "Messages", "tab": "5d888f29.07334", "order": 2, "disp": true, "width": 18, "collapse": true, "className": "" }, { "id": "32170516a52092f8", "type": "ui_tab", "name": "Data", "icon": "show_chart", "order": 2, "disabled": false, "hidden": false }, { "id": "d1631b3685c8e6de", "type": "ui_link", "name": "OhmPi Documentation", "link": "https://reversaal.gitlab.irstea.page/OhmPi/", "icon": "help", "target": "newtab", "order": 4 }, { "id": "df2cbd8c9c9960e1", "type": "ui_group", "name": "Sequence", "tab": "32170516a52092f8", "order": 3,
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
"disp": true, "width": 20, "collapse": false, "className": "" }, { "id": "6e40c7571e22771c", "type": "ui_group", "name": "Readings", "tab": "5d888f29.07334", "order": 3, "disp": true, "width": "26", "collapse": false, "className": "" }, { "id": "65037a21a4930ac3", "type": "ui_link", "name": "HTTP interface", "link": "http://localhost:8080", "icon": "open_in_browser", "target": "iframe", "order": 3 }, { "id": "ee5c899fd6c21c26", "type": "ui_spacer", "z": "753d1cb452ebd76e", "name": "spacer", "group": "142ad6ae.d55e29", "order": 1, "width": 2, "height": 1 }, { "id": "3815328eac2780f2", "type": "ui_spacer", "z": "753d1cb452ebd76e", "name": "spacer", "group": "142ad6ae.d55e29", "order": 4, "width": 2, "height": 1 }, { "id": "5719585211dfe472", "type": "ui_group", "name": "Operating commands", "tab": "32170516a52092f8", "order": 1, "disp": true, "width": "20", "collapse": false, "className": "" }, { "id": "767ffbbb662556c3", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "5719585211dfe472", "order": 1, "width": 8, "height": 1 }, { "id": "5d3796147af02744", "type": "ui_spacer", "z": "4489e1d51c9522f3",
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
"name": "spacer", "group": "5719585211dfe472", "order": 4, "width": 8, "height": 1 }, { "id": "c7b2be461926f73a", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 1, "width": 4, "height": 1 }, { "id": "6147cf00447eec22", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 3, "width": 4, "height": 1 }, { "id": "cc01c939aaadd7d1", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 4, "width": 4, "height": 1 }, { "id": "b71492bae3e55727", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 5, "width": 4, "height": 1 }, { "id": "48825c209ad67af9", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 6, "width": 4, "height": 1 }, { "id": "26c2b66b0782e5c7", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 7, "width": 4, "height": 1 }, { "id": "b8574c9809a42e1e", "type": "ui_spacer", "z": "4489e1d51c9522f3",
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
"name": "spacer", "group": "df2cbd8c9c9960e1", "order": 8, "width": 4, "height": 1 }, { "id": "b085a4b9efe2ab69", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 9, "width": 4, "height": 1 }, { "id": "b519f248e1e53c94", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 10, "width": 4, "height": 1 }, { "id": "6f6cdaba90007ba2", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 11, "width": 4, "height": 1 }, { "id": "da59a79748b0b77b", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 12, "width": 4, "height": 1 }, { "id": "e83aeaa7ec6fd3a5", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 13, "width": 4, "height": 1 }, { "id": "ebb552458e0add8f", "type": "ui_spacer", "z": "4489e1d51c9522f3", "name": "spacer", "group": "df2cbd8c9c9960e1", "order": 14, "width": 8, "height": 1 }, { "id": "7e76f03ac9838b7a", "type": "ui_spacer", "z": "4489e1d51c9522f3",
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
"name": "spacer", "group": "df2cbd8c9c9960e1", "order": 16, "width": 8, "height": 1 }, { "id": "71f435fecd185ab7", "type": "join", "z": "c3dbd6595b0256a9", "name": "", "mode": "custom", "build": "merged", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "3", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 970, "y": 240, "wires": [ [] ] }, { "id": "5eb07cfc6ea7e7e4", "type": "change", "z": "c3dbd6595b0256a9", "name": "", "rules": [ { "t": "set", "p": "complete", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 710, "y": 240, "wires": [ [ "71f435fecd185ab7" ] ] }, { "id": "87336107859f0f4c", "type": "delay", "z": "c3dbd6595b0256a9", "name": "", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second",
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
"randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 510, "y": 240, "wires": [ [ "5eb07cfc6ea7e7e4" ] ] }, { "id": "ef7cd86d21809032", "type": "function", "z": "c3dbd6595b0256a9", "name": "set cmd_id", "func": "var newMsg = { payload: {\"cmd_id\": msg.payload }};\nreturn newMsg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 610, "y": 200, "wires": [ [ "71f435fecd185ab7" ] ] }, { "id": "028e5762e321dce2", "type": "uuid", "z": "c3dbd6595b0256a9", "uuidVersion": "v1", "namespaceType": "", "namespace": "", "namespaceCustom": "", "name": "", "field": "payload", "fieldType": "msg", "x": 430, "y": 200, "wires": [ [ "ef7cd86d21809032" ] ] }, { "id": "23f549ae6ee82d23", "type": "function", "z": "c3dbd6595b0256a9", "name": "get cmd", "func": "return global.get(\"command_tmp\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 600, "y": 280, "wires": [ [ "71f435fecd185ab7" ] ]
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
}, { "id": "3027158d54f370fd", "type": "function", "z": "c3dbd6595b0256a9", "name": "get kwargs", "func": "return global.get(\"kwargs\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 610, "y": 320, "wires": [ [ "71f435fecd185ab7" ] ] }, { "id": "2d858a81f7e7f2b3", "type": "ui_button", "z": "c3dbd6595b0256a9", "name": "", "group": "142ad6ae.d55e29", "order": 12, "width": 0, "height": 0, "passthru": false, "label": "Send command", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 200, "y": 240, "wires": [ [ "028e5762e321dce2", "87336107859f0f4c", "23f549ae6ee82d23", "3027158d54f370fd" ] ] }, { "id": "de9e803de4d28986", "type": "ui_dropdown", "z": "c3dbd6595b0256a9", "name": "", "label": "Command", "tooltip": "", "place": "Select option", "group": "142ad6ae.d55e29", "order": 10, "width": 0, "height": 0, "passthru": true, "multiple": false, "options": [ { "label": "", "value": "load_sequence", "type": "str"
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
}, { "label": "", "value": "reset_mux", "type": "str" }, { "label": "", "value": "set_sequence", "type": "str" }, { "label": "", "value": "update_settings", "type": "str" } ], "payload": "", "topic": "command", "topicType": "str", "className": "", "x": 190, "y": 400, "wires": [ [ "68222c7c6633d3fb" ] ] }, { "id": "17f76c1517cb0285", "type": "ui_text_input", "z": "c3dbd6595b0256a9", "name": "", "label": "kwargs", "tooltip": "", "group": "142ad6ae.d55e29", "order": 11, "width": 0, "height": 0, "passthru": true, "mode": "text", "delay": "250", "topic": "kwargs", "sendOnBlur": false, "className": "", "topicType": "str", "x": 179, "y": 457, "wires": [ [ "c25811ae6ee89f2d" ] ] }, { "id": "c25811ae6ee89f2d", "type": "json", "z": "c3dbd6595b0256a9", "name": "", "property": "payload", "action": "", "pretty": false, "x": 329, "y": 457, "wires": [ [ "071930f0cabf3d94" ] ]
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
}, { "id": "68222c7c6633d3fb", "type": "function", "z": "c3dbd6595b0256a9", "name": "set cmd", "func": "var newMsg = { payload: {\"cmd\": msg.payload }};\nglobal.set(\"command_tmp\",newMsg)\nreturn global.get(\"command_tmp\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 400, "wires": [ [] ] }, { "id": "071930f0cabf3d94", "type": "function", "z": "c3dbd6595b0256a9", "name": "set kwargs", "func": "var newMsg = { payload: {\"kwargs\": msg.payload }};\nglobal.set(\"kwargs\", newMsg)\nreturn global.get(\"kwargs\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 489, "y": 457, "wires": [ [] ] }, { "id": "19e8f5b5b199d998", "type": "ui_text", "z": "c3dbd6595b0256a9", "group": "142ad6ae.d55e29", "order": 9, "width": 0, "height": 0, "name": "", "label": "<font size = 4.5>Manual command", "format": "{{msg.payload}}", "layout": "row-left", "className": "", "x": 260, "y": 340, "wires": [] }, { "id": "1278358184e5b189", "type": "join", "z": "1506d9deaa5de120", "name": "", "mode": "custom", "build": "merged", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "3", "reduceRight": false, "reduceExp": "", "reduceInit": "",
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
"reduceInitType": "", "reduceFixup": "", "x": 970, "y": 120, "wires": [ [] ] }, { "id": "5183385a4d4e6cce", "type": "change", "z": "1506d9deaa5de120", "name": "", "rules": [ { "t": "set", "p": "complete", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 710, "y": 120, "wires": [ [ "1278358184e5b189" ] ] }, { "id": "a91742bfc4517ad5", "type": "delay", "z": "1506d9deaa5de120", "name": "", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 510, "y": 120, "wires": [ [ "5183385a4d4e6cce" ] ] }, { "id": "43a86ef16bc90f95", "type": "function", "z": "1506d9deaa5de120", "name": "set cmd_id", "func": "var newMsg = { payload: {\"cmd_id\": msg.payload }};\nreturn newMsg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "",
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
"libs": [], "x": 610, "y": 80, "wires": [ [ "1278358184e5b189" ] ] }, { "id": "8d984843fded4a0b", "type": "uuid", "z": "1506d9deaa5de120", "uuidVersion": "v1", "namespaceType": "", "namespace": "", "namespaceCustom": "", "name": "", "field": "payload", "fieldType": "msg", "x": 430, "y": 80, "wires": [ [ "43a86ef16bc90f95" ] ] }, { "id": "414271cceb77591d", "type": "function", "z": "1506d9deaa5de120", "name": "set kwargs", "func": "return global.get(\"kwargs_tmp\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 630, "y": 200, "wires": [ [ "1278358184e5b189" ] ] }, { "id": "d1ba46c1d65348db", "type": "ui_form", "z": "1506d9deaa5de120", "name": "", "label": "Settings", "group": "142ad6ae.d55e29", "order": 5, "width": 0, "height": 0, "options": [ { "label": "Nb electrodes", "value": "nb_electrodes", "type": "number", "required": false, "rows": null }, { "label": "Injection duration", "value": "injection_duration", "type": "number", "required": false,
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
"rows": null }, { "label": "Nb stack", "value": "nb_stack", "type": "number", "required": false, "rows": null } ], "formValue": { "nb_electrodes": "", "injection_duration": "", "nb_stack": "" }, "payload": "", "submit": "Update settings", "cancel": "cancel", "topic": "topic", "topicType": "msg", "splitLayout": "", "className": "", "x": 180, "y": 540, "wires": [ [ "8d984843fded4a0b", "40e18df2a4f6f7bc", "7c3f483dc0a97154", "92a5062165281e27", "f260d8e69fe63dbb" ] ] }, { "id": "a28983bae6d15cb6", "type": "function", "z": "1506d9deaa5de120", "name": "set kwargs", "func": "var settings = JSON.parse((msg.payload));\nfor (var key in settings) {\n if (settings[key] == null){\n delete settings[key]}\n }\n\nvar newMsg = {\n payload: {\n \"kwargs\": { \"settings\": settings}}}\nglobal.set(\"kwargs_tmp\", newMsg)\nreturn global.get(\"kwargs_tmp\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 530, "y": 540, "wires": [ [] ] }, { "id": "65d9c7d700116da5", "type": "function", "z": "1506d9deaa5de120", "name": "set cmd", "func": "return { payload: { \"cmd\": \"update_settings\" } };", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 600, "y": 160, "wires": [ [ "1278358184e5b189" ] ] },
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
{ "id": "40e18df2a4f6f7bc", "type": "function", "z": "1506d9deaa5de120", "name": "blank", "func": "return { payload: { } };", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 350, "y": 240, "wires": [ [ "a91742bfc4517ad5" ] ] }, { "id": "7c3f483dc0a97154", "type": "delay", "z": "1506d9deaa5de120", "name": "", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 510, "y": 400, "wires": [ [ "414271cceb77591d" ] ] }, { "id": "92a5062165281e27", "type": "delay", "z": "1506d9deaa5de120", "name": "", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 410, "y": 320, "wires": [ [ "65d9c7d700116da5" ] ] }, {
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
"id": "f260d8e69fe63dbb", "type": "json", "z": "1506d9deaa5de120", "name": "", "property": "payload", "action": "", "pretty": false, "x": 350, "y": 540, "wires": [ [ "a28983bae6d15cb6" ] ] }, { "id": "63021563a27e162b", "type": "ui_chart", "z": "4489e1d51c9522f3", "name": "", "group": "df2cbd8c9c9960e1", "order": 2, "width": 12, "height": 6, "label": "Measured resistances chart", "chartType": "line", "legend": "true", "xformat": "HH:mm:ss", "interpolate": "linear", "nodata": "", "dot": true, "ymin": "", "ymax": "", "removeOlder": 1, "removeOlderPoints": "", "removeOlderUnit": "3600", "cutout": 0, "useOneColor": false, "useUTC": false, "colors": [ "#1f77b4", "#aec7e8", "#ff7f0e", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5" ], "outputs": 1, "useDifferentColor": false, "className": "", "x": 660, "y": 340, "wires": [ [] ] }, { "id": "f655ae35cc8d0036", "type": "function", "z": "4489e1d51c9522f3", "name": "function 3", "func": "var msg2 = { payload: JSON.parse(msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`))[\"R [ohm]\"] };\nreturn msg2;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [],
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
"x": 440, "y": 380, "wires": [ [ "d891753fb13281c2", "63021563a27e162b" ] ] }, { "id": "d891753fb13281c2", "type": "debug", "z": "4489e1d51c9522f3", "name": "debug 6", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 600, "y": 400, "wires": [] }, { "id": "8b35e61a7f7a37f8", "type": "ui_gauge", "z": "4489e1d51c9522f3", "name": "", "group": "7792ecc419ecbb59", "order": 1, "width": 6, "height": 4, "gtype": "gage", "title": "Latest measured resistance", "label": "R [Ohm]", "format": "{{value}}", "min": 0, "max": "50", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "className": "", "x": 660, "y": 100, "wires": [] }, { "id": "9465b94aca687c9f", "type": "function", "z": "4489e1d51c9522f3", "name": "function 4", "func": "var msg2 = { payload: JSON.parse(msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`))[\"R [ohm]\"] };\nreturn msg2;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 440, "y": 100, "wires": [ [ "8b35e61a7f7a37f8", "763ea2c282b8b81a" ]
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
] }, { "id": "763ea2c282b8b81a", "type": "debug", "z": "4489e1d51c9522f3", "name": "debug 7", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 460, "y": 40, "wires": [] }, { "id": "57fd4568a66aac99", "type": "ui_gauge", "z": "4489e1d51c9522f3", "name": "", "group": "7792ecc419ecbb59", "order": 2, "width": 6, "height": 4, "gtype": "gage", "title": "Latest measured voltage", "label": "R [Ohm]", "format": "{{value}}", "min": "-1500", "max": "1500", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "className": "", "x": 650, "y": 160, "wires": [] }, { "id": "cc84bb5476128ec6", "type": "function", "z": "4489e1d51c9522f3", "name": "function 5", "func": "var msg2 = { payload: JSON.parse(msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`))[\"Vmn [mV]\"] };\nreturn msg2;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 440, "y": 160, "wires": [ [ "57fd4568a66aac99" ] ] }, { "id": "035c20e764a1f057", "type": "ui_gauge", "z": "4489e1d51c9522f3", "name": "", "group": "7792ecc419ecbb59",
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
"order": 3, "width": 6, "height": 4, "gtype": "gage", "title": "Latest applied current", "label": "R [Ohm]", "format": "{{value}}", "min": 0, "max": "50", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "className": "", "x": 640, "y": 220, "wires": [] }, { "id": "5bab870fe804aae8", "type": "function", "z": "4489e1d51c9522f3", "name": "function 6", "func": "var msg2 = { payload: JSON.parse(msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`))[\"I [mA]\"] };\nreturn msg2;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 440, "y": 220, "wires": [ [ "035c20e764a1f057" ] ] }, { "id": "6efab6f30d54c251", "type": "mqtt out", "z": "4489e1d51c9522f3", "name": "MQTT ctrl", "topic": "ohmpi_XXXX/ctrl", "qos": "2", "retain": "false", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "5a09c1ee2a3419c3", "x": 720, "y": 600, "wires": [] }, { "id": "3725a076feb38906", "type": "ui_button", "z": "4489e1d51c9522f3", "name": "Run sequence", "group": "5719585211dfe472", "order": 2, "width": 2, "height": 1, "passthru": false, "label": "Run", "tooltip": "run sequence",
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
"color": "red", "bgcolor": "lightgrey", "className": "", "icon": "play_circle_fill", "payload": "{\"cmd_id\" :\"0\", \"cmd\":\"run_sequence_async\"}", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 200, "y": 540, "wires": [ [ "6efab6f30d54c251", "adb2ae9f61f9ee82" ] ] }, { "id": "6ef5acf43be3c8f9", "type": "ui_button", "z": "4489e1d51c9522f3", "name": "Interrupt", "group": "5719585211dfe472", "order": 3, "width": 2, "height": 1, "passthru": false, "label": "Stop", "tooltip": "interrupt sequence", "color": "black", "bgcolor": "lightgrey", "className": "", "icon": "stop", "payload": "{\"cmd_id\" :\"0\", \"cmd\":\"interrupt\"}", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 180, "y": 600, "wires": [ [ "6efab6f30d54c251", "adb2ae9f61f9ee82" ] ] }, { "id": "adb2ae9f61f9ee82", "type": "ui_text", "z": "4489e1d51c9522f3", "group": "b0990b3c5ff3c09a", "order": 2, "width": 0, "height": 0, "name": "", "label": "Command sent", "format": "{{msg.payload}}", "layout": "col-center", "className": "", "x": 720, "y": 500, "wires": [] }, { "id": "e0f21bb5ada6c4d7", "type": "function", "z": "b6b050428bd78f42", "name": "Add data", "func": "msg.payload = {\n command: \"addData\", \n arguments: [\n [msg.payload],\n true\n ],\n returnPromise: true\n }\nreturn msg;", "outputs": 1,
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
"noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 660, "y": 80, "wires": [ [ "3d18b988d090ebf5" ] ] }, { "id": "81a5a8e6.5418f8", "type": "function", "z": "b6b050428bd78f42", "name": "store data", "func": "let tabledata = flow.get('tabledata2') || [];\ntabledata.push(msg.payload);\nflow.set('tabledata2',tabledata);\n\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 80, "wires": [ [ "e0f21bb5ada6c4d7" ] ], "icon": "node-red/db.svg" }, { "id": "e873e03a03791394", "type": "ui_ui_control", "z": "b6b050428bd78f42", "name": "", "events": "change", "x": 400, "y": 160, "wires": [ [ "6870f5124586ee5f" ] ] }, { "id": "6870f5124586ee5f", "type": "function", "z": "b6b050428bd78f42", "name": "get data", "func": "msg.payload = flow.get('tabledata2') || [];\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 570, "y": 160, "wires": [ [ "3d18b988d090ebf5" ] ], "icon": "node-red/db.svg" }, { "id": "61a6e472b87b237a", "type": "function", "z": "b6b050428bd78f42",
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
"name": "data", "func": "let counter = context.get('counter') || 0;\ncounter++;\ncontext.set('counter', counter);\n\nvar data = JSON.parse(\n msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`));\n\n//data[\"id\"] = counter\n\nfor (var key in data) {\n data[key] = data[key].toString()\n};\nmsg.payload = data\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 190, "y": 80, "wires": [ [ "81a5a8e6.5418f8" ] ] }, { "id": "3d18b988d090ebf5", "type": "ui_table", "z": "b6b050428bd78f42", "group": "df2cbd8c9c9960e1", "name": "Latest readings", "order": 17, "width": 20, "height": 11, "columns": [ { "field": "time", "title": "Time", "width": "20%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "A", "title": "A", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "B", "title": "B", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "M", "title": "M", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "N", "title": "N", "width": "2%", "align": "center",
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
"formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "R [ohm]", "title": "R [ohm]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Vmn [mV]", "title": "Vmn [mV]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "I [mA]", "title": "I [mA]", "width": "8%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Ps [mV]", "title": "Ps [mV]", "width": "8%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "inj time [ms]", "title": "Injection<br>Time [ms]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "nbStack", "title": "Nb<br>Stack", "width": "5%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Tx [V]", "title": "Tx [V]", "width": "4%", "align": "left",
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
"formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "CPU temp [degC]", "title": "CPU<br>Temp [degC]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Nb samples [-]", "title": "Nb<br>Samples", "width": "3%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "cmd_id", "title": "Cmd<br>ID", "width": "6%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } } ], "outputs": 1, "cts": true, "x": 900, "y": 120, "wires": [ [] ] }, { "id": "43717a0158183d95", "type": "ui_text", "z": "b6b050428bd78f42", "group": "df2cbd8c9c9960e1", "order": 15, "width": 4, "height": 1, "name": "", "label": "<font size = 4.5>Latest readings", "format": "{{msg.payload}}", "layout": "row-left", "className": "", "x": 170, "y": 160, "wires": [] }, { "id": "f67644bcd94bee9b", "type": "ui_button", "z": "b6b050428bd78f42", "name": "", "group": "7792ecc419ecbb59", "order": 4, "width": 0, "height": 0,
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
"passthru": false, "label": "Clear table", "tooltip": "clear all table data", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "", "payloadType": "date", "topic": "", "topicType": "str", "x": 410, "y": 220, "wires": [ [ "ef121340aa158d36" ] ] }, { "id": "ef121340aa158d36", "type": "function", "z": "b6b050428bd78f42", "name": "clearData", "func": "\nmsg.payload={\n command:\"clearData\",\n arguments: [],\n returnPromise: true\n}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 621, "y": 220, "wires": [ [ "3d18b988d090ebf5" ] ], "info": "# clear data\n\nunfortunately this command (currently) do not send a promise back! So we have to pass it directly to the table handler" }, { "id": "5eb0bd6b.74b794", "type": "function", "z": "2924702c.b33a7", "name": "handle tableData", "func": "var status = {fill:\"red\",shape:\"dot\",text: \"payload \"};\nvar tableIndex = env.get(\"tableIndex\") || \"$topic\";\nvar tableDataProp = env.get(\"tableDataProp\") || \"row\";\nvar tableContext = env.get(\"tableContext\");\nvar dashboard = env.get(\"dashboard\");\nvar maxRows = env.get(\"maxRows\") || 0;\nvar maxStore = env.get(\"maxStore\") || 0;\n\nif (!tableContext.hasOwnProperty(\"tableData\") || !tableContext.hasOwnProperty(\"tableConfig\")) {\n status.text=\"tableContext not defined\";\n node.error(status.text);\n return [{payload:status},null];\n}\n\n// context store to cache table data (memoryOnly prefered)\nvar tableData = flow.get(\"$parent.\"+tableContext.tableData.name,tableContext.tableData.storage);\nif (tableData===undefined) {\n node.warn(\"[ui-table handler] tableData initialized!\");\n tableData={};\n flow.set(\"$parent.\"+tableContext.tableData.name,tableData,tableContext.tableData.storage);\n}\n\n// context Store to save table configuration (file)\nvar tableConfig = flow.get(\"$parent.\"+tableContext.tableConfig.name,tableContext.tableConfig.storage);\nif (tableConfig===undefined) {\n node.warn(\"[ui-table handler] tableConfig initialized!\");\n tableConfig={ResponsiveLayout:true};\n flow.set(\"$parent.\"+tableContext.tableConfig.name,tableConfig,tableContext.tableConfig.storage);\n}\n\nif (tableConfig.hasOwnProperty(\"maxStore\")) maxStore=tableConfig.maxStore;\nif (tableConfig.hasOwnProperty(\"maxRows\")) maxRows=tableConfig.maxRows;\n\n// context Store to save table configuration (file)\nvar tableEdit;\nif (tableContext.hasOwnProperty(\"tableEdit\")) {\n tableEdit = flow.get(\"$parent.\"+tableContext.tableEdit.name,tableContext.tableEdit.storage);\n if (tableEdit===undefined) {\n node.warn(\"[ui-table handler] tableEdit initialized!\");\n tableEdit={};\n flow.set(\"$parent.\"+tableContext.tableEdit.name,tableEdit,tableContext.tableEdit.storage);\n }\n}\n\n// function to merge partial data into existing table row\nvar mergeObject = function (destination, source, filter) {\n for (let currentSource in source) {\n if (source.hasOwnProperty(currentSource)) {\n if (filter!==undefined && tableEdit && tableEdit.hasOwnProperty(filter) && tableEdit[filter].hasOwnProperty(currentSource)) {\n destination[currentSource]= tableEdit[filter][currentSource];\n source[currentSource]=tableEdit[filter][currentSource];\n } else {\n destination[currentSource]= source[currentSource];\n }\n } \n }\n return source;\n};\n\n// merge edits into a destination object respecting _children\nvar mergeEdits = function(destination) {\n \n var mergeChildEdits = function(children) {\n children.forEach(child => {\n if (child.hasOwnProperty(tableIndex) && tableEdit.hasOwnProperty(child[tableIndex])) {\n// node.warn([\"mergeChild\",child])\n Object.keys(tableEdit[child[tableIndex]]).forEach(edit => {\n if (child.hasOwnProperty(edit)) {\n child[edit]=tableEdit[child[tableIndex]][edit];\n// node.warn([\"mergeChild edit \",edit,child[edit]])\n }\n });\n }\n if (child.hasOwnProperty(\"_children\")) {\n mergeChildEdits(child._children);\n }\n })\n }\n \n\n Object.keys(destination).forEach(row => {\n if (destination[row].hasOwnProperty(tableIndex)) {\n if (tableEdit.hasOwnProperty(row)) {\n Object.keys(tableEdit[row]).forEach(edit => {\n destination[row][edit]=tableEdit[row][edit];\n });\n }\n if (destination[row].hasOwnProperty(\"_children\")) {\n mergeChildEdits(destination[row]._children);\n }\n }\n });\n}\n\n// deep search for a column including nested columns\nvar searchTabulatorColumn = function (columns,key,match) {\n var result;\n for (let column of columns) {\n if (column.hasOwnProperty(\"columns\")) {\n result = searchTabulatorColumn(column.columns,key,match);\n if (result!==undefined) return result;\n } else if (column.hasOwnProperty(key) && column[key]===match) {\n return column;\n }\n }\n};\n\n// command message to update add or update data on ui-table\nvar msgToTable={};\nmsgToTable.payload={\n \"command\":msg.tabulatorCommand || \"updateOrAddData\",\n \"arguments\": [],\n \"returnPromise\": false\n};\n\n// store data in tableData\nif (msg.hasOwnProperty(tableDataProp)) {\n // store data for later recover\n if (!msg.hasOwnProperty(\"topic\")) { // check if index existst\n status.text=\"msg.topic not defined!\";\n return [{payload:status},null];\n }\n if (!tableData.hasOwnProperty(msg.topic)){ // first seen\n if (maxRows>0 && Object.keys(tableData).lenght===0) {\n tableConfig.currentFirstRow=msg.topic;\n }\n tableData[msg.topic]={};\n if (tableEdit && tableEdit.hasOwnProperty(msg.topic)) { // table edits available!\n Object.keys(tableEdit[msg.topic]).forEach((key) => {\n msg[tableDataProp][key]=tableEdit[msg.topic][key];\n tableData[msg.topic][key]=tableEdit[msg.topic][key];\n })\n }\n if (maxStore>0 && typeof msg.topic === \"number\") { // limit rows in tableData\n let rowKeys = Object.keys(tableData);\n if (rowKeys.length>maxStore) {\n for (let i=0; i<(rowKeys.length-maxStore); i++) {\n delete tableData[rowKeys[i]];\n }\n }\n }\n }\n if (!tableData[msg.topic].hasOwnProperty(tableIndex)) tableData[msg.topic][tableIndex]=msg.topic;\n msg[tableDataProp]=mergeObject(tableData[msg.topic],msg[tableDataProp],msg.topic);\n msg[tableDataProp][tableIndex]=msg.topic;\n msgToTable.payload.arguments=[[msg[tableDataProp]]];\n // add aditional parameters\n if (msg.hasOwnProperty(\"tabulatorParameter\") && Array.isArray(msg.tabulatorParameter)) {\n for (let arg in msg.tabulatorParameter) msgToTable.payload.arguments.push(arg);\n }\n // delete rows if rows exceed maxRows\n /*\n if (maxRows>0 && tableConfig.hasOwnProperty(\"currentFirstRow\") && typeof tableData[msg.topic][tableIndex]===\"number\") {\n //node.warn([maxRows,tableConfig.hasOwnProperty(\"currentFirstRow\"),typeof tableData[msg.topic][tableIndex],tableConfig.currentFirstRow,tableData[msg.topic][tableIndex]-maxRows])\n if (tableConfig.currentFirstRow<tableData[msg.topic][tableIndex]-maxRows) {\n node.warn([\"maxRowExeeded\",tableConfig.currentFirstRow]);\n node.send([null,{payload:{\"command\":\"deleteRow\",\"arguments\": [tableConfig.currentFirstRow],\"returnPromise\": false}},null]);\n tableConfig.currentFirstRow++;\n }\n }*/\n if (maxRows>0 && typeof tableData[msg.topic][tableIndex]===\"number\" && msg.topic-maxRows>0) {\n node.send([null,{payload:{\"command\":\"deleteRow\",\"arguments\": [msg.topic-maxRows],\"returnPromise\": false}},null]);\n }\n status.fill=\"green\";\n status.text=msg.topic+\" updated\";\n return [{payload:status},msgToTable,null];\n} if (msg.payload===\"connect\" || (msg.payload===\"change\" && msg.name===dashboard) || (msg.hasOwnProperty(\"payload\") && msg.payload.hasOwnProperty(\"command\"))) { \n if (!msg.hasOwnProperty(\"ui_control\")) {\n msg.ui_control = env.get('tabulator');\n status.text+=\" ui_control added\";\n }\n //process commands\n //node.warn({\"command\":msg.payload.command,\"msg\":msg,\"object\":msg.payload.object})\n if (msg.payload.hasOwnProperty(\"command\") && msg.payload.command!=='getTable') {\n status.fill=\"blue\";\n switch(msg.payload.command) {\n case 'deleteTable':\n flow.set(\"$parent.\"+tableContext.tableData.name,undefined,tableContext.tableData.storage);\n tableData={};\n status.text=\"tabledata deleted\";\n node.warn(\"[ui-table handler] \"+\"tabledata deleted\");\n break;\n case 'deleteRow':\n case 'deleteDevice':\n var deleteRow = function(id) {\n // check if row is in root\n if (tableData.hasOwnProperty(id)) {\n delete tableData[id]\n return true;\n }\n // check if row is a child\n let deleteChildRow = function(children, id) {\n for(let i = 0; i < children.length; i++){\n if (children[i].hasOwnProperty(tableIndex) && children[i][tableIndex]===id) {\n children.splice(i, 1); \n return true; \n }\n if (children[i].hasOwnProperty(\"_children\")) {\n if (deleteChildRow(children[i]._children,id)) {\n if (children[i]._children.length === 0) {\n delete children[i]._children;\n }\n return true;\n }\n }\n }\n return false;\n };\n \n for (let row in tableData) {\n if (tableData[row].hasOwnProperty(\"_children\")) {\n if (deleteChildRow(tableData[row]._children,id)) return true;\n }\n }\n return false;\n }\n \n if (deleteRow(msg.payload.object)) {\n status.text=msg.payload.object+\" deleted\";\n } else {\n status.fill=\"yellow\";\n status.text=msg.payload.object+\" undefined\";\n }\n break;\n case 'ignoreRow':\n case 'ignoreDevice':\n if (tableData.hasOwnProperty(msg.payload.object)) {\n delete tableData[msg.payload.object];\n status.text=msg.payload.object+\" will be ignored\";\n if (!tableConfig.hasOwnProperty('ignoreDevice')) tableConfig.ignoreDevice={};\n tableConfig.ignoreDevice[msg.payload.object]=true;\n }\n break;\n case 'unIgnoreRow':\n case 'unIgnoreDevice':\n if (tableConfig.hasOwnProperty('ignoreDevice')) {\n delete tableConfig.ignoreDevice[msg.payload.object];\n }\n break;\n case 'unIgnoreRows':\n case 'unIgnoreDevices':\n delete tableConfig.ignoreDevice;\n break;\n case 'updateData':\n status.text=\"column \"+msg.payload.column+\" updated\";\n delete msg.ui_control;\n return [{payload:status},msg];\n case 'updateTable':\n status.text=msg.payload.command+\": \";\n break;\n case 'columnHide':\n if (!tableConfig.hasOwnProperty('columnVisible')) tableConfig.columnVisible={};\n tableConfig.columnVisible[msg.payload.object]=false;\n break;\n case 'columnUnHide':\n if (!tableConfig.hasOwnProperty('columnVisible')) tableConfig.columnVisible={};\n tableConfig.columnVisible[msg.payload.object]=true;\n break;\n case 'columnsUnHide':\n for (let column in tableConfig.columnVisible) {\n if (tableConfig.columnVisible.hasOwnProperty(column)) tableConfig.columnVisible[column]=true;\n }\n break;\n case 'refreshTable':\n break;\n case 'deleteColumnOrder':\n case 'restoreColumnOrder':\n delete tableConfig.columns;\n break;\n case 'deleteColumnWidth':\n case 'resetColumnWidth':\n delete tableConfig.columnWidths;\n break;\n case 'setResponsiveLayout':\n tableConfig.ResponsiveLayout=!tableConfig.ResponsiveLayout;\n break;\n case 'deleteRowOrder':\n delete tableConfig.rowOrder;\n break;\n case 'setMaxStore':\n tableConfig.maxStore=msg.payload.object;\n maxStore=msg.payload.object;\n break;\n case 'setMaxRows':\n tableConfig.maxRows=msg.payload.object;\n maxRows=msg.payload.object;\n break;\n default:\n status.fill=\"red\";\n status.text=\"unknown command \"+msg.payload.command;\n node.warn(\"[ui-table handler] \"+status.text);\n break;\n }\n flow.set(\"$parent.\"+tableContext.tableConfig.name,tableConfig,tableContext.tableConfig.storage);\n node.send([{payload:status},null,null]);\n }\n\n // crawl through tabulator arrays and updated user defined values\n var crawlTabulator = function (columns,match,config,property) {\n for (let column of columns) {\n if (column.hasOwnProperty(\"columns\")) {\n crawlTabulator(column.columns,match,config,property);\n } else if (config.hasOwnProperty(column[match])) column[property]=config[column.field];\n }\n };\n \n // restore custom column width\n if (tableConfig.hasOwnProperty(\"columnWidths\") && msg.hasOwnProperty(\"ui_control\")) {\n crawlTabulator(msg.ui_control.tabulator.columns,\"field\",tableConfig.columnWidths,\"width\");\n }\n \n // restore custom column hide/show\n if (tableConfig.hasOwnProperty(\"columnVisible\") && msg.hasOwnProperty(\"ui_control\")) {\n crawlTabulator(msg.ui_control.tabulator.columns,\"field\",tableConfig.columnVisible,\"visible\");\n }\n \n // restore custom responsive / standard view\n if (tableConfig.hasOwnProperty(\"ResponsiveLayout\")) {\n if (!tableConfig.ResponsiveLayout) {\n msg.ui_control.tabulator.responsiveLayout=false;\n }\n msg.ui_control.tabulator.columns.forEach((column,index) => {\n if (column.formatter===\"responsiveCollapse\") { // hide expand column on any position\n column.visible=tableConfig.ResponsiveLayout;\n return;\n }\n });\n }\n\n // sort columns\n if (tableConfig.hasOwnProperty(\"columns\") && msg.hasOwnProperty(\"ui_control\") && msg.ui_control.hasOwnProperty(\"tabulator\")) {\n var addedColumns = 0;\n var sortColumnsByLayout = function (sortColumns, columnsLayout, targetColumns) {\n for (var layoutColumn=0; layoutColumn<columnsLayout.length; layoutColumn++) {\n for (var sortColumn in sortColumns) {\n if (sortColumns[sortColumn].hasOwnProperty(\"columns\")) {\n targetColumns.push({\"title\":sortColumns[sortColumn].title, \"columns\":[]});\n sortColumnsByLayout(sortColumns[sortColumn].columns,columnsLayout,targetColumns[targetColumns.length-1].columns);\n layoutColumn=addedColumns; // jump forward after childes added\n } else {\n if (columnsLayout[layoutColumn].field===sortColumns[sortColumn].field){\n targetColumns.push(sortColumns[sortColumn]);\n addedColumns++;\n break;\n }\n }\n }\n }\n }; \n var newColumns=[];\n sortColumnsByLayout(msg.ui_control.tabulator.columns,tableConfig.columns,newColumns);\n msg.ui_control.tabulator.columns=newColumns;\n }\n\n // restore stored lines after connect\n\n let command = msg.payload.command;\n var tableArray;\n if (command===\"getTable\") {\n msg.payload.tableArray=[];\n tableArray=msg.payload.tableArray\n } else {\n msg.payload=[];\n tableArray=msg.payload;\n }\n \n var pushRowData = function(rowData) {\n // ignore rows in ignoreRows array\n if (tableConfig && tableConfig.hasOwnProperty(\"ignoreDevice\") && tableConfig.ignoreDevice[rowData]) {\n // do nothing\n } else {\n // merge edits into table\n if (tableEdit && tableEdit.hasOwnProperty(rowData)) {\n let tableRow = RED.util.cloneMessage(tableData[rowData]);\n Object.keys(tableEdit[rowData]).forEach((field) => {\n tableRow[field]=tableEdit[rowData][field];\n });\n tableArray.push(tableRow);\n } else {\n tableArray.push(tableData[rowData]);\n }\n }\n }\n \n if (tableConfig.hasOwnProperty(\"rowOrder\")) {\n // first check if new rows exits which are not in rowOrder\n Object.keys(tableData).forEach((key) => {\n if (tableConfig.rowOrder.indexOf(tableData[key][tableIndex])<0) {\n tableConfig.rowOrder.push(tableData[key][tableIndex]); // add row to the end of rowOrder\n }\n });\n tableConfig.rowOrder.forEach((value,index) => {\n node.warn([\"pushRowOrder\",value,tableData.hasOwnProperty(value),tableData[value]]);\n if (tableData.hasOwnProperty(value)) { // push rows in rowOrder sequence\n pushRowData(value);\n } else { // delete not existing rows from rowOrder\n tableConfig.rowOrder.splice(index,1)\n }\n });\n } else {\n for (let rowData in tableData) {\n pushRowData(rowData);\n }\n }\n // store the first index if maxRows limits amount of displayed lines\n if (maxRows>0 && tableData) {\n let tableKeys=Object.keys(tableData);\n if (tableKeys.length>0 && typeof tableData[tableKeys[0]][tableIndex] === \"number\") {\n tableConfig.currentFirstRow=tableData[tableKeys[0]][tableIndex];\n }\n }\n \n if (command=='getTable'){\n status.fill=\"blue\";\n status.text+=\" \"+tableArray.length+\" rows emitted\";\n return [{payload:status},null,msg];\n } else {\n status.fill=\"blue\";\n status.text+=\" \"+tableArray.length+\" rows restored\";\n return [{payload:status},msg,[{topic:\"maxRows\",payload:maxRows},{topic:\"maxStore\",payload:maxStore}]];\n }\n} if (msg.hasOwnProperty(\"ui_control\")) {\n // callback from tabulator\n status.fill=\"blue\";\n status.text=\"callback \"+msg.ui_control.callback;\n switch(msg.ui_control.callback) {\n case \"columnResized\": // save new column width\n if (tableConfig.columnWidths===undefined) tableConfig.columnWidths={};\n tableConfig.columnWidths[msg.ui_control.columnWidths.field]=msg.ui_control.columnWidths.width;\n flow.set(\"$parent.\"+tableContext.tableConfig.name,tableConfig,tableContext.tableConfig.storage);\n status.text=msg.ui_control.columnWidths.field+\"=\"+msg.ui_control.columnWidths.width+\"px\";\n break;\n case \"columnMoved\": // save new column order\n if (tableConfig.columns===undefined) tableConfig.columns=[];\n tableConfig.columns=msg.ui_control.columns;\n flow.set(\"$parent.\"+tableContext.tableConfig.name,tableConfig,tableContext.tableConfig.storage);\n status.text=\"new column order\";\n break;\n case \"cellEdited\":\n if (tableEdit) {\n if (!tableEdit.hasOwnProperty(msg[tableIndex])) tableEdit[msg[tableIndex]]={};\n tableEdit[msg[tableIndex]][msg.field] = msg.payload; // save data and mark as edited field\n flow.set(\"$parent.\"+tableContext.tableEdit.name,tableEdit,tableContext.tableEdit.storage);\n mergeEdits(tableData);\n flow.set(\"$parent.\"+tableContext.tableData.name,tableData,tableContext.tableData.storage);\n status.text=msg[tableIndex]+\" \"+msg.field+\" edited to \"+msg.payload;\n msg[tableDataProp]={};\n msg[tableDataProp][tableIndex]=msg[tableIndex];\n msg[tableDataProp][msg.field]=msg.payload;\n msgToTable.payload.arguments=[[msg[tableDataProp]]];\n node.send([{payload:status},null,msg]); // was node.send([{payload:status},msgToTable,msg]);\n } else {\n node.error(\"[ui-table handler] no tableEdit store defined!\")\n }\n break;\n case \"rowContext\":\n msg.ignoredDevices=[];\n for (let rowData in tableConfig.ignoreDevice) {\n if (tableConfig.ignoreDevice.hasOwnProperty(rowData)) {\n msg.ignoredDevices.push({\"text\":rowData,\"icon\":\"fa fa-plug\",\"topic\":\"unIgnoreDevice\",\"payload\":rowData}) \n }\n }\n break;\n case \"headerContext\":\n msg.hiddenColumns=[];\n let tabulatorConfig = env.get('tabulator');\n for (let column in tableConfig.columnVisible) {\n if (tableConfig.columnVisible.hasOwnProperty(column) &&\n !tableConfig.columnVisible[column]) {\n let configColumn=searchTabulatorColumn(tabulatorConfig.tabulator.columns,\"field\",column);\n let icon;\n if (configColumn.hasOwnProperty('title') && configColumn.title.toLowerCase().includes('</i>')) {\n // <i class='fa fa-star-half-o'></i> State\n let start=configColumn.title.indexOf(\"'fa \");\n let end=configColumn.title.indexOf(\"'\",start+1);\n icon=configColumn.title.substring(start+4,end);\n }\n msg.hiddenColumns.push({\"text\":column,\"icon\":icon,\"topic\":\"columnUnHide\",\"payload\":configColumn.field}) \n }\n }\n break;\n case \"rowMoved\":\n if (tableConfig.rowOrder===undefined) tableConfig.rowOrder={};\n tableConfig.rowOrder=msg.ui_control.rowOrder;\n flow.set(\"$parent.\"+tableContext.tableConfig.name,tableConfig,tableContext.tableConfig.storage);\n status.text=\"new row order\";\n break;\n default:\n // if rowIndex exists pass complete object\n if (msg.hasOwnProperty(tableIndex)) {\n msg.rowData=tableData[msg[tableIndex]];\n }\n status.text=\"pass message\";\n }\n return [{payload:status},null,msg];\n} \nif (Array.isArray(msg.payload)) {\n tableData={};\n \n msg.payload.forEach((row) => {\n if (row.hasOwnProperty(tableIndex)) {\n tableData[row[tableIndex]]=row;\n }\n });\n if (msg.keepEdits) {\n mergeEdits(tableData);\n }\n\n \n flow.set(\"$parent.\"+tableContext.tableData.name,tableData,tableContext.tableData.storage);\n if (tableContext.hasOwnProperty(\"tableEdit\") && !msg.keepEdits) {\n tableEdit={};\n flow.set(\"$parent.\"+tableContext.tableEdit.name,tableEdit,tableContext.tableEdit.storage);\n }\n status.fill=\"blue\"\n status.text=\"table replaced \"+msg.payload.length+\" rows\";\n return [{payload:status},msg,null];\n} \n \n// nothing to do bejond this point\nstatus.text+=\" [\"+msg.payload+\"]\";\nreturn [{payload:status},null];\n", "outputs": 3, "noerr": 0, "initialize": "", "finalize": "", "x": 192, "y": 85, "wires": [ [], [], [] ], "icon": "font-awesome/fa-table" }, { "id": "a646103fce176d34", "type": "function", "z": "753d1cb452ebd76e", "name": "set kwargs", "func": "var newMsg = {\n payload: {\n \"kwargs\": { \"filename\": msg.payload}}}\nglobal.set(\"kwargs_sequence\", newMsg)\nreturn global.get(\"kwargs_sequence\");", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 530,
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
"y": 360, "wires": [ [ "24edf8b8e8cc4fe9" ] ] }, { "id": "fc325307f9b71ad7", "type": "ui_text_input", "z": "753d1cb452ebd76e", "name": "", "label": "Filename", "tooltip": "", "group": "142ad6ae.d55e29", "order": 7, "width": 0, "height": 0, "passthru": true, "mode": "text", "delay": "250", "topic": "filename", "sendOnBlur": false, "className": "", "topicType": "str", "x": 180, "y": 360, "wires": [ [ "a646103fce176d34" ] ] }, { "id": "6a463bf900cbcb18", "type": "ui_button", "z": "753d1cb452ebd76e", "name": "", "group": "142ad6ae.d55e29", "order": 8, "width": 0, "height": 0, "passthru": false, "label": "Load sequence", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 180, "y": 220, "wires": [ [ "f7179af84070f140", "60f30b88fa0fd1a5", "a91347161001f3b5", "c32e7279d6c9a272" ] ] }, { "id": "c32e7279d6c9a272", "type": "function", "z": "753d1cb452ebd76e", "name": "set kwargs", "func": "return global.get(\"kwargs_sequence\");",
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
"outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 610, "y": 280, "wires": [ [ "8e435b914e061d45" ] ] }, { "id": "8e435b914e061d45", "type": "join", "z": "753d1cb452ebd76e", "name": "", "mode": "custom", "build": "merged", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "3", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 950, "y": 200, "wires": [ [] ] }, { "id": "009df2f988c7e6ba", "type": "change", "z": "753d1cb452ebd76e", "name": "", "rules": [ { "t": "set", "p": "complete", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 690, "y": 200, "wires": [ [ "8e435b914e061d45" ] ] }, { "id": "ad9caa24ea8df8c7", "type": "function", "z": "753d1cb452ebd76e",
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
"name": "set cmd_id", "func": "var newMsg = { payload: {\"cmd_id\": msg.payload }};\nreturn newMsg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 590, "y": 160, "wires": [ [ "8e435b914e061d45" ] ] }, { "id": "a91347161001f3b5", "type": "function", "z": "753d1cb452ebd76e", "name": "set cmd", "func": "return { payload: { \"cmd\": \"load_sequence\" } };", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 580, "y": 240, "wires": [ [ "8e435b914e061d45" ] ] }, { "id": "60f30b88fa0fd1a5", "type": "delay", "z": "753d1cb452ebd76e", "name": "", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 490, "y": 200, "wires": [ [ "009df2f988c7e6ba" ] ] }, { "id": "f7179af84070f140", "type": "uuid", "z": "753d1cb452ebd76e", "uuidVersion": "v1", "namespaceType": "", "namespace": "", "namespaceCustom": "", "name": "", "field": "payload", "fieldType": "msg",
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
"x": 410, "y": 160, "wires": [ [ "ad9caa24ea8df8c7" ] ] }, { "id": "24edf8b8e8cc4fe9", "type": "debug", "z": "753d1cb452ebd76e", "name": "debug 8", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 740, "y": 360, "wires": [] }, { "id": "f0e1c3fb6491d3de", "type": "ui_text", "z": "753d1cb452ebd76e", "group": "142ad6ae.d55e29", "order": 6, "width": 4, "height": 1, "name": "", "label": "<font size = 4.5>Load sequence", "format": "{{msg.payload}}", "layout": "row-left", "className": "", "x": 210, "y": 300, "wires": [] }, { "id": "0f23781293c4b819", "type": "mqtt in", "z": "b19c51e9d4d25a33", "name": "", "topic": "ohmpi_XXXX/exec", "qos": "2", "datatype": "auto-detect", "broker": "5a09c1ee2a3419c3", "nl": false, "rap": false, "inputs": 0, "x": 330, "y": 40, "wires": [ [ "a5740258089c58ac" ] ] }, { "id": "36ba500fac1d0f38", "type": "mqtt in", "z": "b19c51e9d4d25a33", "name": "", "topic": "ohmpi_XXXX/data", "qos": "2", "datatype": "auto", "broker": "5a09c1ee2a3419c3",
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
"nl": false, "rap": false, "inputs": 0, "x": 330, "y": 140, "wires": [ [ "f6075b441607acc4", "2a196662df41046e", "946869bda15d570c", "d3229390343731e3" ] ] }, { "id": "16b2937ad25f25d2", "type": "mqtt out", "z": "b19c51e9d4d25a33", "name": "MQTT ctrl", "topic": "ohmpi_XXXX/ctrl", "qos": "2", "retain": "false", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "5a09c1ee2a3419c3", "x": 820, "y": 400, "wires": [] }, { "id": "c7c725c7f947f5a8", "type": "mqtt in", "z": "b19c51e9d4d25a33", "name": "", "topic": "ohmpi_xxxx/soh", "qos": "2", "datatype": "auto", "broker": "5a09c1ee2a3419c3", "nl": false, "rap": false, "inputs": 0, "x": 320, "y": 240, "wires": [ [] ] }, { "id": "06e401792488500e", "type": "ui_button", "z": "b19c51e9d4d25a33", "name": "Run sequence", "group": "142ad6ae.d55e29", "order": 2, "width": 2, "height": 1, "passthru": false, "label": "Run", "tooltip": "run sequence", "color": "red", "bgcolor": "lightgrey", "className": "", "icon": "play_circle_fill", "payload": "{\"cmd_id\" :\"0\", \"cmd\":\"run_sequence_async\"}", "payloadType": "str", "topic": "topic", "topicType": "msg",
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
"x": 320, "y": 340, "wires": [ [ "16b2937ad25f25d2", "649dbc02e71571e2" ] ] }, { "id": "c427102c051828b6", "type": "ui_button", "z": "b19c51e9d4d25a33", "name": "Interrupt", "group": "142ad6ae.d55e29", "order": 3, "width": 2, "height": 1, "passthru": false, "label": "Stop", "tooltip": "interrupt sequence", "color": "black", "bgcolor": "lightgrey", "className": "", "icon": "stop", "payload": "{\"cmd_id\" :\"0\", \"cmd\":\"interrupt\"}", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 300, "y": 400, "wires": [ [ "16b2937ad25f25d2", "649dbc02e71571e2" ] ] }, { "id": "f4b6096e60252b62", "type": "ui_text", "z": "b19c51e9d4d25a33", "group": "b0990b3c5ff3c09a", "order": 3, "width": 18, "height": 6, "name": "MQTT exec", "label": "Execution", "format": "{{msg.payload}}", "layout": "col-center", "className": "", "x": 830, "y": 40, "wires": [] }, { "id": "f6075b441607acc4", "type": "ui_text", "z": "b19c51e9d4d25a33", "group": "b0990b3c5ff3c09a", "order": 4, "width": 18, "height": 4, "name": "MQTT Data", "label": "Data", "format": "{{msg.payload}}", "layout": "col-center", "className": "", "x": 830, "y": 140,
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
"wires": [] }, { "id": "455f7fa404a19428", "type": "ui_button", "z": "b19c51e9d4d25a33", "name": "", "group": "b0990b3c5ff3c09a", "order": 1, "width": 0, "height": 0, "passthru": false, "label": "clear messages", "tooltip": "", "color": "", "bgcolor": "", "className": "<p style=\"background-color:Tomato;\">", "icon": "", "payload": " ", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 580, "y": 200, "wires": [ [ "f6075b441607acc4", "f4b6096e60252b62", "649dbc02e71571e2" ] ] }, { "id": "31071d204231a91b", "type": "subflow:c3dbd6595b0256a9", "z": "b19c51e9d4d25a33", "name": "", "x": 320, "y": 540, "wires": [ [ "16b2937ad25f25d2", "649dbc02e71571e2" ] ] }, { "id": "e62faba48a0960cc", "type": "subflow:1506d9deaa5de120", "z": "b19c51e9d4d25a33", "name": "", "x": 320, "y": 640, "wires": [ [ "16b2937ad25f25d2", "649dbc02e71571e2" ] ] }, { "id": "649dbc02e71571e2", "type": "ui_text", "z": "b19c51e9d4d25a33", "group": "b0990b3c5ff3c09a", "order": 2, "width": 0, "height": 0, "name": "", "label": "Command sent",
2521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590
"format": "{{msg.payload}}", "layout": "col-center", "className": "", "x": 840, "y": 300, "wires": [] }, { "id": "2a196662df41046e", "type": "subflow:4489e1d51c9522f3", "z": "b19c51e9d4d25a33", "name": "", "x": 1190, "y": 60, "wires": [] }, { "id": "946869bda15d570c", "type": "subflow:b6b050428bd78f42", "z": "b19c51e9d4d25a33", "name": "", "x": 1190, "y": 100, "wires": [] }, { "id": "d16e9ecebccafc37", "type": "ui_table", "z": "b19c51e9d4d25a33", "group": "6e40c7571e22771c", "name": "Latest reading", "order": 1, "width": 0, "height": 0, "columns": [ { "field": "time", "title": "Time", "width": "20%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "A", "title": "A", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "B", "title": "B", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "M", "title": "M", "width": "2%", "align": "center",
2591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660
"formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "N", "title": "N", "width": "2%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "R [ohm]", "title": "R [ohm]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Vmn [mV]", "title": "Vmn [mV]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "I [mA]", "title": "I [mA]", "width": "8%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Ps [mV]", "title": "Ps [mV]", "width": "8%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "inj time [ms]", "title": "Injection<br>Time [ms]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "nbStack", "title": "Nb<br>Stack", "width": "5%", "align": "center",
2661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730
"formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Tx [V]", "title": "Tx [V]", "width": "4%", "align": "left", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "CPU temp [degC]", "title": "CPU<br>Temp [degC]", "width": "8%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "Nb samples [-]", "title": "Nb<br>Samples", "width": "3%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } }, { "field": "cmd_id", "title": "Cmd<br>ID", "width": "6%", "align": "center", "formatter": "plaintext", "formatterParams": { "target": "_blank" } } ], "outputs": 1, "cts": true, "x": 1140, "y": 140, "wires": [ [] ] }, { "id": "d3229390343731e3", "type": "function", "z": "b19c51e9d4d25a33", "name": "data", "func": "var data = JSON.parse(\n msg.payload.split(' | ')[2].slice(6,).split(`'`).join(`\"`));\n\nfor (var key in data) {\n data[key] = data[key].toString()\n};\nmsg.payload = data\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 810, "y": 180, "wires": [ [ "eda4397c88dfcf6d"
2731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800
] ] }, { "id": "eda4397c88dfcf6d", "type": "function", "z": "b19c51e9d4d25a33", "name": "Add data", "func": "msg.payload = {\n command: \"addData\", \n arguments: [\n [msg.payload],\n true\n ],\n returnPromise: true\n }\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 960, "y": 180, "wires": [ [ "d16e9ecebccafc37" ] ] }, { "id": "357d22b7680ff21c", "type": "ui_button", "z": "b19c51e9d4d25a33", "name": "", "group": "6e40c7571e22771c", "order": 2, "width": 0, "height": 0, "passthru": false, "label": "Clear table", "tooltip": "clear all table data", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "", "payloadType": "date", "topic": "", "topicType": "str", "x": 950, "y": 220, "wires": [ [ "f46aca539df9df53" ] ] }, { "id": "f46aca539df9df53", "type": "function", "z": "b19c51e9d4d25a33", "name": "clearData", "func": "\nmsg.payload={\n command:\"clearData\",\n arguments: [],\n returnPromise: true\n}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1121, "y": 220, "wires": [ [ "d16e9ecebccafc37" ] ], "info": "# clear data\n\nunfortunately this command (currently) do not send a promise back! So we have to pass it directly to the table handler" },
28012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835
{ "id": "a5740258089c58ac", "type": "function", "z": "b19c51e9d4d25a33", "name": "function 7", "func": "var exec_log = flow.get('exec_log') || [];\nexec_log.push(msg.payload);\nflow.set(\"exec_log\", exec_log);\nvar log = exec_log.slice(-10,).join(\"<br>\")\nmsg.payload = log;\nreturn msg;\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 600, "y": 40, "wires": [ [ "f4b6096e60252b62" ] ] }, { "id": "521b0d9b132502a5", "type": "subflow:753d1cb452ebd76e", "z": "b19c51e9d4d25a33", "name": "", "x": 330, "y": 480, "wires": [ [ "649dbc02e71571e2", "16b2937ad25f25d2" ] ] } ]