Skip to content

Commit

Permalink
Force associations in specific circumstances
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <[email protected]>
  • Loading branch information
cdjackson committed Dec 30, 2018
1 parent 55622d0 commit f11db5f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,10 @@ public boolean healNode(int nodeId) {
return true;
}

public boolean isControllerMaster() {
return isMaster;
}

private void updateNeighbours() {
if (controller == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.ThingStatusInfo;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.ConfigStatusThingHandler;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.eclipse.smarthome.core.thing.type.ThingType;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.types.State;
Expand Down Expand Up @@ -84,17 +84,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Sets;

/**
* Thing Handler for ZWave devices
*
* @author Chris Jackson - Initial contribution
*
*/
public class ZWaveThingHandler extends ConfigStatusThingHandler implements ZWaveEventListener {
public final static Set<ThingTypeUID> SUPPORTED_THING_TYPES = Sets.newHashSet();

private final Logger logger = LoggerFactory.getLogger(ZWaveThingHandler.class);

private ZWaveControllerHandler controllerHandler;
Expand Down Expand Up @@ -685,7 +681,21 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
if (parameter instanceof List) {
paramValues.addAll((List) configurationParameter.getValue());
} else if (parameter instanceof String) {
paramValues.add((String) parameter);
String strParam = ((String) parameter).trim();
// Some UIs seem to be sending arrays as strings!!!
// It's a kludge, but let's try and handle this format...
if (strParam.startsWith("[") && strParam.endsWith("]")) {
strParam = strParam.substring(1, strParam.length() - 1);

if (strParam.contains(",")) {
String[] splits = strParam.split(",");
for (String split : splits) {
paramValues.add(split.trim());
}
}
} else {
paramValues.add(strParam);
}
}

ZWaveAssociationGroup currentMembers = node.getAssociationGroup(groupIndex);
Expand All @@ -695,8 +705,6 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
}
logger.debug("NODE {}: Current Members {}", nodeId, currentMembers);

logger.debug("NODE {}: Current Members {}", nodeId, currentMembers);

ZWaveAssociationGroup newMembers = new ZWaveAssociationGroup(groupIndex);
int totalMembers = currentMembers.getAssociationCnt();

Expand All @@ -710,7 +718,7 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter

// Make sure this is a correctly formatted option
if (!"node".equals(groupCfg[0])) {
logger.debug("NODE {}: Invalid association {}", nodeId, paramValue);
logger.debug("NODE {}: Invalid association {} ({})", nodeId, paramValue, groupCfg[0]);
continue;
}

Expand Down Expand Up @@ -756,6 +764,33 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
}
}

if (controllerHandler.isControllerMaster()) {
logger.debug("NODE {}: Controller is master - forcing associations", nodeId);
// Check if this is the lifeline profile
if (newMembers.getProfile1() == 0x00 && newMembers.getProfile2() == 0x01) {
logger.debug("NODE {}: Group is lifeline - forcing association", nodeId);
newMembers.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
}

ThingType thingType = ZWaveConfigProvider.getThingType(node);
if (thingType == null) {
logger.debug("NODE {}: Thing type not found for association check", node.getNodeId());
} else {
String associations = thingType.getProperties()
.get(ZWaveBindingConstants.PROPERTY_XML_ASSOCIATIONS);
if (associations == null || associations.length() == 0) {
logger.debug("NODE {}: Thing has no default associations", node.getNodeId());
} else {
String defaultGroups[] = associations.split(",");
if (Arrays.asList(defaultGroups).contains(cfg[1])) {
logger.debug("NODE {}: Group is controller - forcing association", nodeId);
newMembers
.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
}
}
}
}

// If there are no known associations in the group, then let's clear the group completely
// This ensures we don't end up with strange ghost associations
if (totalMembers == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ private ZWaveThingHandler doConfigurationUpdate(String param, Object value) {
ZWaveController controller = Mockito.mock(ZWaveController.class);
ZWaveControllerHandler controllerHandler = Mockito.mock(ZWaveControllerHandler.class);

Mockito.when(controllerHandler.isControllerMaster()).thenReturn(false);

ThingHandlerCallback thingCallback = Mockito.mock(ThingHandlerCallback.class);
ZWaveThingHandler thingHandler = new ZWaveThingHandlerForTest(thing);
thingHandler.setCallback(thingCallback);
Expand All @@ -82,7 +84,6 @@ private ZWaveThingHandler doConfigurationUpdate(String param, Object value) {
ZWaveNodeNamingCommandClass namingClass = new ZWaveNodeNamingCommandClass(node, controller, null);

Mockito.doNothing().when(node).sendMessage(payloadCaptor.capture());
Mockito.doNothing().when(thingCallback).thingUpdated(Matchers.any(Thing.class));

fieldControllerHandler = ZWaveThingHandler.class.getDeclaredField("controllerHandler");
fieldControllerHandler.setAccessible(true);
Expand Down Expand Up @@ -225,4 +226,15 @@ public void testConfigurationAssociationEndpoint() {
// Note that these are currently null due to mocking
assertEquals(2, response.size());
}

@Test
public void testConfigurationAssociationStringArray() {
List<ZWaveCommandClassTransactionPayload> response = doConfigurationUpdateCommands("group_1", "[node_1]");

// Check that there are only 2 requests - the SET and GET
// Note that these are currently null due to mocking
assertEquals(2, response.size());

response = doConfigurationUpdateCommands("group_1", "[node_1, node_2_1, node_2]");
}
}

0 comments on commit f11db5f

Please sign in to comment.