Syntax: How to delay a command?


(Simeon Simeonov) #1

I would like the gateway to send a command to the device with a desired delay:
I tried:
result << response(“delay 1200”)
cmds << “delay 1200”

but they don’t work.
The inial command I want to delay is:

result << response(zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, scaledConfigurationValue: 0).format())

What is the proper syntax/command to make the gateway to send the command with a delay?


(Robin) #2

delayBetween(cmds, 1200)

Look at the def refresh () section in the following example:

Maybe put a null command ahead of the one you want to send… probably a better way!!


(Robin) #3

Also:

mySwitch.on([delay: 1200])


(Simeon Simeonov) #4

The commands:
delayBetween(cmds, 1200)
mySwitch.on([delay: 1200])

also do not work. (when used in the method bellow, the "result"s do not send any z-wave commands)

def resultConfiguration() {
		def cmds = [] //added this just in case
		def result = []
        result << createEvent(name: "tamper", value: timeString , descriptionText: "$device.displayName was tampered")
        result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds:3600*wakeUpInterval, nodeid:zwaveHubNodeId).format())

I want to delay the 2nd “result” command.

What is a good practice for null commands?


(Robin) #5

response(delayBetween(result, 1200))


(Simeon Simeonov) #6

Still not working - putting this line in the method breaks the whole method. (no results are executed)


(Robin) #7

Sorry I’m all out of ideas… I’m a very very low level coder.

Hopefully one of the hardcore coders on here can help???


#8

I’ve been trying to achieve the same delay from within a zwaveEvent function call without luck.

So far i’ve tried:

 //SENDS COMMANDS
def cmds = []
cmds << response(zwave.associationV1.associationRemove(groupingIdentifier:1).format())
cmds << response(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format())
cmds << response(zwave.configurationV1.configurationGet(parameterNumber: 1).format())
return cmds


 //NOT SENDING CMDS AT ALL
def cmds = []
cmds << response(zwave.associationV1.associationRemove(groupingIdentifier:1).format())
cmds << response(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format())
cmds << response(zwave.configurationV1.configurationGet(parameterNumber: 1).format())
return delayBetween(cmds, 1000)

 //NOT SENDING CMDS AT ALL EITHER
def cmds = []
cmds << zwave.associationV1.associationRemove(groupingIdentifier:1).format()
cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
return delayBetween(cmds, 1000)


 //NOT SENDING COMMANDS EITHER
def cmds = []
cmds << response(zwave.associationV1.associationRemove(groupingIdentifier:1).format())
cmds << "delay 1000"
cmds << response(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format())
cmds << "delay 1000"
cmds << response(zwave.configurationV1.configurationGet(parameterNumber: 1).format())
return cmds


 //SENDS COMMANDS BUT DOESN'T DELAY THEM!
def cmds = []
cmds << response(zwave.associationV1.associationRemove(groupingIdentifier:1).format())
cmds << response("delay 1000")
cmds << response(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format())
cmds << response("delay 1000")
cmds << response(zwave.configurationV1.configurationGet(parameterNumber: 1).format())
return cmds
*

(codersaur) #9

The delays need to be inside the response() wrapper. Try:

def cmds = []
cmds << zwave.associationV1.associationRemove(groupingIdentifier:1).format()
cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
return response(delayBetween(cmds, 1000))

#10

EDIT: Thought i’ve solved it but the above example doesn’t seem to work on my end, from within a:

def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelEndPointReport cmd){
    def cmds = []
	cmds << zwave.associationV1.associationRemove(groupingIdentifier:1).format()
	cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1]).format()
	return response(delayBetween(cmds, 1000))
}

Doesn’t seem to send anything.


(codersaur) #11

hmm, I can’t see anything obviously wrong. Is there anything shown in IDE Live Logging?

Also, out of interest, why are you trying to create a multi-channel association for endpoint 1 of the hub?? (There shouldn’t be any need to do this as the hub doesn’t have any endpoints as such).


#12

I’ll give it another shot with some debug lines to see if it the flow stops somewhere and update the thread with a working solution once i find it.

Also, out of interest, why are you trying to create a multi-channel association for endpoint 1 of the hub?? (There shouldn’t be any need to do this as the hub doesn’t have any endpoints as such).

I’m trying to do this in order to let the device knows we’r working in a fully multichannel context and can push reports to the controller from separate endpoints. This is important when you’ve got a multichannel device with endpoints that send the same reports (for example configurable inputs), this lets the device send unsolicited reports from specific endpoints, via multichannel lifeline association, and you can then use source endpoint numbering to know which tile to update with data.

How and when a device should send unsolicited data (either directly from endpoints or through the root device on behalf of it’s endpoints) is defined by the z-wave protocol in relation to how the lifeline association was set up.

You can find more in-depth info in section 3.6 Multi Channel overview of the public specs here:


(codersaur) #13

Yes, but my point is that you shouldn’t need to add the hub as a multi-channel endpoint destination itself, a simple nodeId should suffice. I.e. you should be able to do the following and the hub should still receive unsolicited reports wrapped in MultiChannelEncap with an appropriate sourceEndpoint:

zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [zwaveHubNodeId])

If the device will only send MultiChannelEncap reports to other multi-channel endpoints, then this is probably a bug in the firmware.


(codersaur) #14

One other thought… what are you expecting to happen?

If you are waiting for a MultiChannelEndPointReport back as confirmation, then remember that a device won’t necessarily send a MultiChannelEndPointReport unless you explicitly request one using multiChannelAssociationGet().

Obviously, be careful not to do this from within the above zwaveEvent(…MultiChannelEndPointReport cmd) handler or you will create an infinite loop!


#15

The device sends unsolicited reports according to the table available in Multichannel Association CC v2 Compatibility section, in the previously linked document.

See image.

Judging from this, only EP to EP or Node to EP communication can be MC encapsulated (and as such can contain source and destination EP adressing).

The device in question has a z-wave certification entry so i doubt the certification house would miss something like this.


#16

One other thought… what are you expecting to happen?

If you are waiting for a MultiChannelEndPointReport back as confirmation, then remember that a device won’t necessarily send a MultiChannelEndPointReport unless you explicitly request one using multiChannelAssociationGet().

Obviously, be careful not to do this from within the above zwaveEvent(…MultiChannelEndPointReport cmd) handler or you will create an infinite loop!

Yep that’s clear to me, the rnumber of endpoints are first requested (in order to discover if the current configuration supports multichannel or not), the code in there is missing some internal logic for clarity’s sake, but the snippet is intended to run when a multichannel report stating the number of supported endpoints arrives. Once the device supports endpoints it makes sense to establish a multichannel lifeline association.

This convoluted way of handling endpoint discovery was implemented explicitely due to ST not having any property that would tell you if a device that the handler is executing for currently supports multichannel command class or not. ST’s approach pretty much handles only static devices.


(codersaur) #17

That’s interesting, it’s been my experience with other devices (like the Fibaro Dimmer 2) that they WILL send MultiChannelEncap to NodeIDs. I.e. (line 2) [End Point -> NodeId] is still Encapsulated. This seemed logical to me as it still allows information about the sourceEndpoint to be sent to non-multi-channel devices. As you have pointed out above though, this is actually not in strict adherence to the Z-wave standard.


(codersaur) #18

Can you just not look at the fingerprint or the zwaveInfo? (see my Z-Wave Tweaker).

// Parse fingerprint for supported command classes:
def ccIds = []
if (getZwaveInfo()?.cc) {
    logger("Device has new-style fingerprint: ${device.rawDescription}","info")
    ccIds = getZwaveInfo()?.cc + getZwaveInfo()?.sec
}
else {
    logger("Device has legacy fingerprint: ${device.rawDescription}","info")
    // Look for hexadecimal numbers (0x##) but remove the first one, which will be deviceID.
    ccIds = device.rawDescription.findAll(/0x\p{XDigit}+/)
    if (ccIds.size() > 0) { ccIds.remove(0) }
}
ccIds.removeAll([null])
// Check the device supports MULTI_CHANNEL:
if (ccIds.find( {it == "0x60" }) ) {
    // Supports MultiChannel...
}

#19

Thanks for the snippet @zcapr17 , it just might do the trick!

Unfortunately my knowledge of Z-Wave greatly exceeds my knowledge of ST’s platform.


#20

That’s interesting, it’s been my experience with other devices (like the Fibaro Dimmer 2) that they WILL send MultiChannelEncap to NodeIDs. I.e. (line 2) [End Point -> NodeId] is still Encapsulated. This seemed logical to me as it still allows information about the sourceEndpoint to be sent to non-multi-channel devices. As you have pointed out above though, this is actually not in strict adherence to the Z-wave standard.

I agree with your estimate about being logical, but as far as i know the protocol makers want to enforce stricter single/multi channel contexts due to legacy controllers that do not support multi channel command classes.