One week in. First impressions

So, I’m one week in and thought I would give some feedback on how it is going for me.

Went through the set up process. - Didn’t find it too daunting.

Set up backups. - Piece of cake.

Installed/initialised zigbee2mqtt. - All was OK until I changed the channel. Needed support to get out of hole but this has now been documented in the documents.
(BTW my zigbee stick is running old firmware and people have shared posts on how to do this but I’m not comfortable to go ahead and do this. Via a UI would be good for me. :slight_smile: ).

Installed 3 zigbee battery devices. Xiaomi/Sonoff/Aqara. All 3 have remained solid and connected ok.

Installed node-red. - This is where my fun started. I just couldn’t get my head round it. I must admit I thought I would never get there. Asked a couple of questions and things slowly started to fall into place.
Here is a flow that is working OK for me and I am more than chuffed that I got it work. Took some playing with but I got there.

EN Suite

Defined about 15 mostly simple flows and I feel that things are running quicker than webCoRE on HE but not exceptionally quicker.

All of my devices that were on HE (3 hubs) remain on HE and I am using MakerAPI.
I intend to leave everything on HE for the time being as all I have to do is power down CC and enable my pistons and everything will run as it did pre-CC.

What do I feel I need.
Virtual Devices. - I rely extensively on virtual devices as I have a house full of LightwaveRF gear that can only be hooked up to HE via an RPi connection to my LightwaveRF hub via my local lan.

What do I need to get my head round.
Still unsure of what messages etc. I should be using in my nodes. I just play until something works.
Is there such a thing as global variables in NR or CC.
Dashboards and graphs.

I haven’t ventured into zwave yet as I haven’t got a stick yet or any spare zwave devices to connect anyway.

A good UI. Until we have a good UI that will allow us to do things through the UI instead of having to type in commands through command line, I feel you will have a limited audience for CC. (I know we are in early days but just thought I would mention it).

Also, I seem to remember in the dim and distant past, I may have made this up in my tiny mind BTW, that CC could also be used as some sort of VPN server to allow us secure access in from the public domain.

Well, there’s my current feedback that I thought I would share and welcome any comments/thoughts.

The final paragraph, am happy with things so far.
As far as it goes, YES. :+1: :+1: :+1: :grin: :grin: :grin: I appreciate we are in beta and look forward to future developments.

EDIT: I forgot to mention how responsive (and quick BTW) the CC team and beta testers have been. Thankyou and keep up the good work. :slight_smile:

7 Likes

Because the devices are still paired to the HE it is still acting as a bottle neck speed wise. Removing the processing from HE and moving it to CORE is why you notice a bit of an increase but not a major one. With the exception of the flows for granny which rely on HE for virtual devices tied to google so she can use voice commands, execution time is usually sub 100ms.

I don’t know anything about that myself, but there are node red nodes related to lightwaveRF, and i came across several articles about integrating it into node red and using them with mqtt. Maybe someone else has some info on them.

Check out the debug/help menu in NR. If you click a node it will usually show you to details about what that node expects in terms of message format.

I believe you are thinking about wire-guard which is included on CORE, but doesnt not have documentation written yet aside from the base command (oll-wireguard)

1 Like

Can I make a suggestion to take a look at the link in/out nodes? They can clean-up your flows a lot by removing all the lines that go allover the place. I even use them to from one flow tab to another and keep things clean.

1 Like

You should check out junctions in NR3, for me, now that they exist the link nodes only really get used for going between tabs or over large distances.

1 Like

Only 1 week in for NR. Didn’t know what they did tbh.
I will have a delve.

Thank you for the first impressions post :slight_smile:

What is it that you’re running on your RPi for this? It may very well be something which could run directly on CORE if you so wish.

Yes, there are many ways, but sticking to NR there’s globals which can easily be set using the change node and selecting global from the dropdown. I’m sure someone will point you to more detailed instructions.

TBH I cannot remember. I set this up when I was running on ST. Probably back in 2016/17.
Just followed instructions and hey presto it worked.
I think it was something to do with UDP and a node.js server but cannot be sure.
I just followed the instructions and set it up on my RPi.
Either way you still need to set the details for the device.
All I do is set up a virtual device using a user driver. I then define the LWRF’s hub and RPi’s IP addresses and the device details that are assigned by the LWRF hub. Then PFM takes over.
Here is a screenshot of device set up to give you a feel of the virtual device.

A video is here for the set up also.

Looks like there’s a HA integration for that you may want to try out.
Can’t speak for CORE long-term, but that’d get you up & running now if it works

At a quick glance, if it is utilising the LWRF API then I would assume it is cloud based.
My current set up is completely local.

“This API outlines the local command protocols currently in use in the LightwaveRF system”

From the link to api.lightwaverf.com used for that integration, it appears to be the same UDP protocol as your existing HE setup :man_shrugging: Those devices don’t exist here in the states, I don’t have a clue just trying to help out :sweat_smile:

I’m sure the CORE team can work something up given the existing nodejs stuff you’re using

2 Likes

