Fixed zigbee on off events

This commit is contained in:
Ziver Koc 2021-07-19 23:51:29 +02:00
parent 203bb67f7f
commit 68054ebf4f
12 changed files with 114 additions and 39 deletions

View file

@ -1,4 +1,4 @@
<h1 class="page-header">Details for <a href="#">{{event.getName()}}</a></h1>
<h1 class="page-header">Details for <a href="?id={{event.getId()}}">{{event.getName()}}</a></h1>
<div class="col-md-5">
<div class="panel panel-default drop-shadow">

View file

@ -1,4 +1,4 @@
<h1 class="page-header">Details for <a href="#">{{sensor.getName()}}</a></h1>
<h1 class="page-header">Details for <a href="?id={{sensor.getId()}}">{{sensor.getName()}}</a></h1>
<div class="col-md-12">
<div class="panel panel-default drop-shadow">

View file

@ -132,7 +132,7 @@ public class EventControllerManager extends HalAbstractControllerManager<HalEven
*/
@Override
public void reportReceived(HalDeviceConfig eventConfig, HalDeviceData eventData) {
if (!(eventConfig instanceof HalEventConfig && eventData instanceof HalEventData))
if (!(eventConfig instanceof HalEventConfig))
return;
try {
@ -140,13 +140,15 @@ public class EventControllerManager extends HalAbstractControllerManager<HalEven
Event event = HalDeviceUtil.findDevice(eventConfig, registeredEvents);
if (event != null) {
logger.finest("Received report from event(" + eventConfig.getClass().getSimpleName() + "): " + eventConfig);
PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO event_data_raw (timestamp, event_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, eventData.getTimestamp());
stmt.setLong(2, event.getId());
stmt.setDouble(3, eventData.getData());
DBConnection.exec(stmt);
if (eventData != null) {
logger.finest("Received report from event(" + eventConfig.getClass().getSimpleName() + "): " + eventConfig);
PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO event_data_raw (timestamp, event_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, eventData.getTimestamp());
stmt.setLong(2, event.getId());
stmt.setDouble(3, eventData.getData());
DBConnection.exec(stmt);
}
}
else { // unknown sensor
logger.info("Received report from unregistered event" +
@ -158,12 +160,14 @@ public class EventControllerManager extends HalAbstractControllerManager<HalEven
}
event.setDeviceConfig((HalEventConfig) eventConfig);
}
event.setDeviceData((HalEventData) eventData);
// call listeners
for (HalDeviceReportListener listener : event.getReportListeners())
listener.reportReceived(event.getDeviceConfig(), eventData);
}catch (SQLException e){
} catch (SQLException e){
logger.log(Level.WARNING, "Unable to store event report", e);
}
}
@ -171,6 +175,7 @@ public class EventControllerManager extends HalAbstractControllerManager<HalEven
public void send(Event event){
HalEventController controller = getControllerInstance(event.getController());
if (controller != null) {
event.getDeviceData().setTimestamp(System.currentTimeMillis()); // Set timestamp to now
controller.send(event.getDeviceConfig(), event.getDeviceData());
reportReceived(event.getDeviceConfig(), event.getDeviceData()); // save action to db
}

View file

@ -134,7 +134,7 @@ public class SensorControllerManager extends HalAbstractControllerManager<HalAbs
*/
@Override
public void reportReceived(HalDeviceConfig sensorConfig, HalDeviceData sensorData) {
if (!(sensorConfig instanceof HalSensorConfig && sensorData instanceof HalSensorData))
if (!(sensorConfig instanceof HalSensorConfig))
return;
try{
@ -142,13 +142,15 @@ public class SensorControllerManager extends HalAbstractControllerManager<HalAbs
Sensor sensor = HalDeviceUtil.findDevice(sensorConfig, registeredSensors);
if (sensor != null) {
logger.finest("Received report from sensor(" + sensorConfig.getClass().getSimpleName() + "): " + sensorConfig);
PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO sensor_data_raw (timestamp, sensor_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, sensorData.getTimestamp());
stmt.setLong(2, sensor.getId());
stmt.setDouble(3, sensorData.getData());
DBConnection.exec(stmt);
if (sensorData != null) {
logger.finest("Received report from sensor(" + sensorConfig.getClass().getSimpleName() + "): " + sensorConfig);
PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO sensor_data_raw (timestamp, sensor_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, sensorData.getTimestamp());
stmt.setLong(2, sensor.getId());
stmt.setDouble(3, sensorData.getData());
DBConnection.exec(stmt);
}
}
else { // unknown sensor
logger.finest("Received report from unregistered sensor" +
@ -160,7 +162,9 @@ public class SensorControllerManager extends HalAbstractControllerManager<HalAbs
}
sensor.setDeviceConfig((HalSensorConfig) sensorConfig);
}
sensor.setDeviceData((HalSensorData) sensorData);
// call listeners
for (HalDeviceReportListener listener : sensor.getReportListeners())
listener.reportReceived(sensorConfig, sensorData);

View file

@ -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));

View file

@ -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.

View file

@ -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());

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}
}