|
[{"id":"62264c9ebd5f8815","type":"tab","label":"Dualshock 4","disabled":false,"info":"","env":[]},{"id":"99a814c605cf657a","type":"group","z":"62264c9ebd5f8815","name":"Dualshock 4 controller sender","style":{"label":true,"stroke":"#003F97"},"nodes":["12de082f6683ba15","b81edf27eef4765d","bb8d491eda1c033b","ff83174dd3248d15","714fc480901f0a0e","1b43646e66f1f04b","ce7a6805e3036fea","1da39337104e7934","370ccf5402f43958","9d91efe76e72ee80","446259cbc3a7bd10","bd23ef4805d7c191","9f63aa2e202ef23a","0c48a8e47e101bcf","81f0956b165be29f","7d7222b409ffa70f","dd4dbac9a2848498"],"x":34,"y":39,"w":892,"h":282},{"id":"12de082f6683ba15","type":"function","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"Dualshock","func":"function filterDeadZone(data, side) {\n if (data.x >= 145 || data.x <= 115 || data.y >= 145 || data.y <= 115) {\n node.send({ \"payload\": `${side}Stick move: (${data.x},${data.y})`, \"controller\": controller, \"topic\": `${side}Stick`});\n } else {\n return;\n };\n};\n\n// controls to turn on the listener\nif (msg.payload === \"on\") {\n // pass options to create the controller.\n var controller = dualShock({\n // you can use a ds4 by uncommenting this line.\n config: \"dualshock4-generic-driver\",\n\n // if the above configuration doesn\"t work for you,\n // try uncommenting the following line instead.\n //config: \"dualshock4-alternate-driver\",\n\n // if using ds4 comment this line.\n //config: \"dualShock3\",\n\n // smooths the output from the acelerometers (moving averages) defaults to true\n accelerometerSmoothing: true,\n\n // smooths the output from the analog sticks (moving averages) defaults to false\n analogStickSmoothing: false,\n });\n\n // set the maximum number of listeners\n controller._maxListeners = 50;\n\n // make sure you add an error event handler\n controller.on(\"error\", err => node.error({ \"error\": err }));\n\n // analog stick handlers:\n controller.on(\"left:move\", data => filterDeadZone(data, \"left\"));\n controller.on(\"right:move\", data => filterDeadZone(data, \"right\"));\n //controller.on(\"left:move\", data => node.send({ \"payload\": `leftStick move: (${data.x},${data.y})`, \"controller\": controller}));\n //controller.on(\"right:move\", data => node.send({ \"payload\": `rightStick move: (${data.x},${data.y})`, \"controller\": controller}));\n\n // square, triangle, circle, and cross event handlers:\n controller.on(\"square:press\", () => node.send({ \"payload\": \"square press\", \"controller\": controller }));\n controller.on(\"square:release\", () => node.send({ \"payload\": \"square release\", \"controller\": controller }));\n controller.on(\"triangle:press\", () => node.send({ \"payload\": \"triangle press\", \"controller\": controller }));\n controller.on(\"triangle:release\", () => node.send({ \"payload\": \"triangle release\", \"controller\": controller }));\n controller.on(\"circle:press\", () => node.send({ \"payload\": \"circle press\", \"controller\": controller }));\n controller.on(\"circle:release\", () => node.send({ \"payload\": \"circle release\", \"controller\": controller }));\n controller.on(\"x:press\", () => node.send({ \"payload\": \"cross press\", \"controller\": controller }));\n controller.on(\"x:release\", () => node.send({ \"payload\": \"cross release\", \"controller\": controller }));\n\n // dpad event handlers:\n controller.on(\"dpadUp:press\", () => node.send({ \"payload\": \"dpadUp press\", \"controller\": controller }));\n controller.on(\"dpadUp:release\", () => node.send({ \"payload\": \"dpadUp release\", \"controller\": controller }));\n controller.on(\"dpadUpRight:press\", () => node.send({ \"payload\": \"dpadUpRight press\", \"controller\": controller }));\n controller.on(\"dpadUpRight:release\", () => node.send({ \"payload\": \"dpadUpRight release\", \"controller\": controller }));\n controller.on(\"dpadRight:press\", () => node.send({ \"payload\": \"dpadRight press\", \"controller\": controller }));\n controller.on(\"dpadRight:release\", () => node.send({ \"payload\": \"dpadRight release\", \"controller\": controller }));\n controller.on(\"dpadDownRight:press\", () => node.send({ \"payload\": \"dpadDownRight press\", \"controller\": controller }));\n controller.on(\"dpadDownRight:release\", () => node.send({ \"payload\": \"dpadDownRight release\", \"controller\": controller }));\n controller.on(\"dpadDown:press\", () => node.send({ \"payload\": \"dpadDown press\", \"controller\": controller }));\n controller.on(\"dpadDown:release\", () => node.send({ \"payload\": \"dpadDown release\", \"controller\": controller }));\n controller.on(\"dpadDownLeft:press\", () => node.send({ \"payload\": \"dpadDownLeft press\", \"controller\": controller }));\n controller.on(\"dpadDownLeft:release\", () => node.send({ \"payload\": \"dpadDownLeft release\", \"controller\": controller }));\n controller.on(\"dpadLeft:press\", () => node.send({ \"payload\": \"dpadLeft press\", \"controller\": controller }));\n controller.on(\"dpadLeft:release\", () => node.send({ \"payload\": \"dpadLeft release\", \"controller\": controller }));\n controller.on(\"dpadUpLeft:press\", () => node.send({ \"payload\": \"dpadUpLeft press\", \"controller\": controller }));\n controller.on(\"dpadUpLeft:release\", () => node.send({ \"payload\": \"dpadUpLeft release\", \"controller\": controller }));\n \n // share, options, and PS Button handlers:\n controller.on(\"share:press\", () => node.send({ \"payload\": \"share press\", \"controller\": controller }));\n controller.on(\"share:release\", () => node.send({ \"payload\": \"share release\", \"controller\": controller }));\n controller.on(\"options:press\", () => node.send({ \"payload\": \"options press\", \"controller\": controller }));\n controller.on(\"options:release\", () => node.send({ \"payload\": \"options release\", \"controller\": controller }));\n controller.on(\"psxButton:press\", () => node.send({ \"payload\": \"PS Button press\", \"controller\": controller }));\n controller.on(\"psxButton:release\", () => node.send({ \"payload\": \"PS Button release\", \"controller\": controller }));\n \n // L/R handlers:\n controller.on(\"l1:press\", () => node.send({ \"payload\": \"L1 press\", \"controller\": controller }));\n controller.on(\"l1:release\", () => node.send({ \"payload\": \"L1 release\", \"controller\": controller }));\n controller.on(\"r1:press\", () => node.send({ \"payload\": \"R1 press\", \"controller\": controller }));\n controller.on(\"r1:release\", () => node.send({ \"payload\": \"R1 release\", \"controller\": controller }));\n controller.on(\"l2:press\", () => node.send({ \"payload\": \"L2 press\", \"controller\": controller }));\n controller.on(\"l2:release\", () => node.send({ \"payload\": \"L2 release\", \"controller\": controller }));\n //controller.on(\"l2:analog\", () => node.send({ \"payload\": \"L2 analog\", \"controller\": controller }));\n controller.on(\"r2:press\", () => node.send({ \"payload\": \"R2 press\", \"controller\": controller }));\n controller.on(\"r2:release\", () => node.send({ \"payload\": \"R2 release\", \"controller\": controller }));\n //controller.on(\"r2:analog\", () => node.send({ \"payload\": \"R2 analog\", \"controller\": controller }));\n //controller.on(\"leftAnalogBump:press\", () => node.send({ \"payload\": \"L2 press\", \"controller\": controller }));\n //controller.on(\"leftAnalogBump:release\", () => node.send({ \"payload\": \"L2 release\", \"controller\": controller }));\n //controller.on(\"rightAnalogBump:press\", () => node.send({ \"payload\": \"R2 press\", \"controller\": controller }));\n //controller.on(\"rightAnalogBump:release\", () => node.send({ \"payload\": \"R2 release\", \"controller\": controller }));\n controller.on(\"leftStick:press\", () => node.send({ \"payload\": \"L3 press\", \"controller\": controller }));\n controller.on(\"leftStick:release\", () => node.send({ \"payload\": \"L3 release\", \"controller\": controller }));\n controller.on(\"rightStick:press\", () => node.send({ \"payload\": \"R3 press\", \"controller\": controller }));\n controller.on(\"rightStick:release\", () => node.send({ \"payload\": \"R3 release\", \"controller\": controller }));\n\n // touchpad handlers:\n controller.on(\"touchpad:press\", () => node.send({ \"payload\": \"touchpad press\", \"controller\": controller }));\n controller.on(\"touchpad:release\", () => node.send({ \"payload\": \"touchpad release\", \"controller\": controller }));\n //finger 1 is x1 finger 2 is x2\n //controller.on(\"touchpad:x1:active\", () => node.send({ \"payload\": \"touchpad one finger active\" }));\n //controller.on(\"touchpad:x2:active\", () => node.send({ \"payload\": \"touchpad two fingers active\" }));\n //controller.on(\"touchpad:x2:inactive\", () => node.send({ \"payload\": \"touchpad back to single finger\" }));\n //controller.on(\"touchpad:x1\", data => node.send({ \"payload\": `touchpad x1: ${data.x}, ${data.y}`, \"controller\": controller, \"topic\": \"touchpad\" }));\n //controller.on(\"touchpad:x2\", data => node.send({ \"payload\": `touchpad x2: ${data.x}, ${data.y}`, \"controller\": controller, \"topic\": \"touchpad\" }));\n\n // motion control handlers:\n //controller.on(\"rightLeft:motion\", data => node.send({ \"payload\": data, \"topic\": \"motion\", \"controller\": controller }))\n //controller.on(\"forwardBackward:motion\", data => node.send({ \"payload\": data, \"topic\": \"motion\", \"controller\": controller }))\n //controller.on(\"upDown:motion\", data => node.send({ \"payload\": data, \"topic\": \"motion\", \"controller\": controller }))\n\n // status handlers:\n //controller.on(\"connected\", () => node.send({ \"payload\": \"connected\", \"topic\": \"status\", \"controller\": controller }));\n //controller.on(\"battery:change\", data => node.send({ \"payload\": data, \"topic\": \"status\", \"controller\": controller }));\n //controller.on(\"connection:change\", data => node.send({ \"payload\": data, \"topic\": \"status\", \"controller\": controller }));\n //controller.on(\"charging:change\", data => node.send({ \"payload\": data, \"topic\": \"status\", \"controller\": controller }));\n\n // send startup message\n node.send({ \"payload\": \"Listeners turned on\", \"controller\": controller });\n\n // save controller\n flow.set(\"controller\", controller);\n \n // status output for function node\n node.status({ fill: \"green\", shape: \"dot\", text: \"ON\" });\n};\n\n// controls to turn off the listener\nif (msg.payload === \"off\") {\n // get our saved controller\n let controller = flow.get(\"controller\");\n\n // set the maximum number of listeners\n controller._maxListeners = 0;\n\n // clear event listeners\n controller._events[\"error\"] = [];\n controller._events[\"left:move\"] = [];\n controller._events[\"right:move\"] = [];\n controller._events[\"square:press\"] = [];\n controller._events[\"square:release\"] = [];\n controller._events[\"triangle:press\"] = [];\n controller._events[\"triangle:release\"] = [];\n controller._events[\"circle:press\"] = [];\n controller._events[\"circle:release\"] = [];\n controller._events[\"x:press\"] = [];\n controller._events[\"x:release\"] = [];\n controller._events[\"dpadUp:press\"] = [];\n controller._events[\"dpadUp:release\"] = [];\n controller._events[\"dpadUpRight:press\"] = [];\n controller._events[\"dpadUpRight:release\"] = [];\n controller._events[\"dpadRight:press\"] = [];\n controller._events[\"dpadRight:release\"] = [];\n controller._events[\"dpadDownRight:press\"] = [];\n controller._events[\"dpadDownRight:release\"] = [];\n controller._events[\"dpadDown:press\"] = [];\n controller._events[\"dpadDown:release\"] = [];\n controller._events[\"dpadDownLeft:press\"] = [];\n controller._events[\"dpadDownLeft:release\"] = [];\n controller._events[\"dpadLeft:press\"] = [];\n controller._events[\"dpadLeft:release\"] = [];\n controller._events[\"dpadUpLeft:press\"] = [];\n controller._events[\"dpadUpLeft:release\"] = [];\n controller._events[\"options:press\"] = [];\n controller._events[\"options:release\"] = [];\n controller._events[\"share:press\"] = [];\n controller._events[\"share:release\"] = [];\n controller._events[\"psxButton:press\"] = [];\n controller._events[\"psxButton:release\"] = [];\n controller._events[\"l1:press\"] = [];\n controller._events[\"l1:release\"] = [];\n controller._events[\"r1:press\"] = [];\n controller._events[\"r1:release\"] = [];\n controller._events[\"l2:press\"] = [];\n controller._events[\"l2:release\"] = [];\n controller._events[\"r2:press\"] = [];\n controller._events[\"r2:release\"] = [];\n controller._events[\"leftStick:press\"] = [];\n controller._events[\"leftStick:release\"] = [];\n controller._events[\"rightStick:press\"] = [];\n controller._events[\"rightStick:release\"] = [];\n controller._events[\"touchpad:press\"] = [];\n controller._events[\"touchpad:release\"] = [];\n\n // send final closing message\n node.send({ \"payload\": \"Listeners turned off\", \"controller\": controller });\n\n // save controller\n flow.set(\"controller\", controller);\n\n // status output for function node\n node.status({ fill: \"red\", shape: \"dot\", text: \"OFF\" });\n};","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"dualShock","module":"node-dualshock-controller"}],"x":290,"y":180,"wires":[["ce7a6805e3036fea"]]},{"id":"b81edf27eef4765d","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"rightStick(x,y)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":800,"y":160,"wires":[]},{"id":"bb8d491eda1c033b","type":"inject","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":130,"y":160,"wires":[["12de082f6683ba15"]]},{"id":"ff83174dd3248d15","type":"catch","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","scope":["12de082f6683ba15"],"uncaught":false,"x":130,"y":260,"wires":[["1b43646e66f1f04b"]]},{"id":"714fc480901f0a0e","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"errors","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":430,"y":260,"wires":[]},{"id":"1b43646e66f1f04b","type":"function","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"warn","func":"if (msg.error) {\n node.warn(\"Don't forget to check that the controller hasn't lost connection first.\")\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":260,"wires":[["714fc480901f0a0e"]]},{"id":"ce7a6805e3036fea","type":"switch","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"hold","vt":"str"},{"t":"eq","v":"leftStick","vt":"str"},{"t":"eq","v":"rightStick","vt":"str"},{"t":"eq","v":"motion","vt":"str"},{"t":"eq","v":"status","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":6,"x":430,"y":180,"wires":[["0c48a8e47e101bcf"],["9d91efe76e72ee80"],["446259cbc3a7bd10"],["9f63aa2e202ef23a"],["bd23ef4805d7c191"],["370ccf5402f43958"]]},{"id":"1da39337104e7934","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"leftStick(x,y)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":790,"y":120,"wires":[]},{"id":"370ccf5402f43958","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"other","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":280,"wires":[]},{"id":"9d91efe76e72ee80","type":"delay","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"5","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":630,"y":120,"wires":[["1da39337104e7934"]]},{"id":"446259cbc3a7bd10","type":"delay","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"5","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":630,"y":160,"wires":[["b81edf27eef4765d"]]},{"id":"bd23ef4805d7c191","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"controller status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":240,"wires":[]},{"id":"9f63aa2e202ef23a","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"motion","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":200,"wires":[]},{"id":"0c48a8e47e101bcf","type":"debug","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"hold","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":80,"wires":[]},{"id":"81f0956b165be29f","type":"comment","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"Sender controls","info":"","x":140,"y":120,"wires":[]},{"id":"7d7222b409ffa70f","type":"comment","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"Output here","info":"","x":430,"y":100,"wires":[]},{"id":"dd4dbac9a2848498","type":"inject","z":"62264c9ebd5f8815","g":"99a814c605cf657a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":130,"y":200,"wires":[["12de082f6683ba15"]]}] |
hi Harold, thanks for this flow! when i load the flow, i get the following error: [info] Failed to load external modules required by this flow:
[info] - node-dualshock-controller [404] . Do you know i can get this to work? Thanks in advance!