Skip to content

Commit

Permalink
Add cluster tests (openhab#47)
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <[email protected]>
  • Loading branch information
cdjackson authored Jul 5, 2017
1 parent 0d177ec commit 12ca951
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Future;

import org.apache.commons.lang.StringUtils;

Expand Down Expand Up @@ -114,8 +115,11 @@ public ZigBeeConsole(final ZigBeeNetworkManager networkManager, final ZigBeeTran
commands.put("unlisten", new UnlistenCommand());
commands.put("subscribe", new SubscribeCommand());
commands.put("unsubscribe", new UnsubscribeCommand());

commands.put("read", new ReadCommand());
commands.put("write", new WriteCommand());
commands.put("reportcfg", new ReportConfigCommand());

commands.put("join", new JoinCommand());
commands.put("lqi", new LqiCommand());
commands.put("warn", new WarnCommand());
Expand Down Expand Up @@ -1544,7 +1548,8 @@ public boolean process(final ZigBeeApi zigbeeApi, final String[] args, PrintStre

final int statusCode = response.getRecords().get(0).getStatus();
if (statusCode == 0) {
out.println("Attribute " + response.getRecords().get(0).getAttributeIdentifier() + ", type "
out.println("Cluster " + response.getClusterId() + ", Attribute "
+ response.getRecords().get(0).getAttributeIdentifier() + ", type "
+ response.getRecords().get(0).getAttributeDataType() + ", value: "
+ response.getRecords().get(0).getAttributeValue());
} else {
Expand Down Expand Up @@ -1633,6 +1638,83 @@ public boolean process(final ZigBeeApi zigbeeApi, final String[] args, PrintStre
}
}

/**
* Reads an attribute from a device.
*/
private class ReportConfigCommand implements ConsoleCommand {
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return "Read the report configuration of an attribute.";
}

/**
* {@inheritDoc}
*/
@Override
public String getSyntax() {
return "reportcfg [DEVICE] [CLUSTER] [ATTRIBUTE]";
}

/**
* {@inheritDoc}
*/
@Override
public boolean process(final ZigBeeApi zigbeeApi, final String[] args, PrintStream out) throws Exception {
if (args.length != 4) {
return false;
}

final int clusterId;
try {
clusterId = Integer.parseInt(args[2]);
} catch (final NumberFormatException e) {
return false;
}
final int attributeId;
try {
attributeId = Integer.parseInt(args[3]);
} catch (final NumberFormatException e) {
return false;
}

final ZigBeeDevice device = getDevice(zigbeeApi, args[1]);
if (device == null) {
print("Device not found.", out);
return false;
}
ZclCluster cluster = device.getCluster(clusterId);

ZclAttribute attribute = cluster.getAttribute(attributeId);

final Future<CommandResult> future = cluster.getReporting(attribute);
CommandResult result = future.get();

if (result.isSuccess()) {
final ReadAttributesResponse response = result.getResponse();

final int statusCode = response.getRecords().get(0).getStatus();
if (statusCode == 0) {
out.println("Cluster " + response.getClusterId() + ", Attribute "
+ response.getRecords().get(0).getAttributeIdentifier() + ", type "
+ response.getRecords().get(0).getAttributeDataType() + ", value: "
+ response.getRecords().get(0).getAttributeValue());
} else {
final ZclStatus status = ZclStatus.getStatus((byte) statusCode);
out.println("Attribute value read error: " + status);
}

return true;
} else {
out.println("Error executing command: " + result.getMessage());
return true;
}

}
}

/**
* Writes an attribute to a device.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public ZclAttribute(final ZclClusterType cluster, final int id, final String nam

/**
* Gets the {@link ZclClusterType} to which this attribute belongs
*
*
* @return the {@link ZclClusterType} for this attribute
*/
public ZclClusterType getCluster() {
Expand Down Expand Up @@ -300,7 +300,20 @@ public void updateValue(Object attributeValue) {

@Override
public String toString() {
return "ZclAttribute [id=" + id + ", name=" + name + ", dataType=" + dataType + ", lastValue=" + lastValue
+ "]";
StringBuilder builder = new StringBuilder();

builder.append("ZclAttribute [cluster=");
builder.append(cluster);
builder.append(", id=");
builder.append(id);
builder.append(", name=");
builder.append(name);
builder.append(", dataType=");
builder.append(dataType);
builder.append(", lastValue=");
builder.append(lastValue);
builder.append(']');

return builder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.zsmartsystems.zigbee.internal.NotificationService;
import com.zsmartsystems.zigbee.zcl.clusters.general.ConfigureReportingCommand;
import com.zsmartsystems.zigbee.zcl.clusters.general.ReadAttributesResponse;
import com.zsmartsystems.zigbee.zcl.clusters.general.ReadReportingConfigurationCommand;
import com.zsmartsystems.zigbee.zcl.field.AttributeRecord;
import com.zsmartsystems.zigbee.zcl.field.AttributeReport;
import com.zsmartsystems.zigbee.zcl.field.AttributeReportingConfigurationRecord;
import com.zsmartsystems.zigbee.zcl.field.ReadAttributeStatusRecord;
Expand Down Expand Up @@ -190,6 +192,24 @@ public Future<CommandResult> setReporting(final ZclAttribute attribute, final in
return setReporting(attribute, minInterval, maxInterval, null);
}

/**
* Gets the reporting configuration for an attribute
*
* @param attribute the {@link ZclAttribute} on which to enable reporting
* @return command future {@link CommandResult}
*/
public Future<CommandResult> getReporting(final ZclAttribute attribute) {
final ReadReportingConfigurationCommand command = new ReadReportingConfigurationCommand();
command.setClusterId(clusterId);
AttributeRecord record = new AttributeRecord();
record.setAttributeIdentifier(attribute.getId());
record.setDirection(0);
command.setRecords(Collections.singletonList(record));
command.setDestinationAddress(zigbeeAddress);

return zigbeeManager.unicast(command, new ZclResponseMatcher());
}

/**
* Gets all the attributes supported by this cluster This will return all
* attributes, even if they are not actually supported by the device. The
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
public class AttributeRecord implements ZclListItemField {
/**
* The direction.
* <p>
* The direction field specifies whether values of the attribute are reported (0x00), or
* whether reports of the attribute are received (0x01).
*
*/
private boolean direction;
private int direction;
/**
* The attribute identifier.
*/
Expand All @@ -40,37 +44,43 @@ public void setAttributeIdentifier(int attributeIdentifier) {
}

/**
* Is direction?
* Gets the direction
* <p>
* The direction field specifies whether values of the attribute are reported (0x00), or
* whether reports of the attribute are received (0x01).
*
* @return the direction
*/
public boolean isDirection() {
public int getDirection() {
return direction;
}

/**
* Sets direction.
* <p>
* The direction field specifies whether values of the attribute are reported (0x00), or
* whether reports of the attribute are received (0x01).
*
* @param direction the direction
*/
public void setDirection(boolean direction) {
public void setDirection(int direction) {
this.direction = direction;
}

@Override
public void serialize(final ZigBeeSerializer serializer) {
serializer.appendZigBeeType(direction, ZclDataType.BOOLEAN);
serializer.appendZigBeeType(direction, ZclDataType.UNSIGNED_8_BIT_INTEGER);
serializer.appendZigBeeType(attributeIdentifier, ZclDataType.UNSIGNED_16_BIT_INTEGER);
}

@Override
public void deserialize(final ZigBeeDeserializer deserializer) {
direction = (boolean) deserializer.readZigBeeType(ZclDataType.BOOLEAN);
direction = (int) deserializer.readZigBeeType(ZclDataType.UNSIGNED_8_BIT_INTEGER);
attributeIdentifier = (int) deserializer.readZigBeeType(ZclDataType.UNSIGNED_16_BIT_INTEGER);
}

@Override
public String toString() {
return "Attribute Record: direction=" + direction + ", attributeIdentifier=" + attributeIdentifier;
return "Attribute Record[ direction=" + direction + ", attributeIdentifier=" + attributeIdentifier + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@
public class AttributeReportingConfigurationRecord implements ZclListItemField {
/**
* The direction.
* <p>
* The direction field specifies whether values of the attribute are be reported, or
* whether reports of the attribute are to be received.
* <p>
* If this value is set to 0x00, then the attribute data type field, the minimum
* reporting interval field, the maximum reporting interval field and the reportable
* change field are included in the payload, and the timeout period field is omitted.
* The record is sent to a cluster server (or client) to configure how it sends reports to
* a client (or server) of the same cluster.
* <p>
* If this value is set to 0x01, then the timeout period field is included in the payload,
* and the attribute data type field, the minimum reporting interval field, the
* maximum reporting interval field and the reportable change field are omitted. The
* record is sent to a cluster client (or server) to configure how it should expect
* reports from a server (or client) of the same cluster.
*/
private int direction;
/**
Expand Down Expand Up @@ -101,7 +116,22 @@ public class AttributeReportingConfigurationRecord implements ZclListItemField {
private int timeoutPeriod;

/**
* Gets direction.
* Gets the direction
* <p>
* The direction field specifies whether values of the attribute are be reported, or
* whether reports of the attribute are to be received.
* <p>
* If this value is set to 0x00, then the attribute data type field, the minimum
* reporting interval field, the maximum reporting interval field and the reportable
* change field are included in the payload, and the timeout period field is omitted.
* The record is sent to a cluster server (or client) to configure how it sends reports to
* a client (or server) of the same cluster.
* <p>
* If this value is set to 0x01, then the timeout period field is included in the payload,
* and the attribute data type field, the minimum reporting interval field, the
* maximum reporting interval field and the reportable change field are omitted. The
* record is sent to a cluster client (or server) to configure how it should expect
* reports from a server (or client) of the same cluster.
*
* @return the direction
*/
Expand All @@ -110,7 +140,22 @@ public int getDirection() {
}

/**
* Sets direction.
* Sets the direction.
* <p>
* The direction field specifies whether values of the attribute are be reported, or
* whether reports of the attribute are to be received.
* <p>
* If this value is set to 0x00, then the attribute data type field, the minimum
* reporting interval field, the maximum reporting interval field and the reportable
* change field are included in the payload, and the timeout period field is omitted.
* The record is sent to a cluster server (or client) to configure how it sends reports to
* a client (or server) of the same cluster.
* <p>
* If this value is set to 0x01, then the timeout period field is included in the payload,
* and the attribute data type field, the minimum reporting interval field, the
* maximum reporting interval field and the reportable change field are omitted. The
* record is sent to a cluster client (or server) to configure how it should expect
* reports from a server (or client) of the same cluster.
*
* @param direction the direction
*/
Expand Down
Loading

0 comments on commit 12ca951

Please sign in to comment.