I took the opportunity to show how a custom UDP protocol subflow can be implemented. As an example I used the LightwaveRF UDP protocol.
@bobbles This may be complicated to setup, if you want to try it and need some help I’d be happy to setup a Teams meeting :slight_smile:
With this flow no external service or anything except the subflow and other nodes in NR are needed, there may still be bugs, especially if the API docs are not correct or your firmware version is not new enough to use JSON output and unicast UDP packets. So far only “Lighting & Power” is implemented, but it would be easy to add additional parts of the API.

The following portmapping needs to be added to the NR config (sudo nano /etc/core/oll-node-red.conf):

PORT_MAP+=("CORE_IP_HERE:9761:9761/udp")

Some screenshots:


The flow itself is fairly large:

[{"id":"1dba3faa997ebb49","type":"subflow","name":"LightwaveRF Command","info":"For API documentation, see here:\nhttp://api.lightwaverf.com/\n\nTo override room, set msg.room to a number between 1 and 15.\n\nTo override device, set msg.device to a number between 0 and 16. 0 = all devices for those commands which support that.\n\nTo override on/off or open/close, send a msg.payload with a boolean.\n\nTo override dimlevel, set msg.dimlevel to a number between 0 and 100.\n\nTo override colour, set msg.colour to a number between 1 and 20.\n\nTo override mood, set msg.mood to a number between 1 and 5.\n\nTo override the command, set msg.command to an expected string (see the msg.payload to API call function for details).\n","category":"","in":[{"x":60,"y":40,"wires":[{"id":"413a2b6b423a69de"}]}],"out":[{"x":960,"y":100,"wires":[{"id":"4fe8355503263fe6","port":0}]}],"env":[{"name":"room","type":"num","value":"","ui":{"label":{"en-US":"Room"},"type":"spinner","opts":{"min":0,"max":15}}},{"name":"device","type":"num","value":"","ui":{"label":{"en-US":"Device"},"type":"spinner","opts":{"min":0,"max":16}}},{"name":"command","type":"str","value":"","ui":{"label":{"en-US":"Command"},"type":"select","opts":{"opts":[{"l":{"en-US":"Register"},"v":"register"},{"l":{"en-US":"De-Register"},"v":"de-register"},{"l":{"en-US":"On"},"v":"on"},{"l":{"en-US":"Off"},"v":"off"},{"l":{"en-US":"Dim"},"v":"dim"},{"l":{"en-US":"Open"},"v":"open"},{"l":{"en-US":"Close"},"v":"close"},{"l":{"en-US":"Stop"},"v":"stop"},{"l":{"en-US":"Colour"},"v":"colour"},{"l":{"en-US":"Cycle Colour"},"v":"colourcycle"},{"l":{"en-US":"Store Mood"},"v":"storemood"},{"l":{"en-US":"Recall Mood"},"v":"recallmood"}]}}},{"name":"dimlevel","type":"num","value":"","ui":{"label":{"en-US":"dimlevel"},"type":"spinner","opts":{"min":0,"max":100}}},{"name":"colour","type":"str","value":"","ui":{"label":{"en-US":"Colour"},"type":"select","opts":{"opts":[{"l":{"en-US":"Undefined"},"v":""},{"l":{"en-US":"White"},"v":"1"},{"l":{"en-US":"Green White"},"v":"2"},{"l":{"en-US":"Red White"},"v":"3"},{"l":{"en-US":"Yellow White"},"v":"4"},{"l":{"en-US":"Red"},"v":"5"},{"l":{"en-US":"Middle Red"},"v":"6"},{"l":{"en-US":"Pink"},"v":"7"},{"l":{"en-US":"Light Red"},"v":"8"},{"l":{"en-US":"Orange"},"v":"9"},{"l":{"en-US":"Middle Orange"},"v":"10"},{"l":{"en-US":"Green White"},"v":"11"},{"l":{"en-US":"Light Orange"},"v":"12"},{"l":{"en-US":"Green"},"v":"13"},{"l":{"en-US":"Middle Green"},"v":"14"},{"l":{"en-US":"Light Yellow Green"},"v":"15"},{"l":{"en-US":"Yellow Green"},"v":"16"},{"l":{"en-US":"Blue"},"v":"17"},{"l":{"en-US":"Water Blue"},"v":"18"},{"l":{"en-US":"Light Blue"},"v":"19"},{"l":{"en-US":"White Blue"},"v":"20"}]}}},{"name":"mood","type":"str","value":"","ui":{"label":{"en-US":"Mood"},"type":"select","opts":{"opts":[{"l":{"en-US":"1"},"v":"1"},{"l":{"en-US":"2"},"v":"2"},{"l":{"en-US":"3"},"v":"3"},{"l":{"en-US":"Entry"},"v":"4"},{"l":{"en-US":"Exit"},"v":"5"}]}}}],"meta":{},"color":"#DAC4B4","inputLabels":["trigger"],"outputLabels":["command"],"icon":"font-awesome/fa-lightbulb-o","status":{"x":920,"y":40,"wires":[{"id":"60aedbda44f185cc","port":0}]}},{"id":"413a2b6b423a69de","type":"change","z":"1dba3faa997ebb49","name":"Set Message from Properties","rules":[{"t":"set","p":"payload_input","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.room","pt":"msg","to":"room","tot":"env"},{"t":"set","p":"payload.device","pt":"msg","to":"device","tot":"env"},{"t":"set","p":"payload.command","pt":"msg","to":"command","tot":"env"},{"t":"set","p":"payload.dimlevel","pt":"msg","to":"dimlevel","tot":"env"},{"t":"set","p":"payload.colour","pt":"msg","to":"colour","tot":"env"},{"t":"set","p":"payload.mood","pt":"msg","to":"mood","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":240,"y":40,"wires":[["ee40b055f41c0181"]]},{"id":"ee40b055f41c0181","type":"function","z":"1dba3faa997ebb49","name":"msg.payload to API call","func":"api_call = {\n    \"register\": \"F*p\"\n}\n\nmsg.property_payload = msg.payload;\nlet cmd = {\n    roomNo: null,\n    deviceNo: null,\n    functionType: null,\n    parameter: null,\n    line1: msg.payload.line1 !== undefined ? msg.payload.line1 : null,\n    line2: msg.payload.line2 !== undefined ? msg.payload.line2 : null\n};\nif(msg.room !== undefined) msg.payload.room = msg.room;\nif(msg.device !== undefined) msg.payload.device = msg.device;\nif(msg.command !== undefined) msg.payload.command = msg.command;\nif(msg.dimlevel !== undefined) msg.payload.dimlevel = msg.dimlevel;\nif(msg.colour !== undefined) msg.payload.colour = msg.colour;\nif(msg.mood !== undefined) msg.payload.mood = msg.mood;\nmsg.payload.command = msg.payload.command.toLowerCase();\nif(typeof msg.payload_input == 'boolean') {\n    switch(msg.payload.command) {\n        case \"on\":\n        case \"off\":\n            msg.payload.command = msg.payload_input ? \"on\" : \"off\";\n            break;\n        case \"open\":\n        case \"close\":\n            msg.payload.command = msg.payload_input ? \"open\" : \"close\";\n            break;\n    }\n}\nlet cmdPrint = msg.payload.command[0].toUpperCase() + msg.payload.command.slice(1).toLowerCase();\n// Colours are defined here: http://api.lightwaverf.com/lighting_power.html\nlet colourMap = {\n    1: \"White\",\n    2:\"Green White\",\n    3: \"Red White\",\n    4: \"Yellow White\",\n    5: \"Red\",\n    6: \"Middle Red\",\n    7: \"Pink\",\n    8: \"Light Red\",\n    9: \"Orange\",\n    10: \"Middle Orange\",\n    11: \"Green White\",\n    12: \"Light Orange\",\n    13: \"Green\",\n    14: \"Middle Green\",\n    15: \"Light Yellow Green\",\n    16: \"Yellow Green\",\n    17: \"Blue\",\n    18: \"Water Blue\",\n    19: \"Light Blue\",\n    20: \"White Blue\",\n}\nlet hasRoomAndDevice = true;\nlet hasRoom = null;\nswitch(msg.payload.command.toLowerCase()) {\n    case \"register\":\n        cmd.functionType = \"*\";\n        cmd.parameter = \"\";\n        hasRoomAndDevice = false;\n        break;\n    case \"deregister\":\n    case \"de-register\":\n        cmd.functionType = \"*x\";\n        cmd.parameter = \"\";\n        hasRoomAndDevice = false;\n        break;\n    case \"on\":\n        cmd.functionType = \"1\";\n        cmd.bool = true;\n        break;\n    case \"off\":\n        if (msg.payload.device == 0) {\n            hasRoom = true;\n            hasRoomAndDevice = false;\n            cmd.functionType = \"a\";\n        } else {\n            cmd.functionType = \"0\";    \n        }\n        cmd.bool = false;\n        break;\n    case \"alloff\":\n        hasRoom = true;\n        hasRoomAndDevice = false;\n        cmd.functionType = \"a\";\n        cmd.bool = false;\n        break;\n    case \"dim\":\n        cmd.functionType = \"d\";\n        let level = msg.payload.dimlevel < 0 ? 0 : msg.payload.dimlevel > 100 ? 100 : msg.payload.dimlevel;\n        cmd.parameter = Math.round((32 / 100) * level ).toString();\n        cmd.line1 = cmdPrint + ' ' + level.toString() + '%';\n        cmd.bool = level > 0;\n        break;\n    case \"open\":\n        cmd.functionType = \"(\";\n        cmd.bool = true;\n        break;\n    case \"close\":\n        cmd.functionType = \")\";\n        cmd.bool = false;\n        break;\n    case \"stop\":\n        cmd.functionType = \"^\";\n        break;\n    case \"colour\":\n        cmd.functionType = \"*c\";\n        let colour = msg.payload.colour < 1 ? 1 : msg.payload.colour > 20 ? 20 : msg.payload.colour;\n        cmd.parameter = colour.toString();\n        cmd.line1 = 'C:' + colourMap[colour];\n        break;\n    case \"colourcycle\":\n        cmd.functionType = \"*y\";\n        break;\n    case \"storemood\":\n        hasRoom = true;\n        hasRoomAndDevice = false;\n        cmd.functionType = \"s\";\n        let mood = msg.payload.mood < 1 ? 1 : msg.payload.mood > 5 ? 5 : msg.payload.mood;\n        cmd.parameter = mood.toString();\n        cmd.line1 = 'StrMood:' + (mood < 4 ? mood.toString() : mood == 4 ? 'Entry' : mood == 5 ? 'Exit' : 'Unknown');\n        break;\n    case \"recallmood\":\n        hasRoom = true;\n        hasRoomAndDevice = false;\n        cmd.functionType = \"m\";\n        let moodRec = msg.payload.mood < 1 ? 1 : msg.payload.mood > 5 ? 5 : msg.payload.mood;\n        cmd.parameter = moodRec.toString();\n        cmd.line1 = 'RecMood:' + (moodRec < 4 ? moodRec.toString() : moodRec == 4 ? 'Entry' : moodRec == 5 ? 'Exit' : 'Unknown');\n        break;\n}\nhasRoom = hasRoom == null ? hasRoomAndDevice : hasRoom;\nif (cmd.line1 == null) {\n    cmd.line1 = cmdPrint;\n}\nif (hasRoom) {\n    cmd.roomNo = msg.payload.room > 0 ? msg.payload.room.toString() : null;\n}\nif (hasRoomAndDevice) {\n    cmd.deviceNo = (msg.payload.device !== undefined && msg.payload.device > 0) ? msg.payload.device.toString() : null;\n}\nif (cmd.line2 == null && (hasRoomAndDevice || hasRoom)) {\n    cmd.line2 = `${cmd.roomNo !== null ? 'R:' + cmd.roomNo : ''}` + \n    `${cmd.deviceNo !== null ? ', D:' + cmd.deviceNo : ''}`;\n}\ncmdStr = `${cmd.roomNo !== null ? 'R' + cmd.roomNo : ''}` + \n    `${cmd.deviceNo !== null ? 'D' + cmd.deviceNo : ''}` + \n    `F${cmd.functionType}` + \n    `${cmd.parameter !== null ? 'P' + cmd.parameter : ''}` +\n    `${cmd.line1 !== null ? '|' + cmd.line1 : ''}` + \n    `${cmd.line2 !== null ? '|' + cmd.line2 : ''}`;\n\nif (msg.topic === undefined || msg.topic == '') {\n    msg.topic = 'lightwaverf/' + `${cmd.roomNo !== null ? cmd.roomNo + '/' : ''}` + `${cmd.deviceNo !== null ? cmd.deviceNo + '/' : ''}` + msg.payload.command.toLowerCase()\n}\nmsg.payload = \"!\" + cmdStr;\nmsg.cmd = cmd;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":40,"wires":[["4fe8355503263fe6","60aedbda44f185cc"]]},{"id":"4fe8355503263fe6","type":"function","z":"1dba3faa997ebb49","name":"Add Transaction #","func":"let trans = global.get(\"lw_messageCounter\");\ntrans = trans === undefined ? 1 : trans + 1;\nif (trans > 4294967295) trans = 1;\nglobal.set(\"lw_messageCounter\", trans);\n// node.status({fill: 'green', shape: \"dot\", text: trans });\ntransStr = trans.toString();\nwhile(transStr.length < 3) {\n    transStr = '0' + transStr;\n}\n\nmsg.payload = transStr + \",\" + msg.payload;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":100,"wires":[[]]},{"id":"60aedbda44f185cc","type":"function","z":"1dba3faa997ebb49","name":"Set Status","func":"let colour = msg.cmd.bool == undefined ? 'black' : msg.cmd.bool == true ? 'green' : 'red';\nmsg.payload = {fill: colour, shape: \"dot\", text: msg.cmd.line1 + (msg.cmd.line2 != '' && msg.cmd.line2 != null ? ' | ' + msg.cmd.line2 : '') }\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":40,"wires":[[]]},{"id":"0c8427c5c139a88e","type":"tab","label":"LightwaveRF","disabled":false,"info":"http://api.lightwaverf.com/\n[https://github.com/ollieparsley/node-lightwaverf/blob/master/index.js](Sample CODE)\n","env":[]},{"id":"eccf14cc5fb112e8","type":"group","z":"0c8427c5c139a88e","name":"LightwaveRF Simulator","style":{"stroke":"#ff0000","fill":"#ffdf7f","label":true,"color":"#000000"},"nodes":["d3aa0a8a2001c234","990b07dfced64a10","d7d61be428baad50","3fb2a5348ab42928","6122b0ee8964028e","d94fb4f7aa5335b4","3745b2bcc95ec6bc","1e2abf2a779976f2","33b2dd0b445feecb","6ec1e7d3c5302bab","b782e1461b191e7a","1b687031da818283","a22218b62d155884"],"x":54,"y":79,"w":1732,"h":222},{"id":"959c014f5f9b2e90","type":"udp in","z":"0c8427c5c139a88e","name":"LightwaveRF (9761) IN","iface":"","port":"9761","ipv":"udp4","multicast":"false","group":"","datatype":"utf8","x":260,"y":1700,"wires":[["d04cc6ae17ff6399","f7546de1653cd67f"]]},{"id":"e5d6bd505620676d","type":"udp out","z":"0c8427c5c139a88e","name":"LightwaveRF (9760) OUT","addr":"192.168.9.1","iface":"","port":"9760","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":1390,"y":1080,"wires":[]},{"id":"545694b3e7ca4548","type":"inject","z":"0c8427c5c139a88e","name":"Register","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":540,"wires":[["24677677b6710afb"]]},{"id":"c391539786c435e7","type":"debug","z":"0c8427c5c139a88e","name":"RAW Cmd","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1370,"y":980,"wires":[]},{"id":"be37a978526b716b","type":"link out","z":"0c8427c5c139a88e","name":"Simulated LighwaveRF Command - OUT","mode":"link","links":["d3aa0a8a2001c234","11cb3bd7cfa214d0"],"x":1440,"y":1040,"wires":[],"l":true},{"id":"d3aa0a8a2001c234","type":"link in","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Simulated LighwaveRF Command - IN","links":["be37a978526b716b"],"x":230,"y":160,"wires":[["990b07dfced64a10"]],"l":true},{"id":"990b07dfced64a10","type":"function","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"LighwaveRF Simulator","func":"// Split the command\nlet cmd_regex = /^(?<trans>[0-9]+),\\!(?<roomNo>([Rr][0-9]*)?)?(?<deviceNo>[Dd][0-9]*)?(?<functionType>([Ff]\\*?[^Pp]?))(?<parameter>([Pp][a-zA-Z0-9]*)?)?(?<line1>\\|[^\\|]*)?(?<line2>\\|[^\\|]*)?$/;\n// cmd_regex = /^\\!(?<functionType>[Ff][\\*a-zA-Z01])(?<parameter>[Pp][a-zA-Z0-9]*)?$/;\nlet cmd_groups = msg.payload.match(cmd_regex).groups;\ncmd_groups.trans = parseInt(cmd_groups.trans, 10);\ncmd_groups.roomNo = cmd_groups.roomNo === undefined ? null : parseInt(cmd_groups.roomNo.slice(1), 10);\ncmd_groups.deviceNo = cmd_groups.deviceNo === undefined ? null : parseInt(cmd_groups.deviceNo.slice(1), 10);\ncmd_groups.functionType = cmd_groups.functionType.slice(1);\ncmd_groups.parameter = cmd_groups.parameter === undefined ? '' : cmd_groups.parameter.slice(1);\ncmd_groups.line1 = cmd_groups.line1 === undefined ? \"\" : cmd_groups.line1.slice(1, 16);\ncmd_groups.line2 = cmd_groups.line2 === undefined ? \"\" : cmd_groups.line2.slice(1, 16);\n// for (const [key, value] of Object.entries(cmd_groups)) {\n//     if(key != 'trans') {\n//         cmd_groups[key] = value.slice(1);\n//     }\n    \n// }\n\nmsg.cmd_groups = cmd_groups;\n\nlet simulatedRegistered = flow.get(\"lw_simulatedRegistered\");\nnode.status({fill: 'green', shape: \"dot\", text: cmd_groups.line1 + (cmd_groups.line2 != '' ? ' | ' : '') + cmd_groups.line2 });\nlet response = {\n    trans: null,\n    mac: null,\n    time: null\n}\n\nif(!simulatedRegistered) {\n    response.pkt = \"error\";\n    response.fn = \"nonRegistered\";\n    if(cmd_groups.functionType == '*' && cmd_groups.parameter == '') {\n        response.payload = \"Not yet registered. See LightwaveLink\";\n        // flow.set(\"lw_simulatedRegistered\", true);\n    } else {\n        response.payload = \"Not yet registered. Send !F*p to register\";\n    }\n} else {\n    response.pkt = \"433T\";\n    switch(cmd_groups.functionType) {\n        case \"*\":\n            response.pkt = 'OK';\n            break;\n        case \"*x\":\n            response.pkt = 'OK';\n            flow.set(\"lw_simulatedRegistered\", false)\n            // Update the registration status\n            node.send([null, {}]);\n            break;\n        case \"1\":\n            response.fn = 'on';\n            break;\n        case \"0\":\n            response.fn = 'off';\n            break;\n        case \"a\":\n            response.fn = 'allOff';\n            break;\n        case \"(\":\n            response.fn = 'open';\n            break;\n        case \")\":\n            response.fn = 'close';\n            break;\n        case \"^\":\n            response.fn = 'stop';\n            break;\n        case \"d\":\n            response.fn = 'dim';\n            break;\n        case \"*c\":\n            response.fn = 'ledColour';\n            break;\n        case \"*y\":\n            response.fn = 'ledColourCycle';\n            break;\n        case \"s\":\n            response.fn = 'moodStore';\n            break;\n        case \"m\":\n            response.fn = 'moodRecall';\n            break;\n        default:\n            response.fn = 'unknown';\n            break;\n    }\n    if(cmd_groups.deviceNo != null) {\n        response.dev = cmd_groups.deviceNo;\n    }\n    if(cmd_groups.roomNo != null) {\n        response.room = cmd_groups.roomNo;\n        // In the real world multiple devices would respond, in this simulator device 1 always responds if no device was specified\n        if(response.dev == null) response.dev = 1;\n    }\n    if(cmd_groups.parameter != '') {\n        response.param = parseInt(cmd_groups.parameter);\n    }\n}\nmsg.payload = response;\nif(response.fn == \"nonRegistered\") {\n    return [msg, msg];    \n} else {\n    return [msg, null];\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":160,"wires":[["b782e1461b191e7a"],["6ec1e7d3c5302bab","3745b2bcc95ec6bc"]]},{"id":"d7d61be428baad50","type":"debug","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Response","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1680,"y":220,"wires":[]},{"id":"e5567cd782ee0adb","type":"change","z":"0c8427c5c139a88e","name":"Reset global.lw_messageCounter","rules":[{"t":"set","p":"lw_messageCounter","pt":"global","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":400,"wires":[[]]},{"id":"6836833a9b80766f","type":"inject","z":"0c8427c5c139a88e","name":"Reset Message Counter","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":400,"wires":[["e5567cd782ee0adb"]]},{"id":"3fb2a5348ab42928","type":"inject","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Reset Simulated Transaction Counter","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":250,"y":120,"wires":[["6122b0ee8964028e"]]},{"id":"6122b0ee8964028e","type":"change","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Reset flow.lw_simulatedTransactionCounter","rules":[{"t":"set","p":"lw_simulatedTransactionCounter","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":120,"wires":[[]]},{"id":"d94fb4f7aa5335b4","type":"link out","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Simulated LighwaveRF Response - OUT","mode":"link","links":["3e4f674c22295fd8"],"x":1380,"y":260,"wires":[],"l":true},{"id":"3e4f674c22295fd8","type":"link in","z":"0c8427c5c139a88e","name":"Simulated LighwaveRF Response - IN","links":["d94fb4f7aa5335b4","4cf32f7005d73049"],"x":210,"y":1660,"wires":[["d04cc6ae17ff6399"]],"l":true},{"id":"d04cc6ae17ff6399","type":"function","z":"0c8427c5c139a88e","name":"Parse response JSON","func":"if (msg.payload.startsWith(\"*!\")) {\n    msg.payload = JSON.parse(msg.payload.slice(2));\n    let type = msg.payload.type !== undefined ? msg.payload.type : msg.payload.pkt !== undefined ? msg.payload.pkt : 'link';\n    let room = msg.payload.room !== undefined ? '/' + msg.payload.room.toString() : '';\n    let device = msg.payload.dev !== undefined ? '/' + msg.payload.dev.toString() : '';\n    msg.topic = 'lightwaverf/' + type + room + device\n    return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":1660,"wires":[["c2640e76b05f1e9e","9db7cba00b4d9dc6"]]},{"id":"c2640e76b05f1e9e","type":"debug","z":"0c8427c5c139a88e","name":"Parsed Response","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1130,"y":1660,"wires":[]},{"id":"3745b2bcc95ec6bc","type":"function","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"LighwaveRF Simulator Registration Status","func":"let simulatedRegistered = flow.get(\"lw_simulatedRegistered\");\nnode.status({fill: simulatedRegistered ? 'green' : 'red', shape: \"dot\", text: simulatedRegistered ? 'registered' : 'unregistered' });\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":180,"wires":[[]]},{"id":"1e2abf2a779976f2","type":"function","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Send Registration packet","func":"if (msg.payload !== undefined && msg.payload.payload == 'Not yet registered. See LightwaveLink') {\n    let response = {\n        trans: null,\n        mac: null,\n        time: null,\n        type: \"link\",\n        prod: \"lwl\",\n        pairType: \"local\",\n        msg: \"success\",\n        class: \"\",\n        serial: \"\"\n    }\n    flow.set(\"lw_simulatedRegistered\", true);\n    msg.payload = response;\n    return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":260,"wires":[["3745b2bcc95ec6bc","b782e1461b191e7a","1b687031da818283"]]},{"id":"33b2dd0b445feecb","type":"function","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"LighwaveRF Simulator - Stringify payload","func":"msg.payload = \"*!\" + JSON.stringify(msg.payload);\n// Deleting parts of the message to be more like the \"real\" replies\ndelete msg.topic;\ndelete msg.property_payload;\ndelete msg.cmd;\ndelete msg.cmd_groups;\ndelete msg.payload_input;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1400,"y":220,"wires":[["d94fb4f7aa5335b4","d7d61be428baad50"]]},{"id":"6ec1e7d3c5302bab","type":"delay","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":540,"y":220,"wires":[["1e2abf2a779976f2"]]},{"id":"14c8b49b8e652a16","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":740,"wires":[["95d6469b66f310fb"]]},{"id":"b782e1461b191e7a","type":"function","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Set transaction #, mac and timestamp","func":"let trans = flow.get(\"lw_simulatedTransactionCounter\");\ntrans = trans == undefined ? 1 : trans + 1;\nnode.status({fill: 'green', shape: \"dot\", text: trans.toString() });\nflow.set(\"lw_simulatedTransactionCounter\", trans);\nvar d = new Date();\nmsg.payload.trans = trans;\nmsg.payload.mac = \"21:34:56\";\nmsg.payload.time = Math.round(d.getTime() / 1000);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1390,"y":160,"wires":[["33b2dd0b445feecb"]]},{"id":"9db7cba00b4d9dc6","type":"switch","z":"0c8427c5c139a88e","name":"Room & Device","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"lightwaverf/433T/1/5","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":980,"y":1720,"wires":[["5725ce5842405aee"]]},{"id":"5725ce5842405aee","type":"debug","z":"0c8427c5c139a88e","name":"Room 1 Dev 5","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1200,"y":1720,"wires":[]},{"id":"cdd4091851e8797b","type":"inject","z":"0c8427c5c139a88e","name":"De-register","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":600,"wires":[["beed1f45d132d01f"]]},{"id":"1b687031da818283","type":"debug","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"Register","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1020,"y":260,"wires":[]},{"id":"f7546de1653cd67f","type":"debug","z":"0c8427c5c139a88e","name":"RAW Response","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":680,"y":1700,"wires":[]},{"id":"24677677b6710afb","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Register","env":[{"name":"command","value":"register","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":480,"y":540,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"beed1f45d132d01f","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"De-Register","env":[{"name":"command","value":"de-register","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":470,"y":600,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"a65771f757f48c81","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":130,"y":660,"wires":[["126975b7cc41b796"]]},{"id":"126975b7cc41b796","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Device 5 - On","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"5","type":"num"},{"name":"command","value":"on","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":440,"y":660,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"556f7495d8fe02b9","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":130,"y":700,"wires":[["126975b7cc41b796"]]},{"id":"b16a97aa9fc5f2c9","type":"function","z":"0c8427c5c139a88e","name":"NOOP","func":"// This function just forward the message = NOOP\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1110,"y":1040,"wires":[["c391539786c435e7","be37a978526b716b","e5d6bd505620676d"]]},{"id":"95d6469b66f310fb","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Device 5 - Off","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"5","type":"num"},{"name":"command","value":"off","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":440,"y":740,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"c0e503b645eee94d","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":800,"wires":[["446cd6df3ae541a8"]]},{"id":"446cd6df3ae541a8","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Device 5 - On","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"5","type":"num"},{"name":"command","value":"on","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":440,"y":800,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"4948055d3ae4f7c2","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - All Devices - Off","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"0","type":"num"},{"name":"command","value":"off","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":430,"y":860,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"ef6f2c1ad48a4e1b","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":860,"wires":[["4948055d3ae4f7c2"]]},{"id":"5e30af4fdfae4f07","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 2 - Device 1 - Dim 50%","env":[{"name":"room","value":"2","type":"num"},{"name":"device","value":"1","type":"num"},{"name":"command","value":"dim","type":"str"},{"name":"dimlevel","value":"50","type":"num"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":420,"y":920,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"69c9280451def820","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":920,"wires":[["5e30af4fdfae4f07"]]},{"id":"fd19bd66e0f9b7d2","type":"inject","z":"0c8427c5c139a88e","name":"Dim 30%","props":[{"p":"dimlevel","v":"30","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":960,"wires":[["5e30af4fdfae4f07"]]},{"id":"717515309b8db8da","type":"inject","z":"0c8427c5c139a88e","name":"Dim 0%","props":[{"p":"dimlevel","v":"0","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":1000,"wires":[["5e30af4fdfae4f07"]]},{"id":"c6d9e3441fc0447c","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1160,"wires":[["1252fc710ba6678b"]]},{"id":"1d59ce6405dede51","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1220,"wires":[["a5e2ef53045b578b"]]},{"id":"db75821d7a6f22dc","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":130,"y":1080,"wires":[["54bc540b07d6cde2"]]},{"id":"34e44b6bdb8159a0","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":130,"y":1040,"wires":[["54bc540b07d6cde2"]]},{"id":"54bc540b07d6cde2","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 2 - Device 3 - Open","env":[{"name":"room","value":"2","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"open","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":430,"y":1040,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"1252fc710ba6678b","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 2 - Device 3 - Open","env":[{"name":"room","value":"2","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"open","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":430,"y":1160,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"a5e2ef53045b578b","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 2 - Device 3 - Close","env":[{"name":"room","value":"2","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"close","type":"str"},{"name":"colour","value":null,"type":"str"},{"name":"mood","value":null,"type":"str"}],"x":430,"y":1220,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"44193e1f5294eb72","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 2 - Device 3 - Stop","env":[{"name":"room","value":"2","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"stop","type":"str"},{"name":"mood","value":null,"type":"str"}],"x":430,"y":1280,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"b5d5e212886b37b0","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1280,"wires":[["44193e1f5294eb72"]]},{"id":"61943bed88ae34bc","type":"inject","z":"0c8427c5c139a88e","name":"stop","props":[{"p":"command","v":"stop","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":1120,"wires":[["54bc540b07d6cde2"]]},{"id":"6b6b27d298964d47","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Device 3 - Colour Orange","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"colour","type":"str"},{"name":"colour","value":"9","type":"str"},{"name":"mood","value":null,"type":"str"}],"x":400,"y":1340,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"4e18f83ff00e7a57","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1340,"wires":[["6b6b27d298964d47"]]},{"id":"8dc121012645c8c2","type":"inject","z":"0c8427c5c139a88e","name":"White Blue","props":[{"p":"colour","v":"20","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":1380,"wires":[["6b6b27d298964d47"]]},{"id":"018df32c762cc5e0","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Device 3 - Cycle Colour","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"3","type":"num"},{"name":"command","value":"colourcycle","type":"str"},{"name":"mood","value":null,"type":"str"}],"x":410,"y":1420,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"cf40307b18d24878","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1420,"wires":[["018df32c762cc5e0"]]},{"id":"e68115868c782c62","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Store Mood 3","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"0","type":"num"},{"name":"command","value":"storemood","type":"str"},{"name":"mood","value":"3","type":"str"}],"x":440,"y":1480,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"20f0ab3029c15869","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1480,"wires":[["e68115868c782c62"]]},{"id":"d0c6ef305fc00afd","type":"subflow:1dba3faa997ebb49","z":"0c8427c5c139a88e","name":"Room 1 - Recall Mood 3","env":[{"name":"room","value":"1","type":"num"},{"name":"device","value":"0","type":"num"},{"name":"command","value":"recallmood","type":"str"},{"name":"mood","value":"3","type":"str"}],"x":430,"y":1540,"wires":[["b16a97aa9fc5f2c9"]]},{"id":"2c2f408e02e09136","type":"inject","z":"0c8427c5c139a88e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1540,"wires":[["d0c6ef305fc00afd"]]},{"id":"a22218b62d155884","type":"comment","z":"0c8427c5c139a88e","g":"eccf14cc5fb112e8","name":"READ THIS!!!","info":"The simulator is NOT needed to use an actual LightwaveRF device! It is only included to facilitate development.\nDisconnect the input to the simulator when running a REAL LightwaveRF device!","x":270,"y":220,"wires":[]},{"id":"80efdbed5cb728ae","type":"comment","z":"0c8427c5c139a88e","name":"Message Counter","info":"The emssage counter doesn't need to be reset, it is handled automatically, it's just here for debugging and convenience.","x":170,"y":360,"wires":[]},{"id":"a058bbfd39904354","type":"comment","z":"0c8427c5c139a88e","name":"--- Sample Commands ---","info":"","x":190,"y":500,"wires":[]},{"id":"98d4206e1828c1bd","type":"comment","z":"0c8427c5c139a88e","name":"--- Sample Input parsing ---","info":"Use topic to determine which message is for which device, see the switch sample \"Room & Device\".\n","x":170,"y":1620,"wires":[]}]

EDIT: Changed ‘p’ to ‘P’ in flow

2 Likes

@bobbles what kind of devices are you using lightwaverf with? As I mentioned above currently I just added “Lighting & Power” devices, but once you have time to test this I can add additional device types if needed. Btw, the subflows have editable properties, just like other nodes:
image

Set the IP of your lifghtwaverf device in the LightwaveRF OUT node. Let me know if you want to schedule a Teams meeting, this was fun to work on for a little bit. This is a fully stand-alone integration, no external libraries or additional services needed, just NR.

1 Like

I’m using dimmers and switches (outlets) only.
I’ll have a crack at following your post and see what I come up with.
Thanks.

1 Like

Loaded the following into the file as requested.
Received this when restarting NR.
Does it look correct?

---- CONFIG OVERRIDES START ----
PORT_MAP+=(“192.168.0.40:9761:9761/udp”)
----- CONFIG OVERRIDES END -----

Yes, that looks correct

1 Like

There’s also Tailscale VPN in HA as well. I tested all 3. Wireguard, openVPN, and Tailscale and still have them all up but I now use Unifi Wifiman ( if you have Ubiquiti) for all my VPN since it’s much easier for me to define my firewall and rules for my network.

1 Like

Hi @markus. On the above is this the IP address of CC or my LWRF hub?
Thanks.

That is the CC IP, the LWRF ip goes in the UDP out node in NR

1 Like

Hi @markus
Does UDP need to be activated on CC or is it ‘live’ already.
Thanks.

1 Like

Once you’ve added the mapping described above, as long as your CC is in the same subnet as your LWRF that is all you need. The only other limitation is that LWRF will only send unicast to the latest IP which sent a command to it (if the API docs are to be believed). So using two different connections, like the one on your pi, at the same time may cause some messages to be missed. If you have a lot of trouble getting this up and running, it was written just based on API docs after all, I’d be happy to do Teams during the weekend, we will be opening up a session like we did last weekend for those who need it.

1 Like