use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.
the class ZWaveNodeInitStageAdvancer method doStaticStages.
private void doStaticStages() {
setCurrentStage(ZWaveNodeInitStage.MANUFACTURER);
// Try and get the manufacturerSpecific command class.
ZWaveManufacturerSpecificCommandClass manufacturerSpecific = (ZWaveManufacturerSpecificCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_MANUFACTURER_SPECIFIC);
if (manufacturerSpecific != null) {
// If we already known the manufacturer information, then don't request again
if (manufacturerSpecific.getDeviceManufacturer() == Integer.MAX_VALUE) {
// If this node implements the Manufacturer Specific command
// class, we use it to get manufacturer info.
logger.debug("NODE {}: Node advancer: MANUFACTURER - send ManufacturerSpecific", node.getNodeId());
processTransaction(manufacturerSpecific.getManufacturerSpecificMessage());
if (initRunning == false) {
return;
}
}
}
setCurrentStage(ZWaveNodeInitStage.APP_VERSION);
ZWaveVersionCommandClass versionCommandClass = (ZWaveVersionCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_VERSION);
if (versionCommandClass == null) {
logger.debug("NODE {}: Node advancer: APP_VERSION - VERSION not supported", node.getNodeId());
// Notify the higher layers that we know this device now.
setCurrentStage(ZWaveNodeInitStage.DISCOVERY_COMPLETE);
} else {
// Request the version report for this node
logger.debug("NODE {}: Node advancer: APP_VERSION - send VersionMessage", node.getNodeId());
processTransaction(versionCommandClass.getVersionMessage());
if (initRunning == false) {
return;
}
// Notify the higher layers that we know this device now.
setCurrentStage(ZWaveNodeInitStage.DISCOVERY_COMPLETE);
setCurrentStage(ZWaveNodeInitStage.VERSION);
thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Node advancer: VERSION - thing is null!", node.getNodeId());
}
// Loop through all command classes, requesting their version
// using the Version command class
// We use a new list here so since command classes can be removed in the VERSION class
Collection<ZWaveCommandClass> classes = new ArrayList<ZWaveCommandClass>(node.getCommandClasses(0));
for (ZWaveCommandClass zwaveVersionClass : classes) {
logger.debug("NODE {}: Node advancer: VERSION - checking {}, version is {}", node.getNodeId(), zwaveVersionClass.getCommandClass(), zwaveVersionClass.getVersion());
// See if we want to force the version of this command class
if (thingType != null) {
Map<String, String> properties = thingType.getProperties();
for (Map.Entry<String, String> entry : properties.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
String[] cmds = key.split(":");
if ("commandClass".equals(cmds[0]) == false) {
continue;
}
String[] args = value.split("=");
if ("setVersion".equals(args[0])) {
if (zwaveVersionClass.getCommandClass().toString().equals(cmds[1])) {
logger.debug("NODE {}: Node advancer: VERSION - Set {} to Version {}", node.getNodeId(), CommandClass.getCommandClass(cmds[1]), args[1]);
// TODO: This ignores endpoint
try {
zwaveVersionClass.setVersion(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
logger.error("NODE {}: Node advancer: VERSION - number format exception {}", node.getNodeId(), args[1]);
}
}
}
}
}
if (zwaveVersionClass.getVersion() == 0) {
logger.debug("NODE {}: Node advancer: VERSION - queued {}", node.getNodeId(), zwaveVersionClass.getCommandClass());
processTransaction(versionCommandClass.checkVersion(zwaveVersionClass));
if (initRunning == false) {
return;
}
} else if (zwaveVersionClass.getVersion() == 0) {
logger.debug("NODE {}: Node advancer: VERSION - VERSION default to 1", node.getNodeId());
zwaveVersionClass.setVersion(1);
}
}
}
setCurrentStage(ZWaveNodeInitStage.ENDPOINTS);
// Try and get the multi instance / channel command class.
ZWaveMultiInstanceCommandClass multiInstance = (ZWaveMultiInstanceCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_MULTI_CHANNEL);
if (multiInstance != null) {
logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance is supported", node.getNodeId());
boolean first = true;
do {
logger.debug("NODE {}: MultiInstance init first={}", node.getNodeId(), first);
ArrayList<ZWaveCommandClassTransactionPayload> multiInstanceMessages = multiInstance.initEndpoints(first);
logger.debug("NODE {}: MultiInstance init returned {}", node.getNodeId(), multiInstanceMessages.size());
if (multiInstanceMessages.isEmpty()) {
break;
}
processTransactions(multiInstanceMessages);
if (initRunning == false) {
return;
}
first = false;
} while (true);
} else {
logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance not supported.", node.getNodeId());
// Set all classes to 1 instance.
for (ZWaveCommandClass commandClass : node.getCommandClasses(0)) {
commandClass.setInstances(1);
}
}
setCurrentStage(ZWaveNodeInitStage.UPDATE_DATABASE);
// This stage reads information from the database to allow us to modify the configuration
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE", node.getNodeId());
thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - thing is null!", node.getNodeId());
} else {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - check properties", node.getNodeId());
// We now should know all the command classes, so run through the database and set any options
Map<String, String> properties = thingType.getProperties();
for (Map.Entry<String, String> entry : properties.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - property {} == {}", node.getNodeId(), key, value);
String[] cmds = key.split(":");
if ("commandClass".equals(cmds[0]) == false) {
continue;
}
int endpoint = cmds.length == 2 ? 0 : Integer.parseInt(cmds[2]);
String[] options = value.split(",");
Map<String, String> optionMap = new HashMap<String, String>(1);
for (String option : options) {
String[] args = option.split("=");
if (args.length == 2) {
optionMap.put(args[0], args[1]);
} else {
optionMap.put(args[0], "");
}
}
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - optionmap {}", node.getNodeId(), optionMap);
if (optionMap.containsKey("ccRemove")) {
// If we want to remove the class, then remove it!
ZWaveEndpoint endpointForRemoval = node.getEndpoint(endpoint);
if (endpointForRemoval == null) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - endpoint null - unable to remove {}", node.getNodeId(), CommandClass.getCommandClass(cmds[1]));
} else {
endpointForRemoval.removeCommandClass(CommandClass.getCommandClass(cmds[1]));
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - removing {}", node.getNodeId(), CommandClass.getCommandClass(cmds[1]));
}
continue;
}
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - len {}", node.getNodeId(), cmds.length);
// TODO: Does this need to account for multiple endpoints!?!
if (optionMap.containsKey("ccAdd")) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - add", node.getNodeId());
ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(CommandClass.getCommandClass(cmds[1]).getKey(), node, controller);
if (commandClass != null) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - adding {}", node.getNodeId(), CommandClass.getCommandClass(cmds[1]));
node.getEndpoint(endpoint).addCommandClass(commandClass);
}
}
// Get the command class
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - endpoint {}", node.getNodeId(), endpoint);
if (node.getEndpoint(endpoint) != null) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - endpoint found {}", node.getNodeId(), endpoint);
CommandClass commandClass = CommandClass.getCommandClass(cmds[1]);
ZWaveCommandClass zwaveClass = node.getEndpoint(endpoint).getCommandClass(commandClass);
// If we found the command class, then set its options
if (zwaveClass != null) {
zwaveClass.setOptions(optionMap);
continue;
}
}
}
}
setCurrentStage(ZWaveNodeInitStage.STATIC_VALUES);
// Update all dynamic information from command classes
for (int endpointId = 0; endpointId < node.getEndpointCount(); endpointId++) {
for (ZWaveCommandClass zwaveStaticClass : node.getCommandClasses(endpointId)) {
// The device only sends commands
if (zwaveStaticClass.isControlClass()) {
continue;
}
if (endpointId == 0) {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {}", node.getNodeId(), zwaveStaticClass.getCommandClass());
} else {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {} for endpoint {}", node.getNodeId(), zwaveStaticClass.getCommandClass(), endpointId);
}
if (!(zwaveStaticClass instanceof ZWaveCommandClassInitialization)) {
continue;
}
ZWaveCommandClassInitialization zdds = (ZWaveCommandClassInitialization) zwaveStaticClass;
int instances = zwaveStaticClass.getInstances();
logger.debug("NODE {}: Found {} instances of {} for endpoint {}", node.getNodeId(), instances, zwaveStaticClass.getCommandClass(), endpointId);
if (instances == 1) {
processTransactions(zdds.initialize(true), endpointId);
if (initRunning == false) {
return;
}
} else {
for (int i = 1; i <= instances; i++) {
processTransactions(zdds.initialize(true), i);
if (initRunning == false) {
return;
}
}
}
}
}
setCurrentStage(ZWaveNodeInitStage.ASSOCIATIONS);
// Do we support associations
ZWaveMultiAssociationCommandClass multiAssociationCommandClass = (ZWaveMultiAssociationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION);
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_ASSOCIATION);
if (multiAssociationCommandClass != null || associationCommandClass != null) {
thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Node advancer: ASSOCIATIONS - thing is null!", node.getNodeId());
} else {
ConfigDescription config = ZWaveConfigProvider.getThingTypeConfig(thingType);
if (config == null) {
logger.debug("NODE {}: Node advancer: ASSOCIATIONS - no configuration!", node.getNodeId());
} else {
for (ConfigDescriptionParameter parm : config.getParameters()) {
String[] cfg = parm.getName().split("_");
if ("group".equals(cfg[0])) {
int group = Integer.parseInt(cfg[1]);
logger.debug("NODE {}: Node advancer: ASSOCIATIONS request group {}", node.getNodeId(), group);
processTransaction(node.getAssociation(group));
if (initRunning == false) {
return;
}
}
}
}
}
}
setCurrentStage(ZWaveNodeInitStage.SET_WAKEUP);
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_WAKE_UP);
// It sets the node to point to us, and the time is left along
if (controller.isMasterController() == true && wakeupCommandClass != null) {
if (wakeupCommandClass.getTargetNodeId() == controller.getOwnNodeId()) {
logger.debug("NODE {}: Node advancer: SET_WAKEUP - TargetNode is set to controller", node.getNodeId());
} else {
int value = controller.getSystemDefaultWakeupPeriod();
if (wakeupCommandClass.getInterval() == 0 && value != 0) {
logger.debug("NODE {}: Node advancer: SET_WAKEUP - Interval is currently 0. Set to {}", node.getNodeId(), value);
} else {
value = wakeupCommandClass.getInterval();
}
logger.debug("NODE {}: Node advancer: SET_WAKEUP - Set wakeup node to controller ({}), period {}", node.getNodeId(), controller.getOwnNodeId(), value);
// Set the wake-up interval, and request an update
processTransaction(wakeupCommandClass.setInterval(controller.getOwnNodeId(), value));
if (initRunning == false) {
return;
}
processTransaction(wakeupCommandClass.getIntervalMessage());
if (initRunning == false) {
return;
}
}
}
setCurrentStage(ZWaveNodeInitStage.SET_ASSOCIATION);
if (controller.isMasterController() == true) {
if (multiAssociationCommandClass == null && associationCommandClass == null) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION class not supported", node.getNodeId());
} else {
thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - thing is null!", node.getNodeId());
} else {
String associations = thingType.getProperties().get(ZWaveBindingConstants.PROPERTY_XML_ASSOCIATIONS);
if (associations == null || associations.length() == 0) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - no default associations", node.getNodeId());
} else {
ZWaveAssociation association;
if (multiAssociationCommandClass != null) {
association = new ZWaveAssociation(controller.getOwnNodeId(), 1);
} else {
association = new ZWaveAssociation(controller.getOwnNodeId());
}
String[] defaultGroups = associations.split(",");
for (int c = 0; c < defaultGroups.length; c++) {
int groupId = Integer.parseInt(defaultGroups[c]);
// We should know about all groups at this stage.
// If we don't know about the group, then assume it doesn't exist
ZWaveAssociationGroup associationGroup = node.getAssociationGroup(groupId);
if (associationGroup == null) {
continue;
}
// Check if we're already a member
if (associationGroup.isAssociated(association)) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION {} set for group {}", node.getNodeId(), association, groupId);
} else {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - Adding ASSOCIATION {} to group {}", node.getNodeId(), association, groupId);
// Set the association, and request the update so we confirm if it's set
processTransaction(node.setAssociation(groupId, association));
if (initRunning == false) {
return;
}
processTransaction(node.getAssociation(groupId));
if (initRunning == false) {
return;
}
}
}
}
}
}
}
setCurrentStage(ZWaveNodeInitStage.SET_LIFELINE);
if (controller.isMasterController() == true) {
if (multiAssociationCommandClass == null && associationCommandClass == null) {
logger.debug("NODE {}: Node advancer: SET_LIFELINE - ASSOCIATION class not supported", node.getNodeId());
} else {
ZWaveAssociation association;
if (multiAssociationCommandClass != null) {
association = new ZWaveAssociation(controller.getOwnNodeId(), 1);
} else {
association = new ZWaveAssociation(controller.getOwnNodeId());
}
Collection<ZWaveAssociationGroup> associations = node.getAssociationGroups().values();
for (ZWaveAssociationGroup associationGroup : associations) {
logger.debug("NODE {}: Node advancer: SET_LIFELINE - Checking group {}", node.getNodeId(), associationGroup.getIndex());
// Check if this is the lifeline profile
if (associationGroup.getProfile1() != 0x00 || associationGroup.getProfile2() != 0x01) {
continue;
}
// Check if we're already a member
if (associationGroup.isAssociated(association)) {
logger.debug("NODE {}: Node advancer: SET_LIFELINE - ASSOCIATION {} already set for group {}", node.getNodeId(), association, associationGroup.getIndex());
break;
}
// Check if there's another node set
if (associationGroup.getAssociationCnt() != 0) {
logger.debug("NODE {}: Node advancer: SET_LIFELINE - ASSOCIATION clearing group {}", node.getNodeId(), associationGroup.getIndex());
processTransaction(node.clearAssociation(associationGroup.getIndex()));
if (initRunning == false) {
return;
}
}
logger.debug("NODE {}: Node advancer: SET_LIFELINE - Adding ASSOCIATION {} to group {}", node.getNodeId(), association, associationGroup.getIndex());
// Set the association, and request the update so we confirm if it's set
processTransaction(node.setAssociation(associationGroup.getIndex(), association));
if (initRunning == false) {
return;
}
processTransaction(node.getAssociation(associationGroup.getIndex()));
if (initRunning == false) {
return;
}
break;
}
}
} else {
logger.debug("NODE {}: Node advancer: SET_LIFELINE - not configured as not master", node.getNodeId());
}
setCurrentStage(ZWaveNodeInitStage.GET_CONFIGURATION);
ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_CONFIGURATION);
// If the node doesn't support configuration class, then we better let people know!
if (configurationCommandClass == null) {
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - CONFIGURATION class not supported", node.getNodeId());
} else {
thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - thing is null!", node.getNodeId());
} else {
ConfigDescription cfgConfig = ZWaveConfigProvider.getThingTypeConfig(thingType);
if (cfgConfig == null) {
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - no configuration!", node.getNodeId());
} else {
// Due to subparameters, we keep track of what we've sent to avoid sending duplicate requests
ArrayList<Integer> paramSent = new ArrayList<Integer>();
for (ConfigDescriptionParameter parm : cfgConfig.getParameters()) {
String[] cfg = parm.getName().split("_");
if ("config".equals(cfg[0])) {
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - checking {} - config", node.getNodeId(), parm.getName());
int index = Integer.parseInt(cfg[1]);
int size = Integer.parseInt(cfg[2]);
// Some parameters don't return anything, so don't request them!
if (Arrays.asList(cfg).contains("wo")) {
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - checking {} - wo", node.getNodeId(), parm.getName());
configurationCommandClass.setParameterWriteOnly(index, size, true);
continue;
}
// See if we've already sent this param
if (paramSent.contains(index)) {
continue;
}
paramSent.add(index);
// If this is the first time around the loop
// or we don't have a value for this parameter
// then request it!
logger.debug("NODE {}: Node advancer: GET_CONFIGURATION - checking {} - index {}", node.getNodeId(), parm.getName(), index);
if (configurationCommandClass.getParameter(index) == null) {
processTransaction(configurationCommandClass.getConfigMessage(index));
if (initRunning == false) {
return;
}
}
}
}
}
}
}
}
Aggregations