Hey Glenn, it is a feature that has been specifically implemented into our Inovelli handlers. There is actually an App that is designed to work with our devices to simplify the association procedure.
I believe that if you want to submit the association directly from the device screen it would be in this format:
group number
nodes // as a map i.e. [01, 02]
action // (0 - remove, 1 - add)
multi-channel endpoint (optional) // ignore - not finished
The weird thing is that when I submit [01] through the App it is stored and processed correctly as a map. If I submit the same thing ([01]) through the device page it treats it as a string so it processes it as "[", "0", "1", "]"
Which causes it to error. I haven't figured that out yet.
If you wanted to make the Qubino driver compatible with the App then you would just need to add:
command "setAssociationGroup", ["number", "enum", "number", "number"] // group number, nodes, action (0 - remove, 1 - add), multi-channel endpoint (optional)
and this to "configure()"
def cmds = processAssociations()
return cmds
And these methods:
def setDefaultAssociations() {
def smartThingsHubID = zwaveHubNodeId.toString().format( '%02x', zwaveHubNodeId )
state.defaultG1 = [smartThingsHubID]
state.defaultG2 = [smartThingsHubID]
state.defaultG3 = []
}
def setAssociationGroup(group, nodes, action, endpoint = null){
log.debug nodes
log.debug action
if (!state."desiredAssociation${group}") {
state."desiredAssociation${group}" = nodes
} else {
switch (action) {
case 0:
state."desiredAssociation${group}" = state."desiredAssociation${group}" - nodes
break
case 1:
log.debug nodes
state."desiredAssociation${group}" = state."desiredAssociation${group}" + nodes
break
}
}
}
def processAssociations(){
def cmds = []
setDefaultAssociations()
def associationGroups = 5
if (state.associationGroups) {
associationGroups = state.associationGroups
} else {
log.debug "Getting supported association groups from device"
cmds << zwave.associationV2.associationGroupingsGet()
}
for (int i = 1; i <= associationGroups; i++){
if(state."actualAssociation${i}" != null){
if(state."desiredAssociation${i}" != null || state."defaultG${i}") {
def refreshGroup = false
((state."desiredAssociation${i}"? state."desiredAssociation${i}" : [] + state."defaultG${i}") - state."actualAssociation${i}").each {
log.debug "Adding node $it to group $i"
cmds << zwave.associationV2.associationSet(groupingIdentifier:i, nodeId:Integer.parseInt(it,16))
refreshGroup = true
}
((state."actualAssociation${i}" - state."defaultG${i}") - state."desiredAssociation${i}").each {
log.debug "Removing node $it from group $i"
cmds << zwave.associationV2.associationRemove(groupingIdentifier:i, nodeId:Integer.parseInt(it,16))
refreshGroup = true
}
if (refreshGroup == true) cmds << zwave.associationV2.associationGet(groupingIdentifier:i)
else log.debug "There are no association actions to complete for group $i"
}
} else {
log.debug "Association info not known for group $i. Requesting info from device."
cmds << zwave.associationV2.associationGet(groupingIdentifier:i)
}
}
return cmds
}
void zwaveEvent(hubitat.zwave.commands.associationv2.AssociationReport cmd) {
def temp = []
if (cmd.nodeId != []) {
cmd.nodeId.each {
temp += it.toString().format( '%02x', it.toInteger() ).toUpperCase()
}
}
state."actualAssociation${cmd.groupingIdentifier}" = temp
log.debug "Associations for Group ${cmd.groupingIdentifier}: ${temp}"
updateDataValue("associationGroup${cmd.groupingIdentifier}", "$temp")
}
def zwaveEvent(hubitat.zwave.commands.associationv2.AssociationGroupingsReport cmd) {
log.debug "Supported association groups: ${cmd.supportedGroupings}"
state.associationGroups = cmd.supportedGroupings
createEvent(name: "groups", value: cmd.supportedGroupings)
}