node-redz-wave

How to get the status of door lock in node-red using z-wave


I have tried various different topics and parms to try and get z-wave to return the status of my door lock. I can open and close the lock no problem. My problem is when Node red is restarted, it doesn't know the status of the lock state.


Solution

  • I found the answer and thought I would share it. Here is an export of the nodes:

    [{"id":"ccd35439.32d568","type":"zwave-in","z":"38bb25a8.1f57aa","name":"z-wave Door Lock Status","controller":"93367f67.56b28","x":150,"y":200,"wires":[["385b25b3.262c6a","a8c4e232.ad831"]]},{"id":"a8c4e232.ad831","type":"switch","z":"38bb25a8.1f57aa","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":330,"y":300,"wires":[["b1e45c70.b783b"],["a954b6b9.4d7ab8"],["46e4a223.18712c"],["e702be97.58f7b"],["e1ac058a.c86dc8"],["6b59ab28.819fb4"],["401d406b.4b902"]]},{"id":"b1e45c70.b783b","type":"function","z":"38bb25a8.1f57aa","name":"init nodes","func":"flow.set(\"nodes\", []);\nflow.set(\"scanComplete\", false);\n\n","outputs":"0","noerr":0,"x":573,"y":197,"wires":[]},{"id":"a954b6b9.4d7ab8","type":"function","z":"38bb25a8.1f57aa","name":"add node","func":"var nodes = flow.get(\"nodes\");\nmsg.payload.values = [];\nmsg.payload.ready = false;\nnodes.push(msg.payload);\n\n","outputs":"0","noerr":0,"x":572,"y":231,"wires":[]},{"id":"46e4a223.18712c","type":"function","z":"38bb25a8.1f57aa","name":"add value to node","func":"var nodes = flow.get(\"nodes\");\nvar n = nodes.find(n => n.nodeid == msg.payload.nodeid);\nvar value = msg.payload.value;\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":"0","noerr":0,"x":602,"y":267,"wires":[]},{"id":"e702be97.58f7b","type":"function","z":"38bb25a8.1f57aa","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":"0","noerr":0,"x":580,"y":306,"wires":[]},{"id":"e1ac058a.c86dc8","type":"function","z":"38bb25a8.1f57aa","name":"value changed","func":"var nodes = flow.get(\"nodes\");\nvar node = nodes.find(n => n.nodeid == msg.payload.nodeid);\nvar value = node.values.find(v => v.value_id == msg.payload.value.value_id);\nvalue.value = msg.payload.value.value;\nmsg.topic = \"value_changed\";\nmsg.payload = \"Value Changed\";\nreturn msg;","outputs":"1","noerr":0,"x":588,"y":347,"wires":[["7c6a10c3.4d92c"]]},{"id":"6b59ab28.819fb4","type":"function","z":"38bb25a8.1f57aa","name":"node ready","func":"var nodes = flow.get(\"nodes\");\nvar n = nodes.find(n => n.nodeid == msg.payload.nodeid);\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":580,"y":386,"wires":[]},{"id":"401d406b.4b902","type":"function","z":"38bb25a8.1f57aa","name":"scan complete","func":"var nodes = flow.get(\"nodes\");\nflow.set(\"scanComplete\", true);\nmsg.topic = \"scan_complete\";\nmsg.payload = \"Scan Complete\";\nreturn msg;","outputs":"1","noerr":0,"x":589,"y":424,"wires":[["7c6a10c3.4d92c"]]},{"id":"93367f67.56b28","type":"zwave-controller","z":"","port":"/dev/cu.usbmodem1411","driverattempts":"3","pollinterval":"10000","allowunreadyupdates":false,"networkkey":"0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01","logging":"full"}]
    

    You will notice that two nodes, value changed and scan complete, have outputs. Here you can direct to a function to extract whatever info you wish from the z-wave nodes by reading the flow variable "nodes". For example, I get the battery level and lock state as follows:

    var nodes = flow.get("nodes");
    var node = nodes.find(n => n.nodeid == "2");
    var value = node.values.find(v => v.value_id == "2-128-1-0");
    var batLevel = value.value + "%";
    value = node.values.find(v => v.value_id == "2-98-1-0");
    var lockState = value.value;
    return [{payload: batLevel}, {payload: {"nodeid":  2, "cmdclass":  98, "value":  lockState}}];
    

    This will return batLevel through one output and a json to the lock switch which is used to trigger the lock when the switch is changed (I disable passthru and just use this to change the switch).

    For more details, see the example here: https://gist.github.com/robertsLando/41ae75dbfbe6465d5cf40248e2500e0a