Skip to content

Commit

Permalink
Zwave association refactor and consolidation (openhab#893)
Browse files Browse the repository at this point in the history
* ZWave refactor and consolidate association command classes

Signed-off-by: Chris Jackson <chris@cd-jackson.com>
  • Loading branch information
cdjackson authored and doubled-ca committed Aug 14, 2016
1 parent 2754483 commit 88b6745
Show file tree
Hide file tree
Showing 14 changed files with 672 additions and 421 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.openhab.binding.zwave.test.internal.protocol;

import static org.junit.Assert.*;

import org.junit.Test;
import org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup;

public class ZWaveAssociationGroupTest {
@Test
public void TestAssociationGroup() {
ZWaveAssociationGroup group = new ZWaveAssociationGroup(1);

group.addAssociation(1);
assertEquals(1, group.getAssociationCnt());
assertTrue(group.isAssociated(1, 0));

group.addAssociation(1, 0);
assertEquals(1, group.getAssociationCnt());

group.addAssociation(3, 2);
assertEquals(2, group.getAssociationCnt());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.openhab.binding.zwave.internal.protocol.SerialMessage;
import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass;
import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType;
import org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup;
import org.openhab.binding.zwave.internal.protocol.ZWaveNode;
import org.openhab.binding.zwave.internal.protocol.ZWaveSerialMessageException;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass;
Expand All @@ -29,6 +30,7 @@
* Test cases for {@link ZWaveAssociationGroupInfoCommandClass}.
*
* @author Jorg de Jong - Initial version
* @author Chris Jackson
*/
public class ZWaveAssociationGroupInfoCommandClassTest {

Expand All @@ -46,8 +48,12 @@ public void applicationCommands() {
byte[] groupCommands = { 0x01, 0x16, 0x00, 0x04, 0x00, 0x0A, 0x10, 0x59, 0x06, 0x01, 0x0C, 0x26, 0x03, 0x5A,
0x01, 0x2B, 0x01, 0x31, 0x05, 0x32, 0x02, 0x71, 0x05, (byte) 0x81 };

ZWaveAssociationGroup group = new ZWaveAssociationGroup(1);

// setup mocks
ZWaveNode node = mock(ZWaveNode.class);
when(node.getAssociationGroup(1)).thenReturn(group);

ZWaveCommandClass reset = ZWaveCommandClass.getInstance(CommandClass.DEVICE_RESET_LOCALLY.getKey(), node, null);
when(node.getCommandClass(Matchers.eq(CommandClass.DEVICE_RESET_LOCALLY))).thenReturn(reset);

Expand All @@ -59,13 +65,11 @@ public void applicationCommands() {
processCommandClassMessages(cls, Arrays.asList(new SerialMessage(groupName), new SerialMessage(groupProfile),
new SerialMessage(groupCommands)));

// see if we got the expected results
assertNotNull(cls.getGroupInfo());
assertEquals("Lifeline", cls.getGroupInfo().get(1).getName());
assertEquals(Integer.valueOf(1), cls.getGroupInfo().get(1).getProfile());
assertEquals(false, cls.getGroupInfo().get(1).getCommands().isEmpty());
assertEquals(false,
cls.getGroupInfo().get(1).getCommands().contains(CommandClass.DEVICE_RESET_LOCALLY.getKey()));
// See if we got the expected results
assertEquals("Lifeline", group.getName());
assertEquals(Integer.valueOf(1), group.getProfile());
assertEquals(false, group.getCommandClasses().isEmpty());
assertEquals(false, group.getCommandClasses().contains(CommandClass.DEVICE_RESET_LOCALLY.getKey()));
assertEquals(true, cls.getAutoSubscribeGroups().contains(1));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Copyright (c) 2014-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.zwave.test.internal.protocol.commandclass;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;
import org.openhab.binding.zwave.internal.protocol.SerialMessage;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiAssociationCommandClass;
import org.openhab.binding.zwave.internal.protocol.event.ZWaveAssociationEvent;
import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent;

/**
* Test cases for {@link ZWaveMultiAssociationCommandClass}.
*
* @author Chris Jackson - Initial version
*/
public class ZWaveMultiAssociationCommandClassTest extends ZWaveCommandClassTest {

@Test
public void getAssociationMessage() {
ZWaveMultiAssociationCommandClass cls = (ZWaveMultiAssociationCommandClass) getCommandClass(
CommandClass.MULTI_INSTANCE_ASSOCIATION);
SerialMessage msg;

byte[] expectedResponseV1 = { 1, 10, 0, 19, 99, 3, -114, 2, 1, 0, 4, 15 };
cls.setVersion(1);
msg = cls.getAssociationMessage(1);
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponseV1));
}

@Test
public void getGroupingsMessage() {
ZWaveMultiAssociationCommandClass cls = (ZWaveMultiAssociationCommandClass) getCommandClass(
CommandClass.MULTI_INSTANCE_ASSOCIATION);
SerialMessage msg;

byte[] expectedResponseV1 = { 1, 9, 0, 19, 99, 2, -114, 5, 0, 4, 11 };
cls.setVersion(1);
msg = cls.getGroupingsMessage();
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponseV1));
}

@Test
public void removeAssociationMessage() {
ZWaveMultiAssociationCommandClass cls = (ZWaveMultiAssociationCommandClass) getCommandClass(
CommandClass.MULTI_INSTANCE_ASSOCIATION);
SerialMessage msg;

byte[] expectedResponse1 = { 1, 11, 0, 19, 99, 4, -114, 4, 1, 2, 0, 4, 13 };
byte[] expectedResponse2 = { 1, 13, 0, 19, 99, 6, -114, 4, 1, 0, 2, 3, 0, 4, 10 };

cls.setVersion(1);
msg = cls.removeAssociationMessage(1, 2, 0);
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponse1));

msg = cls.removeAssociationMessage(1, 2, 3);
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponse2));
}

