Fixed zigbee on off events
This commit is contained in:
parent
203bb67f7f
commit
68054ebf4f
12 changed files with 114 additions and 39 deletions
|
|
@ -27,13 +27,13 @@ import se.hal.plugin.zigbee.device.*;
|
|||
import zutil.Timer;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.zsmartsystems.zigbee.zcl.clusters.ZclBasicCluster.*;
|
||||
|
||||
/**
|
||||
* Controller that will connect to a Zigbee USB coordinator.
|
||||
*/
|
||||
|
|
@ -289,15 +289,30 @@ public class ZigbeeController implements HalSensorController,
|
|||
ZclCluster cluster = endpoint.getInputCluster(inputClusterId);
|
||||
ZigbeeHalDeviceConfig config = createDeviceConfig(inputClusterId);
|
||||
|
||||
if (cluster != null && config != null) {
|
||||
// Read basic attributes
|
||||
if (cluster instanceof ZclBasicCluster) {
|
||||
try {
|
||||
cluster.readAttributes(Arrays.asList(
|
||||
ZclBasicCluster.ATTR_MANUFACTURERNAME,
|
||||
ZclBasicCluster.ATTR_MODELIDENTIFIER,
|
||||
ZclBasicCluster.ATTR_HWVERSION,
|
||||
ZclBasicCluster.ATTR_APPLICATIONVERSION,
|
||||
ZclBasicCluster.ATTR_STACKVERSION,
|
||||
ZclBasicCluster.ATTR_ZCLVERSION,
|
||||
ZclBasicCluster.ATTR_DATECODE
|
||||
)).get();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Was unable to read basic device information.", e);
|
||||
}
|
||||
}
|
||||
// Handle specific node attributes
|
||||
else if (cluster != null && config != null) {
|
||||
config.setZigbeeNodeAddress(endpoint.getIeeeAddress());
|
||||
config.initialize(cluster);
|
||||
|
||||
cluster.addAttributeListener(new ZclAttributeListener() {
|
||||
@Override
|
||||
public void attributeUpdated(ZclAttribute attribute, Object value) {
|
||||
if (attribute.getId() != 0) // Only report on Measured Value attribute updates
|
||||
return;
|
||||
|
||||
logger.finer("[Node: " + endpoint.getIeeeAddress() + ", Endpoint: " + endpoint.getEndpointId() + ", Cluster: " + attribute.getCluster().getId() + "] Attribute " + config.getClass().getSimpleName() + " updated: id=" + attribute.getId() + ", attribute_name=" + attribute.getName() + ", value=" + attribute.getLastValue());
|
||||
for (HalDeviceReportListener deviceListener : deviceListeners) {
|
||||
deviceListener.reportReceived(config, config.getDeviceData(attribute));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package se.hal.plugin.zigbee.device;
|
|||
|
||||
import com.zsmartsystems.zigbee.IeeeAddress;
|
||||
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
|
||||
import com.zsmartsystems.zigbee.zcl.ZclCluster;
|
||||
import se.hal.intf.HalAbstractController;
|
||||
import se.hal.intf.HalDeviceConfig;
|
||||
import se.hal.intf.HalDeviceData;
|
||||
|
|
@ -30,6 +31,14 @@ public abstract class ZigbeeHalDeviceConfig implements HalDeviceConfig {
|
|||
// Abstract Methods
|
||||
// --------------------------
|
||||
|
||||
/**
|
||||
* Method will configured a newly discovered or updated cluster. Method by default
|
||||
* does nothing and will need to be extended by subclasses to add specific initialization logic.
|
||||
*
|
||||
* @param cluster is the cluster to be initialized.
|
||||
*/
|
||||
public void initialize(ZclCluster cluster) {}
|
||||
|
||||
/**
|
||||
* @param zclAttribute
|
||||
* @return a HalDeviceData object containing the same value representation as the endpoint.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import com.zsmartsystems.zigbee.zcl.ZclCommand;
|
|||
import se.hal.intf.HalEventData;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
|
|
@ -31,15 +34,19 @@ public abstract class ZigbeeHalEventDeviceConfig extends ZigbeeHalDeviceConfig {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sendZigbeeCommand(ZigBeeNetworkManager networkManager, HalEventData data) {
|
||||
ZclCluster cluster = getZigbeeCluster(networkManager);
|
||||
|
||||
if (cluster != null) {
|
||||
try {
|
||||
ZclCommand command = getZigbeeCommandObject(data);
|
||||
|
||||
// Need to do reflection as the generic method has visibility protected.
|
||||
CommandResult result =
|
||||
(CommandResult) ZclCluster.class.getMethod("sendCommand", ZclCommand.class).invoke(command);
|
||||
|
||||
Method method = ZclCluster.class.getDeclaredMethod("sendCommand", ZclCommand.class);
|
||||
method.setAccessible(true);
|
||||
CommandResult result = ((Future<CommandResult>) method.invoke(cluster, command)).get();
|
||||
|
||||
if (result.isError() || result.isTimeout()) {
|
||||
logger.warning("[Node: " + getZigbeeNodeAddress() + ", Endpoint: " + cluster.getZigBeeAddress() + "] Command failed with error: " + result.isError() + " (timeout=" + result.isTimeout() + ")");
|
||||
|
|
@ -47,7 +54,7 @@ public abstract class ZigbeeHalEventDeviceConfig extends ZigbeeHalDeviceConfig {
|
|||
logger.info("[Node: " + getZigbeeNodeAddress() + ", Endpoint: " + cluster.getZigBeeAddress() + "] Command has been successfully sent.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warning("[Node: " + getZigbeeNodeAddress() + ", Endpoint: " + cluster.getZigBeeAddress() + "] Failed to send command: " + e.getMessage());
|
||||
logger.log(Level.WARNING, "[Node: " + getZigbeeNodeAddress() + ", Endpoint: " + cluster.getZigBeeAddress() + "] Failed to send command.", e);
|
||||
}
|
||||
} else {
|
||||
logger.warning("[Node: " + getZigbeeNodeAddress() + "] Unable to find cluster: " + getZigbeeClusterId());
|
||||
|
|
|
|||
|
|
@ -18,7 +18,11 @@ public class ZigbeeHumidityConfig extends ZigbeeHalDeviceConfig implements HalSe
|
|||
|
||||
@Override
|
||||
public HalDeviceData getDeviceData(ZclAttribute zclAttribute) {
|
||||
return new HumiditySensorData(((int) zclAttribute.getLastValue()) / 100.0, zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
if (zclAttribute.getId() == ZclRelativeHumidityMeasurementCluster.ATTR_MEASUREDVALUE)
|
||||
return new HumiditySensorData(
|
||||
((int) zclAttribute.getLastValue()) / 100.0,
|
||||
zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package se.hal.plugin.zigbee.device;
|
||||
|
||||
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
|
||||
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
|
||||
import com.zsmartsystems.zigbee.zcl.ZclCluster;
|
||||
import com.zsmartsystems.zigbee.zcl.ZclCommand;
|
||||
|
|
@ -11,18 +10,41 @@ import se.hal.intf.HalDeviceData;
|
|||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.struct.devicedata.OnOffEventData;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A device configuration for a specific endpoint on a Zigbee device.
|
||||
*/
|
||||
public class ZigbeeOnOffConfig extends ZigbeeHalEventDeviceConfig implements HalEventConfig {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
// --------------------------
|
||||
// Zigbee Methods
|
||||
// --------------------------
|
||||
|
||||
@Override
|
||||
public void initialize(ZclCluster cluster) {
|
||||
if (! (cluster instanceof ZclOnOffCluster))
|
||||
return;
|
||||
|
||||
try {
|
||||
ZclAttribute attribute = cluster.getAttribute(ZclOnOffCluster.ATTR_ONOFF);
|
||||
attribute.setReporting(1, 900).get();
|
||||
attribute.readValue(60);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Was unable to initialize cluster reporting rate.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HalDeviceData getDeviceData(ZclAttribute zclAttribute) {
|
||||
if (zclAttribute.getId() == ZclOnOffCluster.ATTR_ONOFF)
|
||||
return new OnOffEventData(
|
||||
(boolean) zclAttribute.getLastValue(),
|
||||
zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ public class ZigbeePressureConfig extends ZigbeeHalDeviceConfig implements HalSe
|
|||
|
||||
@Override
|
||||
public HalDeviceData getDeviceData(ZclAttribute zclAttribute) {
|
||||
return new PressureSensorData(((int) zclAttribute.getLastValue()), zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
if (zclAttribute.getId() == ZclTemperatureMeasurementCluster.ATTR_MAXMEASUREDVALUE)
|
||||
return new PressureSensorData(
|
||||
(int) zclAttribute.getLastValue(),
|
||||
zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,7 +18,11 @@ public class ZigbeeTemperatureConfig extends ZigbeeHalDeviceConfig implements Ha
|
|||
|
||||
@Override
|
||||
public HalDeviceData getDeviceData(ZclAttribute zclAttribute) {
|
||||
return new TemperatureSensorData(((int) zclAttribute.getLastValue()) / 100.0, zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
if (zclAttribute.getId() == ZclTemperatureMeasurementCluster.ATTR_MEASUREDVALUE)
|
||||
return new TemperatureSensorData(
|
||||
((int) zclAttribute.getLastValue()) / 100.0,
|
||||
zclAttribute.getLastReportTime().getTimeInMillis());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,16 +27,17 @@ public class ZigbeeNodeOverviewPage extends HalWebPage {
|
|||
Map<String, String> request)
|
||||
throws Exception {
|
||||
|
||||
Set<ZigBeeNode> nodes = null;
|
||||
for (HalAbstractController controller : HalAbstractControllerManager.getControllers()) {
|
||||
if (controller instanceof ZigbeeController) {
|
||||
nodes = ((ZigbeeController) controller).getNodes();
|
||||
ZigbeeController controller = null;
|
||||
for (HalAbstractController cont : HalAbstractControllerManager.getControllers()) {
|
||||
if (cont instanceof ZigbeeController) {
|
||||
controller = ((ZigbeeController) cont);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
|
||||
tmpl.set("nodes", nodes);
|
||||
tmpl.set("controller", controller);
|
||||
tmpl.set("nodes", controller.getNodes());
|
||||
return tmpl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue