Zwave JS loop help

I currently have 3 zwave devices that I switch on with delay between them of a few seconds

The function node is as follows

if (msg.payload.directive == "TurnOn") {  // === means equals, both value and datatype ie 1 but not "1"
 var onoff = true
}
else if (msg.payload.directive == "TurnOff") {
var onoff = false
}
//var on = msg.payload /\*trigger\*/
const \_nodeId = 23;             /\* Target Node \*/
const \_value = onoff;            /\* Value \*/
const \_valueId = {
"commandClassname": "Binary Switch", 
"commandClass": 37,         /\* Binary Class \*/
"endpoint": 0,              /\* Target End point - The device might have 2 binary switches \*/
 "property": "targetValue",  /\* Property \*/
}
const Message = {
payload: {
 cmd: {
api: 'VALUE',
method: 'setValue'
 },
 cmdProperties: {
 nodeId: \_nodeId,
valueId: \_valueId,
value: \_value
 }
 }
}
return Message;

I the move to the second function one changing the Node ID and then the third.

Is there a way of just having one function and having the node id changing

Many thanks

Andrew

You should be able to send an array of ID's e.g [23,24,25]As @marcus-j-davies has allowed mutli casting in his nodes.

Or if you wamt a delay set up a loop ( for, forech, etc) and use node.send() rather than return, and delay each output of the function node with a delay set to rate limit. Writing Functions : Node-RED

Or use a split node and split the array of id,s and use the split payload in the same function node, you can rate limit each split message.

As mentioned above...

send 1 message, but set nodeId to an array of Device ID's

  • Providing all devices in the array support the same class / security (I think - but there might be magic in the driver to address that anyway)

You shouldn't need to loop / spread.
If multicasting isn't an option - refer to node.send()

Hi and thank you so much for your prompt reply.
Would you be able to expand on your responses with a brief outline of the requirements, i am fairly new to nodered.

Thank you in advance

Andrew

Hi @fogmajor

I have butchered your image.

And the function node that is left, use the following

/* Short hand for 'If its TurnOn = true else false' */
let Value = (msg.payload.directive === "TurnOn" ? true : false)

const Nodes = [3, 5, 7]          /* Your Target Nodes */

const ValueID = {
    "commandClass": 37,          /* Binary Class      */
    "endpoint": 0,               /* Target End point - */
    "property": "targetValue"    /* Property */
}

const Message = {
    payload: {
        cmd: {
            api: 'VALUE',
            method: 'setValue'
        },
        cmdProperties: {
            nodeId: Nodes,
            valueId: ValueID,
            value: Value
        }
    }
}
return Message

Sending an array (collection of Node ID's) : [1,2,3,4,5]
The Device Node will attempt to send a single message to all target nodes, instead of 3 messages to the network.

This is not a Node RED thing its a Marcus is great thing :wink:

  • It uses multicast to achieve it.
    • The stipulation is, the Target nodes, must support the same class (and I think Security class), so its trial and error - although I think the underlining driver does a lot here to address that)

Also..

Where you see commandClassName, propertyName its just metadata, not a required property

An array in javascript, is just that... an array of "things"
[Something, Something, Something, Something]

In the Device Node, it supports an array of Node IDs

Hi Marcus
May I take this opportunity to thank you for the basic and informative way you explained the solution. It works a treat there was no trial and error but it also taught me about arrays. Thank you for your input of Zwavejs.

As late father used to say "Every day is a school day"

Best wishes

Andrew

Hi there
Many thanks for taking the time trouble to answer my questions.

Best wishes

Andrew

Just a nice to know, if you use the property name as the object name, in javascript it will create the property names for you, eg:


const api = "VALUE"
const method = "setValue"

let value = (msg.payload.directive === "TurnOn" ? true : false)

const nodeId = [3, 5, 7]
const valueId = {
    "commandClass": 37,
    "endpoint": 0, 
    "property": "targetValue" 
}

const message = {
    payload: {
        cmd: { api, method },
        cmdProperties: { nodeId, valueId, value }
    }
}

return message

I am allergic to pascal case in javascript :')

Thank you very much, its good to know.

Best Wishes
Andrew