@Test
public void setAssociationMessage() {
ZWaveMultiAssociationCommandClass cls = (ZWaveMultiAssociationCommandClass) getCommandClass(
CommandClass.MULTI_INSTANCE_ASSOCIATION);
SerialMessage msg;

byte[] expectedResponse1 = { 1, 11, 0, 19, 99, 4, -114, 1, 1, 2, 0, 4, 8 };
byte[] expectedResponse2 = { 1, 13, 0, 19, 99, 6, -114, 1, 1, 0, 2, 3, 0, 4, 15 };

cls.setVersion(1);
msg = cls.setAssociationMessage(1, 2, 0);
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponse1));

msg = cls.setAssociationMessage(1, 2, 3);
msg.setCallbackId(4);
assertTrue(Arrays.equals(msg.getMessageBuffer(), expectedResponse2));
}

@Test
public void AssociationReport() {
byte[] packetData = { 0x01, 0x0E, 0x00, 0x04, 0x00, 0x03, 0x08, (byte) 0x8E, 0x03, 0x02, 0x10, 0x00, 0x00, 0x01,
0x01, 0x61 };

List<ZWaveEvent> events = processCommandClassMessage(packetData);

assertEquals(events.size(), 1);

ZWaveAssociationEvent event = (ZWaveAssociationEvent) events.get(0);

assertEquals(event.getCommandClass(), CommandClass.ASSOCIATION);
// assertEquals(event.getNodeId(), 3);
assertEquals(event.getEndpoint(), 0);
assertEquals(event.getGroupId(), 2);
assertEquals(event.getGroupMembers().size(), 1);
assertEquals(event.getGroupMembers().get(0).getNode(), 1);
assertEquals(event.getGroupMembers().get(0).getEndpoint(), 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass.ZWaveConfigurationParameterEvent;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveDoorLockCommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiAssociationCommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNodeNamingCommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWavePlusCommandClass;
import org.openhab.binding.zwave.internal.protocol.commandclass.ZWavePowerLevelCommandClass;
Expand Down Expand Up @@ -586,12 +587,11 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter

Integer groupIndex = Integer.valueOf(cfg[1]);

// Get the association command class
// Get the association command class - we'll use the multi_instance version if it exists.
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node
.getCommandClass(CommandClass.ASSOCIATION);
// ZWaveAssociationCommandClass associationCommandClassMulti = (ZWaveAssociationCommandClass)
// node
// .getCommandClass(CommandClass.ASSOCIATION);
ZWaveMultiAssociationCommandClass associationCommandClassMulti = (ZWaveMultiAssociationCommandClass) node
.getCommandClass(CommandClass.MULTI_INSTANCE_ASSOCIATION);

// Get the configuration information.
// This should be an array of nodes, and/or nodes and endpoints
Expand All @@ -603,7 +603,7 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
paramValues.add((String) parameter);
}

ZWaveAssociationGroup currentMembers = associationCommandClass.getGroupMembers(groupIndex);
ZWaveAssociationGroup currentMembers = node.getAssociationGroup(groupIndex);
ZWaveAssociationGroup newMembers = new ZWaveAssociationGroup(groupIndex);

// Loop over all the parameters
Expand All @@ -627,8 +627,13 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
// Is the current association still in the newMembers list?
if (newMembers.isAssociated(member.getNode(), member.getEndpoint()) == false) {
// No - so it needs to be removed
controllerHandler.sendData(
associationCommandClass.removeAssociationMessage(groupIndex, member.getNode()));
if (associationCommandClassMulti != null) {
controllerHandler.sendData(associationCommandClassMulti.removeAssociationMessage(groupIndex,
member.getNode(), member.getEndpoint()));
} else {
controllerHandler.sendData(
associationCommandClass.removeAssociationMessage(groupIndex, member.getNode()));
}
}
}

