Possible to pass physicalgraph.device.HubAction object into zwave.securityV1.securityMessageEncapsulation().encapsulate() method?


Hello gentlemen,
i’m trying to issue a z-wave hubAction object into the security command’s encpasulation method, but receive errors because the hubAction object isn’t a command object like the rest of the implemented z-wave objects are.

Does anyone know if it’s possible to convert a hubAction object into a command object so that the encapsulation method will correctly convert it into security encapsulated frames?

Unfortunately i need to use hubAction to set a multichannel lifeline association to the device after inclusion and implementing it securely via raw bytes seems really really not worth it due to the complexity of the security command class.

(codersaur) #2

Hopefully, you shouldn’t need to do this anymore if you’ve seen my reply here.

However, the solution to this problem is easily discovered with a simple experiment:

def cmd = zwave.associationV2.associationRemove(groupingIdentifier:2, nodeId: [])
log.debug ("Command: ${cmd.format()}") 
// Outputs: "Command: 850402"
def secCmd = zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd)
log.debug ("Secure Command: ${secCmd.format()}")
// Outputs: "Secure Command: 988100850402"

Again, with another type of command:

def cmd = zwave.basicV1.basicSet(value: 0xFF)
log.debug ("Command: ${cmd.format()}") 
// Outputs: "Command: 2001FF"
def secCmd = zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd)
log.debug ("Secure Command: ${secCmd.format()}")
// Outputs: "Secure Command: 9881002001FF"

We can see that securityMessageEncapsulation() merely adds three bytes (98 81 00) to the front of the raw command. Looking up the definition of COMMAND_CLASS_SECURITY in the Z-Wave public spec…

… we can guess the meaning of the bytes:

  • 0x00 = Presumably this is a placeholder for the ‘Initialization Vector’ bytes…?
  • The remaining bytes are then the encapsulated command. I’m guessing the actual security encapsulation must only occur after the raw command is returned from parse().

In conclusion, if you want to build a raw command string and send it securely, simply prepend “988100” to the beginning of the raw command before passing to HubAction(). E.g. :

def unsecuredCmd = "8E0101000101"
cmds << physicalgraph.device.HubAction( "988100" + unsecuredCmd )



Thanks for the well structured reply @zcapr17 , i’ve decided against using raw commands for this due to encapsulation of commands (which now works flawlessly after reading the method you posted! Hats off to you sir!) which can stack on each other in case of multichannel/security/CRC command classes.