Custom implementation of Open-Zwave-Control-Panel (https://github.com/OpenZWave/open-zwave-control-panel) using node-contrib-openzwave (https://github.com/OpenZWave/node-red-contrib-openzwave) and node-red-dashboard.
Last active
May 6, 2023 08:58
-
-
Save robertsLando/41ae75dbfbe6465d5cf40248e2500e0a to your computer and use it in GitHub Desktop.
Z-Wave Control Panel with node-red-dashboard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"id":"c8fe91b8.daa3","type":"tab","label":"Flow 2"},{"id":"5b1e3f38.50856","type":"zwave-in","z":"c8fe91b8.daa3","name":"read_zwave","controller":"93bf10ea.1c4c3","x":194,"y":180,"wires":[["ee5ce307.9c417","c46bb234.40dcc"]]},{"id":"c46bb234.40dcc","type":"debug","z":"c8fe91b8.daa3","name":"","active":false,"console":"false","complete":"false","x":416,"y":74,"wires":[]},{"id":"ee5ce307.9c417","type":"switch","z":"c8fe91b8.daa3","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"zwave: driver ready","vt":"str"},{"t":"eq","v":"zwave: node added","vt":"str"},{"t":"eq","v":"zwave: value added","vt":"str"},{"t":"eq","v":"zwave: notification","vt":"str"},{"t":"eq","v":"zwave: value changed","vt":"str"},{"t":"eq","v":"zwave: node ready","vt":"str"},{"t":"eq","v":"zwave: scan complete","vt":"str"}],"checkall":"true","outputs":7,"x":455,"y":180,"wires":[["2bbed007.b1598"],["f439bf74.64e93"],["5dd0df27.0fddb"],["c1c7ad30.1fe2"],["1000fdaf.d177e2"],["592813f3.15708c"],["b9cbd4d9.694eb8"]]},{"id":"2bbed007.b1598","type":"function","z":"c8fe91b8.daa3","name":"init nodes","func":"flow.set(\"nodes\", []);\nflow.set(\"scanComplete\", false);\n\n","outputs":"0","noerr":0,"x":698,"y":77,"wires":[]},{"id":"f439bf74.64e93","type":"function","z":"c8fe91b8.daa3","name":"add node","func":"var nodes = flow.get(\"nodes\");\nmsg.payload.values = [];\nmsg.payload.ready = false;\n\nnodes.push(msg.payload);\n\n","outputs":"0","noerr":0,"x":697,"y":111,"wires":[]},{"id":"5dd0df27.0fddb","type":"function","z":"c8fe91b8.daa3","name":"add value to node","func":"var nodes = flow.get(\"nodes\");\n\nvar n = nodes.find(n => n.nodeid == msg.payload.nodeid);\n\nvar value = msg.payload.value;\n\nn.values.push(value);\n\n//optionally send enablepool \nif(value.label == \"Temperature\"){\n node.send({topic: \"enablePool\", payload: {\"args\": [value.nodeid, value.cmdclass]}});\n}\n\n\n","outputs":"1","noerr":0,"x":727,"y":147,"wires":[[]]},{"id":"c1c7ad30.1fe2","type":"function","z":"c8fe91b8.daa3","name":"notification","func":"var nodes = flow.get(\"nodes\");\nvar nodeid = msg.payload.nodeid;\nvar n = nodes.find(n => n.nodeid == nodeid);\n\nswitch (msg.payload.notification) {\n case 0:\n console.log('node%d: message complete', nodeid);\n break;\n case 1:\n console.log('node%d: timeout', nodeid);\n break;\n case 2:\n console.log('node%d: nop', nodeid);\n break;\n case 3:\n console.log('node%d: node awake', nodeid);\n break;\n case 4:\n console.log('node%d: node sleep', nodeid);\n break;\n case 5:\n console.log('node%d: node dead', nodeid);\n n.ready = false;\n node.send({topic: \"node_status\", nodeid: nodeid, payload: false});\n break;\n case 6:\n console.log('node%d: node alive', nodeid);\n n.ready = true;\n node.send({topic: \"node_status\", nodeid: nodeid, payload: true});\n break;\n }\n","outputs":1,"noerr":0,"x":705,"y":186,"wires":[[]]},{"id":"1000fdaf.d177e2","type":"function","z":"c8fe91b8.daa3","name":"value changed","func":"var nodes = flow.get(\"nodes\");\n\nvar node = nodes.find(n => n.nodeid == msg.payload.nodeid);\n\nvar value = node.values.find(v => v.value_id == msg.payload.value.value_id);\n\nvalue.value = msg.payload.value.value;\n\n\nmsg.payload = value;\nmsg.topic = \"value_changed\";\n\nreturn msg;","outputs":"1","noerr":0,"x":713,"y":227,"wires":[["3c7afb39.71dd74"]]},{"id":"592813f3.15708c","type":"function","z":"c8fe91b8.daa3","name":"node ready","func":"var nodes = flow.get(\"nodes\");\n\nvar n = nodes.find(n => n.nodeid == msg.payload.nodeid);\n\nn.ready = true;\nn.type = msg.payload.nodeinfo.type;\n\n/* NODEINFO\n{\"manufacturer\":\"Qubino\",\"manufacturerid\":\"0x0159\",\"product\":\"ZMNHKDx Flush Heat and Cool thermostat\",\"producttype\":\"0x0005\",\"productid\":\"0x0052\",\"type\":\"Thermostat HVAC\",\"name\":\"\",\"loc\":\"\"}\n*/","outputs":"0","noerr":0,"x":705,"y":266,"wires":[]},{"id":"b9cbd4d9.694eb8","type":"function","z":"c8fe91b8.daa3","name":"scan complete","func":"var nodes = flow.get(\"nodes\");\n\nflow.set(\"scanComplete\", true);\n\nreturn [{payload:{}, topic: \"writeConfig\"}, {payload: nodes, topic: \"init\"}];","outputs":"2","noerr":0,"x":714,"y":304,"wires":[[],[]]},{"id":"cd817b4e.3f49b8","type":"link in","z":"c8fe91b8.daa3","name":"zwaveWrite","links":["59251ba3.b3c2b4","bea6132.04aacf","177b2fe1.737a1"],"x":975,"y":480,"wires":[["47d342b5.7563cc"]]},{"id":"47d342b5.7563cc","type":"zwave-out","z":"c8fe91b8.daa3","name":"write","controller":"93bf10ea.1c4c3","x":1090,"y":480,"wires":[[]]},{"id":"d2183a6d.1b43e8","type":"ui_dropdown","z":"c8fe91b8.daa3","name":"","label":"Nodes","place":"Select a node","group":"91eff83b.4842a8","order":0,"width":0,"height":0,"passthru":false,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"","x":340,"y":480,"wires":[["84c3d05.479453"]]},{"id":"59fc0fa2.398dc","type":"function","z":"c8fe91b8.daa3","name":"parse options","func":"var nodes = msg.payload;\nvar options = [];\n\nfor(var i=0;i<nodes.length; i++){\n var n = nodes[i];\n var tmp = {};\n var title = n.nodeid +\": \"+n.type;\n tmp[title] = n.nodeid;\n options.push(tmp);\n}\n\nmsg.options = options;\n\nreturn msg;","outputs":1,"noerr":0,"x":160,"y":480,"wires":[["d2183a6d.1b43e8"]]},{"id":"84c3d05.479453","type":"function","z":"c8fe91b8.daa3","name":"","func":"var n = flow.get(\"nodes\").find(n => n.nodeid == msg.payload);\n\nmsg.payload = n.values;\n\nmsg.topic = \"init\";\n\nreturn msg;","outputs":1,"noerr":0,"x":485,"y":480,"wires":[["a9ba8c06.0593c"]]},{"id":"a9ba8c06.0593c","type":"ui_template","z":"c8fe91b8.daa3","group":"d8a503ba.8c0ad","name":"config","order":0,"width":"20","height":"20","format":"<style>\nmd-tooltip .md-content {\n height: auto !important;\n max-width: 200px !important;\n font-size: 13px !important;\n}\n\nmd-tooltip {\n height: auto !important;\n max-width: 200px !important;\n font-size: 13px !important;\n overflow: visible !important;\n white-space: normal !important;\n}\n\nmd-tooltip ._md-content {\n height: auto !important;\n max-width: 200px !important;\n font-size: 13px !important;\n}\n</style>\n\n<div ng-repeat=\"v in values\">\n <label>\n {{v.label}}\n <md-tooltip ng-if=\"v.help\" md-direction=\"right\">{{v.help}}</md-tooltip>\n <select ng-if=\"v.values\" id=\"{{v.value_id}}\" ng-model=\"v.value\" ng-change=\"updateValue(v)\" ng-options=\"value as value for (key , value) in v.values\">\n </select>\n <div ng-if=\"!v.values\">\n <input type=\"text\" id=\"{{v.value_id}}\" ng-model=\"v.value\" ng-disabled=\"v.read_only\">\n <button ng-if=\"!v.read_only\" ng-click=\"updateValue(v)\">Submit</button>\n </div>\n </label>\n</div>\n\n<script>\n(function(scope) {\n \n scope.values = [];\n scope.send({topic:\"load\"});\n \n scope.updateValue = function(v){\n var newValue = $('#'+v.value_id).val();\n if(v.values) newValue = newValue.split(':')[1];\n var cmd = {};\n cmd.nodeid = v.node_id;\n cmd.cmdclass = v.class_id;\n cmd.instance = v.instance;\n cmd.cmdidx = v.index;\n cmd.value = newValue;\n v.value = \"\"; //to check updating\n scope.send({payload: cmd, topic: \"setValue\"});\n }\n \n scope.$watch('msg', function (msg) { \n if(msg){\n switch(msg.topic){\n case \"init\":\n if(scope.values.length == 0)\n scope.values = msg.payload;\n break;\n case \"value_changed\":\n var value = scope.values.find(n => n.value_id == msg.payload.value_id);\n if(value)\n value.value = msg.payload.value;\n break;\n }\n }\n }); \n\n})(scope);\n\n\n</script>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":625,"y":480,"wires":[["30212724.e08828"]]},{"id":"30212724.e08828","type":"switch","z":"c8fe91b8.daa3","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"setValue","vt":"str"},{"t":"eq","v":"load","vt":"str"}],"checkall":"true","outputs":2,"x":767,"y":480,"wires":[["59251ba3.b3c2b4"],["85f1bb2a.ed8278"]]},{"id":"59251ba3.b3c2b4","type":"link out","z":"c8fe91b8.daa3","name":"writeConfig","links":["cd817b4e.3f49b8"],"x":876,"y":480,"wires":[]},{"id":"a7c360ff.c8e3","type":"link in","z":"c8fe91b8.daa3","name":"configs","links":["3c7afb39.71dd74"],"x":565,"y":420,"wires":[["a9ba8c06.0593c"]]},{"id":"85f1bb2a.ed8278","type":"change","z":"c8fe91b8.daa3","name":"load","rules":[{"t":"set","p":"payload","pt":"msg","to":"nodes","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":560,"wires":[["59fc0fa2.398dc"]]},{"id":"3c7afb39.71dd74","type":"link out","z":"c8fe91b8.daa3","name":"value_changed","links":["a7c360ff.c8e3"],"x":857,"y":227,"wires":[]},{"id":"185c5e39.6f0d12","type":"inject","z":"c8fe91b8.daa3","name":"","topic":"","payload":"nodes","payloadType":"flow","repeat":"","crontab":"","once":false,"x":120,"y":280,"wires":[["589071d.12e7d9"]]},{"id":"589071d.12e7d9","type":"debug","z":"c8fe91b8.daa3","name":"","active":true,"console":"false","complete":"false","x":305,"y":280,"wires":[]},{"id":"8afcb2c1.c6946","type":"inject","z":"c8fe91b8.daa3","name":"healNetwork","topic":"healNetwork","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"x":132,"y":327,"wires":[["bea6132.04aacf"]]},{"id":"bea6132.04aacf","type":"link out","z":"c8fe91b8.daa3","name":"healNetwork","links":["cd817b4e.3f49b8"],"x":282,"y":327,"wires":[]},{"id":"171a9cd4.bb6a53","type":"inject","z":"c8fe91b8.daa3","name":"softReset","topic":"softReset","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"x":120,"y":371,"wires":[["177b2fe1.737a1"]]},{"id":"177b2fe1.737a1","type":"link out","z":"c8fe91b8.daa3","name":"softReset","links":["cd817b4e.3f49b8"],"x":281,"y":371,"wires":[]},{"id":"93bf10ea.1c4c3","type":"zwave-controller","z":"","port":"/dev/ttyACM0","driverattempts":"3","pollinterval":"10000","allowunreadyupdates":false,"logging":"full"},{"id":"91eff83b.4842a8","type":"ui_group","z":"","name":"Seleziona nodo","tab":"f990693c.63b0e8","disp":true,"width":"6"},{"id":"d8a503ba.8c0ad","type":"ui_group","z":"","name":"Config","tab":"f990693c.63b0e8","disp":true,"width":"20"},{"id":"f990693c.63b0e8","type":"ui_tab","z":"","name":"Configurazione","icon":"dashboard"}] |
very good flow! Helped me a lot to understand z-wave.
I have the description of this command below in order to get a report from node 3 (devolo meter switch)
[(https://www.devolo.de/fileadmin/Web-Content/DE/Products/HC_Schalt-_und_Messsteckdose_2.0/Documents/DE/Full_Manual_Home_Control_Schalt_Messsteckdose_V2_0317_DE.pdf)]
Meter Get Command: [Command Class Meter, Meter Get, Scale =0x02(W)]
What do I have to put into your report field to get the report?
If someone is interested in a zwave control panel nodeJS based that also works as zwave to MQTT gateway check my proejct: Zwave2MQTT
very nice flow! is it posible to show the parameter ID in the node's config? So we can found the right parameter from the tec. spec.
Thank you.
I suggest you to use Zwave2mqtt
…---
Daniel - Software Engineer
Support me at:
Github sponsors
On 29 Apr 2020, at 18:21, Hubertus ***@***.***> wrote:
***@***.*** commented on this gist.
very nice flow! is it posible to show the parameter ID in the node's config? So we can found the right parameter from the tec. spec.
Thank you.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
Thank you for your answer – bu how can i used it under Noder-Red?
From: Daniel Lando <[email protected]>
Sent: Wednesday, April 29, 2020 7:05 PM
To: robertsLando <[email protected]>
Cc: Hubertus <[email protected]>; Mention <[email protected]>
Subject: Re: robertsLando/README.md
@robertsLando commented on this gist.
_____
I suggest you to use Zwave2mqtt
---
Daniel - Software Engineer
Support me at:
Github sponsors
On 29 Apr 2020, at 18:21, Hubertus ***@***.*** ***@***.***> > wrote:
***@***.*** commented on this gist.
very nice flow! is it posible to show the parameter ID in the node's config? So we can found the right parameter from the tec. spec.
Thank you.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <https://gist.github.com/41ae75dbfbe6465d5cf40248e2500e0a#gistcomment-3275212> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD6XWMVFN6SUUMRDGRR374LRPBM3PANCNFSM4MT3Y46A> . <https://github.com/notifications/beacon/AD6XWMRXCIARL3IZOQR657LRPBM3PA5CNFSM4MT3Y46KYY3PNVWWK3TUL52HS4DFVNDWS43UINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAGH44Y.gif>
Simply use it and catch/send messages to it using mqtt nodes :)
…---
Daniel - Software Engineer
Support me at:
Github sponsors
On 1 May 2020, at 18:42, Hubertus ***@***.***> wrote:
***@***.*** commented on this gist.
Thank you for your answer – bu how can i used it under Noder-Red?
From: Daniel Lando ***@***.***>
Sent: Wednesday, April 29, 2020 7:05 PM
To: robertsLando ***@***.***>
Cc: Hubertus ***@***.***>; Mention ***@***.***>
Subject: Re: robertsLando/README.md
@robertsLando commented on this gist.
_____
I suggest you to use Zwave2mqtt
---
Daniel - Software Engineer
Support me at:
Github sponsors
> On 29 Apr 2020, at 18:21, Hubertus ***@***.*** ***@***.***> > wrote:
>
> ***@***.*** commented on this gist.
> very nice flow! is it posible to show the parameter ID in the node's config? So we can found the right parameter from the tec. spec.
> Thank you.
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub, or unsubscribe.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <https://gist.github.com/41ae75dbfbe6465d5cf40248e2500e0a#gistcomment-3275212> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD6XWMVFN6SUUMRDGRR374LRPBM3PANCNFSM4MT3Y46A> . <https://github.com/notifications/beacon/AD6XWMRXCIARL3IZOQR657LRPBM3PA5CNFSM4MT3Y46KYY3PNVWWK3TUL52HS4DFVNDWS43UINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAGH44Y.gif>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice flow - it really jump started my understanding of node-red and this zwave module. A few notes though to help others in the future:
-- Use "lsusb -v | less" to find your device. Look specifically for the vendor and product ID.
-- For the Aeotec Gen5 Stick, your udev rule (to be placed in /etc/udev/rules.d/99-my.rules) would be: SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200",
SYMLINK+="zwave"