Expand All @@ -637,13 +642,22 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
// Is the new association still in the currentMembers list?
if (currentMembers.isAssociated(member.getNode(), member.getEndpoint()) == false) {
// No - so it needs to be added
controllerHandler
.sendData(associationCommandClass.setAssociationMessage(groupIndex, member.getNode()));
if (associationCommandClassMulti != null) {
controllerHandler.sendData(associationCommandClassMulti.setAssociationMessage(groupIndex,
member.getNode(), member.getEndpoint()));
} else {
controllerHandler.sendData(
associationCommandClass.setAssociationMessage(groupIndex, member.getNode()));
}
}
}

// Request an update to the association group
controllerHandler.sendData(associationCommandClass.getAssociationMessage(groupIndex));
if (associationCommandClassMulti != null) {
controllerHandler.sendData(associationCommandClassMulti.getAssociationMessage(groupIndex));
} else {
controllerHandler.sendData(associationCommandClass.getAssociationMessage(groupIndex));
}
pendingCfg.put(configurationParameter.getKey(), valueObject);
} else if ("wakeup".equals(cfg[0])) {
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node
Expand Down Expand Up @@ -1315,22 +1329,17 @@ private void updateNodeProperties() {
}

// Process ASSOCIATION
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node
.getCommandClass(CommandClass.ASSOCIATION);
if (associationCommandClass != null) {
for (int groupId : associationCommandClass.getAssociations().keySet()) {
List<String> group = new ArrayList<String>();

// Build the configuration value
for (ZWaveAssociation groupMember : associationCommandClass.getGroupMembers(groupId)
.getAssociations()) {
logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding node_{}_{}", nodeId, groupId,
groupMember.getNode(), groupMember.getEndpoint());
group.add("node_" + groupMember.getNode() + "_" + groupMember.getEndpoint());
}

config.put("group_" + groupId, group);
for (ZWaveAssociationGroup group : node.getAssociationGroups().values()) {
List<String> members = new ArrayList<String>();

// Build the configuration value
for (ZWaveAssociation groupMember : group.getAssociations()) {
logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding node_{}_{}", nodeId, group,
groupMember.getNode(), groupMember.getEndpoint());
members.add("node_" + groupMember.getNode() + "_" + groupMember.getEndpoint());
}

config.put("group_" + group, members);
}

// Process WAKE_UP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ public boolean equals(Object checker) {
}
return false;
}
}
}
Loading

0 comments on commit 88b6745

Please sign in to comment.