Simple UI for zigbee2mqtt
This is a very simple UI for zigbee2mqtt that allows to toggle pairing, view device info, rename and remove devices.
[{"id":"5f4d217a.0f172","type":"subflow","name":"dashboard","info":"A simple zigbee2mqtt dashboard, it takes mqtt input and gives mqtt output.","category":"zigbee2mqtt","in":[{"x":100,"y":180,"wires":[{"id":"f628b70d.9f2738"}]}],"out":[{"x":240,"y":180,"wires":[{"id":"cb2ccc7d.61c8b","port":0}]}],"inputLabels":["mqtt"],"outputLabels":["mqtt"],"icon":"node-red-dashboard/ui_form.png"},{"id":"8c692bc0.8bc66","type":"ui_switch","z":"5f4d217a.0f172","name":"permit_join","label":"Pairing","tooltip":"Enable joining of new devices","group":"dbfdd2ba.174fa","order":1,"width":"4","height":"1","passthru":false,"decouple":"true","topic":"zigbee2mqtt/bridge/config/permit_join","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":390,"y":120,"wires":[["f6fad897.0d1138"]]},{"id":"39908e09.b5ff12","type":"function","z":"5f4d217a.0f172","name":"update_zigbee_ui","func":"var mqtt = null;\nvar permit_join = null;\nvar log_level = null;\nvar devices = null;\n\n// decode json payload\nif (typeof msg.payload == \"string\") {\n try {\n msg.payload = JSON.parse(msg.payload);\n } catch (e) {\n // payload was not json\n }\n}\n\n// route messages\nswitch (msg.topic) {\n case \"zigbee2mqtt/bridge/state\":\n if (msg.payload == \"online\") {\n mqtt = {\n \"topic\": \"zigbee2mqtt/bridge/config/devices/get\",\n \"payload\": true,\n };\n }\n break;\n case \"zigbee2mqtt/bridge/config\":\n permit_join = {\n \"payload\": msg.payload.permit_join,\n };\n log_level = {\n \"payload\": msg.payload.log_level,\n };\n break;\n case \"zigbee2mqtt/bridge/config/devices\":\n var devices = {\"options\": []}\n \n for (var i = 0; i < msg.payload.length; i++) {\n if (msg.payload[i].type == \"Coordinator\")\n continue;\n \n var opt = {};\n opt[msg.payload[i].friendly_name] =\n msg.payload[i];\n devices.options.push(opt);\n }\n break;\n}\nreturn [\n mqtt,\n permit_join,\n log_level,\n devices,\n];","outputs":4,"noerr":0,"x":170,"y":100,"wires":[["3561b67a.4556c2"],["8c692bc0.8bc66"],["cbdb39c3.5a36a"],["64a1345a.0b84bc"]],"outputLabels":["mqtt","permit_join","log_level","devices"],"icon":"node-red/switch.png"},{"id":"cbdb39c3.5a36a","type":"ui_dropdown","z":"5f4d217a.0f172","name":"log_level","label":"Log Level","tooltip":"Select the log level for zigbee2mqtt","place":"Select option","group":"dbfdd2ba.174fa","order":2,"width":"6","height":"1","passthru":false,"options":[{"label":"Info","value":"info","type":"str"},{"label":"Debug","value":"debug","type":"str"},{"label":"Warn","value":"warn","type":"str"},{"label":"Error","value":"error","type":"str"}],"payload":"","topic":"zigbee2mqtt/bridge/config/log_level","x":380,"y":160,"wires":[["76997f62.c76688"]]},{"id":"64a1345a.0b84bc","type":"ui_dropdown","z":"5f4d217a.0f172","name":"device","label":"","tooltip":"Select a device","place":"Device","group":"dbfdd2ba.174fa","order":3,"width":"8","height":"1","passthru":false,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"","x":370,"y":200,"wires":[["451ecf29.48062"]]},{"id":"f6fad897.0d1138","type":"link out","z":"5f4d217a.0f172","name":"permit_join","links":["cb2ccc7d.61c8b"],"x":515,"y":120,"wires":[]},{"id":"76997f62.c76688","type":"link out","z":"5f4d217a.0f172","name":"log_level","links":["cb2ccc7d.61c8b"],"x":515,"y":160,"wires":[]},{"id":"451ecf29.48062","type":"function","z":"5f4d217a.0f172","name":"store_device_cur","func":"flow.set(\"device\", msg.payload.friendly_name);\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":200,"wires":[["80ac330.644f25"]],"outputLabels":["device_info","remove_confirm"]},{"id":"a388679e.33cb9","type":"ui_button","z":"5f4d217a.0f172","name":"remove_device","group":"dbfdd2ba.174fa","order":4,"width":"1","height":"1","passthru":false,"label":"","tooltip":"Remove device from network","color":"","bgcolor":"red","icon":"remove_circle","payload":"device","payloadType":"flow","topic":"Remove device?","x":400,"y":360,"wires":[["9fbc1102.297598"]]},{"id":"8433df10.19f8f8","type":"ui_button","z":"5f4d217a.0f172","name":"refresh_devices","group":"dbfdd2ba.174fa","order":5,"width":"1","height":"2","passthru":false,"label":"","tooltip":"Refresh devices information","color":"","bgcolor":"gray","icon":"update","payload":"true","payloadType":"bool","topic":"zigbee2mqtt/bridge/config/devices/get","x":400,"y":280,"wires":[["12983b43.e0385d"]]},{"id":"12983b43.e0385d","type":"link out","z":"5f4d217a.0f172","name":"refresh_devices","links":["cb2ccc7d.61c8b"],"x":515,"y":280,"wires":[]},{"id":"80ac330.644f25","type":"ui_template","z":"5f4d217a.0f172","group":"dbfdd2ba.174fa","name":"device_info","order":8,"width":"10","height":"4","format":"<div>\n <h3>Device Information</h3>\n <div><label style=\"width: 8em; display: inline-block;\">Name:</label> <span ng-bind-html=\"msg.payload.friendly_name\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">IEEE Address:</label> <span ng-bind-html=\"msg.payload.ieeeAddr\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">Type:</label> <span ng-bind-html=\"msg.payload.type\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">Manufacturer :</label> <span ng-bind-html=\"msg.payload.manufName\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">Model:</label> <span ng-bind-html=\"msg.payload.modelId\"></span> <span style=\"font-weight: bold;\" ng-bind-html=\"msg.payload.model\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">Power Source:</label> <span ng-bind-html=\"msg.payload.powerSource\"></span></div>\n <div><label style=\"width: 8em; display: inline-block;\">Firmware:</label> <span ng-bind-html=\"msg.payload.swBuildId\"></span></div>\n</div>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":790,"y":200,"wires":[[]]},{"id":"5e350f6e.d276a","type":"link out","z":"5f4d217a.0f172","name":"execute_remove","links":["cb2ccc7d.61c8b"],"x":1075,"y":360,"wires":[]},{"id":"fdc4f093.86bd18","type":"ui_button","z":"5f4d217a.0f172","name":"rename_device","group":"dbfdd2ba.174fa","order":7,"width":"1","height":"1","passthru":false,"label":"","tooltip":"Rename device","color":"","bgcolor":"orange","icon":"swap_horiz","payload":"device_rename","payloadType":"flow","topic":"zigbee2mqtt/bridge/config/rename","x":400,"y":320,"wires":[["963b4d7c.c160e8"]]},{"id":"ed34ee80.b37628","type":"ui_text_input","z":"5f4d217a.0f172","name":"device_new","label":"","tooltip":"New device name","group":"dbfdd2ba.174fa","order":6,"width":"8","height":"1","passthru":false,"mode":"text","delay":300,"topic":"","x":390,"y":240,"wires":[["44136496.73d37c"]]},{"id":"44136496.73d37c","type":"function","z":"5f4d217a.0f172","name":"store_device_new","func":"var rename_payload = null;\nvar name_old = flow.get(\"device\");\nvar name_new = msg.payload;\n\nif (name_old != name_new && name_new !== \"\") {\n rename_payload = {\n \"old\": flow.get(\"device\"),\n \"new\": msg.payload,\n }\n}\n\nflow.set(\"device_rename\", rename_payload);","outputs":1,"noerr":0,"x":590,"y":240,"wires":[[]]},{"id":"95d7d649.84332","type":"link out","z":"5f4d217a.0f172","name":"execute_rename::mqtt","links":["cb2ccc7d.61c8b"],"x":1075,"y":320,"wires":[]},{"id":"963b4d7c.c160e8","type":"function","z":"5f4d217a.0f172","name":"execute_rename","func":"var msg_rename = msg;\nvar msg_update = {};\nvar msg_clear = {};\n\nif (msg_rename.payload !== null) {\n // update devices\n msg_update[\"topic\"] = \"zigbee2mqtt/bridge/config/devices/get\";\n msg_update[\"payload\"] = true; \n \n // clear rename_device field\n msg_clear[\"payload\"] = \"\";\n \n // clear flow fields\n flow.set(\"device\", null);\n flow.set(\"rename_payload\", null);\n} else {\n msg_rename = null;\n msg_update = null;\n msg_clear = null;\n}\n\n\nreturn [[msg_rename, msg_update], msg_clear];","outputs":2,"noerr":0,"x":580,"y":320,"wires":[["25f65aa0.304506"],["369d2482.8a096c"]],"outputLabels":["mqtt","ui_clear"],"icon":"node-red/switch.png"},{"id":"25f65aa0.304506","type":"delay","z":"5f4d217a.0f172","name":"","pauseType":"rate","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":970,"y":320,"wires":[["95d7d649.84332"]]},{"id":"4d3185f4.a3964c","type":"link in","z":"5f4d217a.0f172","name":"device_new","links":["369d2482.8a096c"],"x":275,"y":240,"wires":[["ed34ee80.b37628"]]},{"id":"369d2482.8a096c","type":"link out","z":"5f4d217a.0f172","name":"execute_rename::ui_clear","links":["4d3185f4.a3964c"],"x":695,"y":340,"wires":[]},{"id":"4a724b8.0a730b4","type":"function","z":"5f4d217a.0f172","name":"execute_remove","func":"var msg_remove = {};\nvar msg_update = {};\n\nif (msg.payload == \"yes\") {\n // remove device\n msg_remove[\"topic\"] = \"zigbee2mqtt/bridge/config/remove\";\n msg_remove[\"payload\"] = flow.get(\"device\"); \n \n // update devices\n msg_update[\"topic\"] = \"zigbee2mqtt/bridge/config/devices/get\";\n msg_update[\"payload\"] = true; \n} else {\n msg_remove = null;\n msg_update = null;\n}\n\nreturn [[msg_remove, msg_update]];","outputs":1,"noerr":0,"x":800,"y":360,"wires":[["e8377aa3.6bd3d8"]],"outputLabels":["mqtt"],"icon":"node-red/switch.png"},{"id":"e8377aa3.6bd3d8","type":"delay","z":"5f4d217a.0f172","name":"","pauseType":"rate","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":970,"y":360,"wires":[["5e350f6e.d276a"]]},{"id":"982cddca.94bf88","type":"inject","z":"5f4d217a.0f172","name":"networkmap","topic":"zigbee2mqtt/bridge/networkmap","payload":"graphviz","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":390,"y":440,"wires":[["ff04d8a2.a730a"]]},{"id":"ff04d8a2.a730a","type":"link out","z":"5f4d217a.0f172","name":"networkmap","links":["cb2ccc7d.61c8b"],"x":515,"y":440,"wires":[]},{"id":"841125cb.87be28","type":"link out","z":"5f4d217a.0f172","name":"update_zigbee_ui","links":["cb2ccc7d.61c8b"],"x":515,"y":80,"wires":[]},{"id":"3561b67a.4556c2","type":"delay","z":"5f4d217a.0f172","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":380,"y":80,"wires":[["841125cb.87be28"]]},{"id":"75a9e30f.cc4b54","type":"link in","z":"5f4d217a.0f172","name":"update_zigbee_ui","links":["f628b70d.9f2738"],"x":35,"y":100,"wires":[["39908e09.b5ff12"]]},{"id":"f628b70d.9f2738","type":"link out","z":"5f4d217a.0f172","name":"mqtt_in","links":["75a9e30f.cc4b54"],"x":175,"y":200,"wires":[]},{"id":"cb2ccc7d.61c8b","type":"link in","z":"5f4d217a.0f172","name":"mqtt_out","links":["12983b43.e0385d","5e350f6e.d276a","76997f62.c76688","841125cb.87be28","95d7d649.84332","f6fad897.0d1138","ff04d8a2.a730a"],"x":175,"y":160,"wires":[[]]},{"id":"9fbc1102.297598","type":"ui_toast","z":"5f4d217a.0f172","position":"dialog","displayTime":"3","highlight":"","outputs":1,"ok":"no","cancel":"yes","topic":"","name":"confirm_remove","x":580,"y":360,"wires":[["4a724b8.0a730b4"]]},{"id":"dbfdd2ba.174fa","type":"ui_group","z":"","name":"zigbee","tab":"f75e2df.773c85","disp":true,"width":"10","collapse":false},{"id":"f75e2df.773c85","type":"ui_tab","z":"","name":"System","icon":"settings","order":1,"disabled":false,"hidden":false},{"id":"aa715df3.5fcd1","type":"subflow:5f4d217a.0f172","z":"84119c5a.51863","name":"zigbee2mqtt_ui","x":320,"y":200,"wires":[["a0aea2fa.a70388"]]}]