Vertex Action - Motion sensor logic

In a Vertex Action node Motion sensor mode is created to get the information from the motion sensor configured in a node (dali2devs or dali2common).

Input of the node:

These are commands received from Motion sensor:
{"payload": {"MSEVENT": 0}} - presence
{"payload": {"MSEVENT": 1}} - transition
{"payload": {"MSEVENT": 2}} - no presence

Additionally, each sensor is sending an individual UID (unique identifier):

You need to create a direct connection between a “device” node and a VA: Motion sensor node.

That’s because there is a list of devices in the Vertex Action node, and the logic behind it is waiting for all of the devices to report the No Presence event to turn off a group of luminaires.

Every flow “deploy” clears the list of devices that are connected to the Vertex Action.

Global values

The CCT node outputs a brightness level in 0 to 100 range. On the other hand, the vertex action node outputs the brigthness in logarithmic scale. In order to use the CCT value for setting the brightness for motion sensor events, it needs to be properly converted to the logarithmic scale. Conversion is implemented in the “Global values“ flow section.

Import the ready made flow using the instructions here: Importing a Node-RED flow

[{"id":"463437f9.dd86a8","type":"tab","label":"Multiple sensors to Vertex Action","disabled":false,"info":""},{"id":"8b0cf8a1.a69ad8","type":"group","z":"463437f9.dd86a8","name":"Main Flow","style":{"stroke":"#92d04f","fill":"#e3f3d3","label":true,"label-position":"n","color":"#009919"},"nodes":["e80d35a8.6d7d1","d361885a.96a2c8","39f5c80b.08bad","b88f58bc.dff27","ec01ed4.c44cc9","ea1c2fda.2cda1"],"x":234,"y":319,"w":1172,"h":242},{"id":"d176b7eb.c2ce1","type":"group","z":"463437f9.dd86a8","name":"Global values","style":{"stroke":"#a4a4a4","label":true,"color":"#777777","fill":"#d1d1d1","label-position":"n"},"nodes":["f610cec.980f33","6f775291.3e5eac","f4413f57.6b66b","4ba5ce99.ee955","eec241fa.c4cb4"],"x":234,"y":119,"w":672,"h":182},{"id":"e80d35a8.6d7d1","type":"vertex action","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","name":"Motion sensor","typeButton":"motionsensor","bPayload":{"PRESENCE":{"action":"setbrightness","group":null,"param":"100","priority":"255"},"TRANSITION":{"action":"setbrightness","group":null,"param":"50","priority":"0"},"NOPRESENCE":{"action":"setbrightness","group":null,"param":"0","priority":"254"}},"bState":"","defaultpriority":true,"x":770,"y":440,"wires":[["ea1c2fda.2cda1"]]},{"id":"d361885a.96a2c8","type":"dali2devs","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","name":"Motion Sensor no1","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":350,"y":360,"wires":[["e80d35a8.6d7d1"]]},{"id":"39f5c80b.08bad","type":"dali2devs","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","name":"Motion Sensor no2","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":350,"y":440,"wires":[["e80d35a8.6d7d1"]]},{"id":"b88f58bc.dff27","type":"dali2devs","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","name":"Motion Sensor no3","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":350,"y":520,"wires":[["e80d35a8.6d7d1"]]},{"id":"f610cec.980f33","type":"es cct","z":"463437f9.dd86a8","g":"d176b7eb.c2ce1","name":"","startTime":"07:00","finishTime":"19:00","colorLevels":[6500,2700],"colorLabels":["07:00","19:00"],"brightnessLevels":[100,0],"brightnessLabels":["07:00","19:00"],"sendFrequencyInMinutes":1,"cctMin":2700,"cctMax":6500,"x":320,"y":160,"wires":[[],["f4413f57.6b66b"]]},{"id":"ec01ed4.c44cc9","type":"vertex cluster","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","rate":5,"x":1310,"y":440,"wires":[]},{"id":"ea1c2fda.2cda1","type":"function","z":"463437f9.dd86a8","g":"8b0cf8a1.a69ad8","name":"Set presence state brightness value","func":"if(msg.topic.includes(\"MOTIONSENSOR/PRESENCE\"))\n{\n for(var gr in msg.payload.parameter.value)\n {\n\t msg.payload.parameter.value[gr] = flow.get(\"level\");\n }\n return msg;\n}\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1040,"y":440,"wires":[["ec01ed4.c44cc9"]]},{"id":"4ba5ce99.ee955","type":"function","z":"463437f9.dd86a8","g":"d176b7eb.c2ce1","name":"","func":"\nfor(var gr in msg.payload.parameter.value){\n\t msg.payload=msg.payload.parameter.value[gr];\n}\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":260,"wires":[["6f775291.3e5eac"]]},{"id":"f4413f57.6b66b","type":"vertex action","z":"463437f9.dd86a8","g":"d176b7eb.c2ce1","name":"","typeButton":"directv","bPayload":{"action":"setbrightness","group":"02b2f16593e1a547148ffacde02898b2","param":0,"priority":"254"},"bState":"","defaultpriority":true,"x":470,"y":260,"wires":[["4ba5ce99.ee955"]]},{"id":"6f775291.3e5eac","type":"change","z":"463437f9.dd86a8","g":"d176b7eb.c2ce1","name":"level_logarithmic","rules":[{"t":"set","p":"level","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":260,"wires":[[]]},{"id":"eec241fa.c4cb4","type":"comment","z":"463437f9.dd86a8","g":"d176b7eb.c2ce1","name":"Conversion to logarithmic scale","info":"","x":630,"y":220,"wires":[]}]

This is an example flow related to Change node - Setting and triggering variables

Output of the node:

One of the above commands is sent directly to the vertex cluster node
OR
You can change its parameters halfway using the function node:

If the sensor detects presence, this function sets the brightness value to a global variable “level“.

//"Set the presence state brightnesss value" function code// if(msg.topic.includes("MOTIONSENSOR/PRESENCE")) { for(var gr in msg.payload.parameter.value) { msg.payload.parameter.value[gr] = flow.get("level"); } return msg; } return msg

Starting from software version 3.1.22 the topic structure has changed due to a new feature that allows to share motion sensor state across all Vertexes in a cluster. The topic now provides additional information about Vertex MAC address to distinguish the source of information.

Tricks & tips:

  • Fake sensor events:

By using the "Inject" block into Vertex action, you are able to fake the action of a sensor, for example, to maintain the "Presence" state even in the absence of physical movement.

You need to send a msg.payload of {"MSEVENT": 0, "UID": "FAKE1"}

NodeRed flow:

[{"id":"ad9350e1.02ae9","type":"tab","label":"Flow 22","disabled":false,"info":""},{"id":"e5af922f.d1ad4","type":"group","z":"ad9350e1.02ae9","name":"Injects simulating sensor events ","style":{"stroke":"#3f93cf","fill":"#bfdbef","label":true,"label-position":"n","color":"#0070c0"},"nodes":["5255a035.80381","4df3c9f4.c54c38","fc6ab9c7.9d54c8","ad84f038.8e2d","76240bf4.3375a4","a76c72a9.cffa2","bf0d6277.52521","47b4dc22.a62664"],"x":214,"y":219,"w":1112,"h":262},{"id":"5255a035.80381","type":"vertex action","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Motion sensor","typeButton":"motionsensor","bPayload":{"PRESENCE":{"action":"setbrightness","group":null,"param":"50","priority":"255"},"TRANSITION":{"action":"setbrightness","group":null,"param":"50","priority":"0"},"NOPRESENCE":{"action":"setbrightness","group":null,"param":"0","priority":"254"}},"bState":"","defaultpriority":true,"x":670,"y":340,"wires":[["47b4dc22.a62664"]]},{"id":"4df3c9f4.c54c38","type":"dali2devs","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Motion Sensor no1","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":330,"y":260,"wires":[["5255a035.80381"]]},{"id":"fc6ab9c7.9d54c8","type":"dali2devs","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Motion Sensor no2","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":330,"y":340,"wires":[["5255a035.80381"]]},{"id":"ad84f038.8e2d","type":"dali2devs","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Motion Sensor no3","uid":"00000003A4214709BC","dali2dev":"0","instanceType":3,"dali2t1":"10","dali2t2":"","mode":"","x":330,"y":420,"wires":[["5255a035.80381"]]},{"id":"76240bf4.3375a4","type":"vertex cluster","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","rate":5,"x":1230,"y":340,"wires":[]},{"id":"a76c72a9.cffa2","type":"inject","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Presence","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"MSEVENT\": 0, \"UID\": \"FAKE1\"}","payloadType":"json","x":640,"y":400,"wires":[["5255a035.80381"]]},{"id":"bf0d6277.52521","type":"inject","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"No presence","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"MSEVENT\": 2, \"UID\": \"FAKE1\"}","payloadType":"json","x":650,"y":440,"wires":[["5255a035.80381"]]},{"id":"47b4dc22.a62664","type":"function","z":"ad9350e1.02ae9","g":"e5af922f.d1ad4","name":"Set presence state brightness value","func":"if(msg.topic.includes(\"MOTIONSENSOR/PRESENCE\"))\n{\n for(var gr in msg.payload.parameter.value)\n {\n\t msg.payload.parameter.value[gr] = flow.get(\"level\");\n }\n return msg;\n}\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":340,"wires":[["76240bf4.3375a4"]]}]