Skip to content

Commit

Permalink
Improve how attributes are requested during discovery
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <[email protected]>
  • Loading branch information
cdjackson committed May 12, 2020
1 parent 2032178 commit ef6dab1
Showing 1 changed file with 51 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
*/
package org.openhab.binding.zigbee.discovery;

import static com.zsmartsystems.zigbee.zcl.clusters.ZclBasicCluster.*;
import static org.eclipse.smarthome.core.thing.Thing.*;
import static org.openhab.binding.zigbee.ZigBeeBindingConstants.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -42,6 +38,7 @@
*
* @author Chris Jackson - initial contribution
* @author Henning Sudbrock - read multiple attributes from basic cluster with a single command to speedup discovery
* @author Chris Jackson - fix issue with reading multiple attributes that are unsupported
*/
public class ZigBeeNodePropertyDiscoverer {

Expand All @@ -50,13 +47,13 @@ public class ZigBeeNodePropertyDiscoverer {
private static final Map<String, Integer> BASIC_CLUSTER_ATTRIBUTES_FOR_THING_PROPERTY;
static {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put(PROPERTY_VENDOR, ATTR_MANUFACTURERNAME);
map.put(PROPERTY_MODEL_ID, ATTR_MODELIDENTIFIER);
map.put(PROPERTY_HARDWARE_VERSION, ATTR_HWVERSION);
map.put(THING_PROPERTY_APPLICATIONVERSION, ATTR_APPLICATIONVERSION);
map.put(THING_PROPERTY_STKVERSION, ATTR_STACKVERSION);
map.put(THING_PROPERTY_ZCLVERSION, ATTR_ZCLVERSION);
map.put(THING_PROPERTY_DATECODE, ATTR_DATECODE);
map.put(Thing.PROPERTY_VENDOR, ZclBasicCluster.ATTR_MANUFACTURERNAME);
map.put(Thing.PROPERTY_MODEL_ID, ZclBasicCluster.ATTR_MODELIDENTIFIER);
map.put(Thing.PROPERTY_HARDWARE_VERSION, ZclBasicCluster.ATTR_HWVERSION);
map.put(ZigBeeBindingConstants.THING_PROPERTY_APPLICATIONVERSION, ZclBasicCluster.ATTR_APPLICATIONVERSION);
map.put(ZigBeeBindingConstants.THING_PROPERTY_STKVERSION, ZclBasicCluster.ATTR_STACKVERSION);
map.put(ZigBeeBindingConstants.THING_PROPERTY_ZCLVERSION, ZclBasicCluster.ATTR_ZCLVERSION);
map.put(ZigBeeBindingConstants.THING_PROPERTY_DATECODE, ZclBasicCluster.ATTR_DATECODE);
BASIC_CLUSTER_ATTRIBUTES_FOR_THING_PROPERTY = Collections.unmodifiableMap(map);
}

Expand Down Expand Up @@ -116,21 +113,25 @@ public Map<String, String> getProperties(final ZigBeeNode node) {

private void addPropertiesFromNodeDescriptors(ZigBeeNode node) {
if (node.getLogicalType() != null) {
properties.put(THING_PROPERTY_LOGICALTYPE, node.getLogicalType().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_LOGICALTYPE, node.getLogicalType().toString());
}

properties.put(THING_PROPERTY_NETWORKADDRESS, node.getNetworkAddress().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_NETWORKADDRESS, node.getNetworkAddress().toString());

PowerDescriptor powerDescriptor = node.getPowerDescriptor();
if (powerDescriptor != null) {
properties.put(THING_PROPERTY_AVAILABLEPOWERSOURCES, powerDescriptor.getAvailablePowerSources().toString());
properties.put(THING_PROPERTY_POWERSOURCE, powerDescriptor.getCurrentPowerSource().toString());
properties.put(THING_PROPERTY_POWERMODE, powerDescriptor.getCurrentPowerMode().toString());
properties.put(THING_PROPERTY_POWERLEVEL, powerDescriptor.getPowerLevel().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_AVAILABLEPOWERSOURCES,
powerDescriptor.getAvailablePowerSources().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_POWERSOURCE,
powerDescriptor.getCurrentPowerSource().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_POWERMODE,
powerDescriptor.getCurrentPowerMode().toString());
properties.put(ZigBeeBindingConstants.THING_PROPERTY_POWERLEVEL,
powerDescriptor.getPowerLevel().toString());
}

if (node.getNodeDescriptor() != null) {
properties.put(THING_PROPERTY_MANUFACTURERCODE,
properties.put(ZigBeeBindingConstants.THING_PROPERTY_MANUFACTURERCODE,
String.format("0x%04x", node.getNodeDescriptor().getManufacturerCode()));
}
}
Expand Down Expand Up @@ -164,62 +165,76 @@ private void addPropertiesFromBasicCluster(ZigBeeNode node) {
// Now, get each single property via the basic cluster. If the above multi-attribute read was successful,
// this will get each property from the cache. Otherwise, it will try to get the property from the device again.

if (alwaysUpdate || properties.get(Thing.PROPERTY_VENDOR) == null) {
String manufacturer = basicCluster.getManufacturerName(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(Thing.PROPERTY_VENDOR) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_MANUFACTURERNAME)) {
String manufacturer = (String) basicCluster.getAttribute(ZclBasicCluster.ATTR_MANUFACTURERNAME)
.readValue(Long.MAX_VALUE);
if (manufacturer != null) {
properties.put(Thing.PROPERTY_VENDOR, manufacturer.trim());
} else {
logger.debug("{}: Manufacturer request failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(Thing.PROPERTY_MODEL_ID) == null) {
String model = basicCluster.getModelIdentifier(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(Thing.PROPERTY_MODEL_ID) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_MODELIDENTIFIER)) {
String model = (String) basicCluster.getAttribute(ZclBasicCluster.ATTR_MODELIDENTIFIER)
.readValue(Long.MAX_VALUE);
if (model != null) {
properties.put(Thing.PROPERTY_MODEL_ID, model.trim());
} else {
logger.debug("{}: Model request failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(Thing.PROPERTY_HARDWARE_VERSION) == null) {
Integer hwVersion = basicCluster.getHwVersion(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(Thing.PROPERTY_HARDWARE_VERSION) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_MODELIDENTIFIER)) {
Integer hwVersion = (Integer) basicCluster.getAttribute(ZclBasicCluster.ATTR_HWVERSION)
.readValue(Long.MAX_VALUE);
if (hwVersion != null) {
properties.put(Thing.PROPERTY_HARDWARE_VERSION, hwVersion.toString());
} else {
logger.debug("{}: Hardware version failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_APPLICATIONVERSION) == null) {
Integer appVersion = basicCluster.getApplicationVersion(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_APPLICATIONVERSION) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_MODELIDENTIFIER)) {
Integer appVersion = (Integer) basicCluster.getAttribute(ZclBasicCluster.ATTR_APPLICATIONVERSION)
.readValue(Long.MAX_VALUE);
if (appVersion != null) {
properties.put(ZigBeeBindingConstants.THING_PROPERTY_APPLICATIONVERSION, appVersion.toString());
} else {
logger.debug("{}: Application version failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_STKVERSION) == null) {
Integer stkVersion = basicCluster.getStackVersion(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_STKVERSION) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_STACKVERSION)) {
Integer stkVersion = (Integer) basicCluster.getAttribute(ZclBasicCluster.ATTR_STACKVERSION)
.readValue(Long.MAX_VALUE);
if (stkVersion != null) {
properties.put(ZigBeeBindingConstants.THING_PROPERTY_STKVERSION, stkVersion.toString());
} else {
logger.debug("{}: Stack version failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_ZCLVERSION) == null) {
Integer zclVersion = basicCluster.getZclVersion(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_ZCLVERSION) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_ZCLVERSION)) {
Integer zclVersion = (Integer) basicCluster.getAttribute(ZclBasicCluster.ATTR_ZCLVERSION)
.readValue(Long.MAX_VALUE);
if (zclVersion != null) {
properties.put(ZigBeeBindingConstants.THING_PROPERTY_ZCLVERSION, zclVersion.toString());
} else {
logger.debug("{}: ZCL version failed", node.getIeeeAddress());
}
}

if (alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_DATECODE) == null) {
String dateCode = basicCluster.getDateCode(Long.MAX_VALUE);
if ((alwaysUpdate || properties.get(ZigBeeBindingConstants.THING_PROPERTY_DATECODE) == null)
&& basicCluster.isAttributeSupported(ZclBasicCluster.ATTR_ZCLVERSION)) {
String dateCode = (String) basicCluster.getAttribute(ZclBasicCluster.ATTR_DATECODE)
.readValue(Long.MAX_VALUE);
if (dateCode != null) {
properties.put(ZigBeeBindingConstants.THING_PROPERTY_DATECODE, dateCode);
} else {
Expand All @@ -232,8 +247,9 @@ private void addPropertiesFromBasicCluster(ZigBeeNode node) {
private Map<String, Integer> getPropertiesToRead(ZclBasicCluster basicCluster) {
Map<String, Integer> result = new HashMap<>();
for (Map.Entry<String, Integer> entry : BASIC_CLUSTER_ATTRIBUTES_FOR_THING_PROPERTY.entrySet()) {
if (alwaysUpdate || properties.get(entry.getKey()) == null
|| !basicCluster.getAttribute(entry.getValue()).isLastValueCurrent(Long.MAX_VALUE)) {
if ((alwaysUpdate || properties.get(entry.getKey()) == null
|| !basicCluster.getAttribute(entry.getValue()).isLastValueCurrent(Long.MAX_VALUE))
&& basicCluster.isAttributeSupported(entry.getValue())) {
result.put(entry.getKey(), entry.getValue());
}
}
Expand All @@ -252,7 +268,7 @@ private void addPropertiesFromOtaCluster(ZigBeeNode node) {
ZclAttribute attribute = otaCluster.getAttribute(ZclOtaUpgradeCluster.ATTR_CURRENTFILEVERSION);
Object fileVersion = attribute.readValue(Long.MAX_VALUE);
if (fileVersion != null) {
properties.put(PROPERTY_FIRMWARE_VERSION, String.format("0x%08X", fileVersion));
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, String.format("0x%08X", fileVersion));
} else {
logger.debug("{}: Could not get OTA firmware version from device", node.getIeeeAddress());
}
Expand Down

0 comments on commit ef6dab1

Please sign in to comment.