Added zigbee Hal DB data storage

This commit is contained in:
Ziver Koc 2021-07-06 21:57:21 +02:00
parent 52273e1ebe
commit aea0d9bab1
8 changed files with 179 additions and 32 deletions

View file

@ -0,0 +1,151 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.zigbee;
import com.zsmartsystems.zigbee.IeeeAddress;
import com.zsmartsystems.zigbee.database.ZigBeeNetworkDataStore;
import com.zsmartsystems.zigbee.database.ZigBeeNodeDao;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.handler.ListSQLResult;
import zutil.io.StringInputStream;
import zutil.log.LogUtil;
import zutil.parser.json.JSONObjectInputStream;
import zutil.parser.json.JSONObjectOutputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
public class ZigBeeHalDataStore implements ZigBeeNetworkDataStore {
private static final Logger logger = LogUtil.getLogger();
private DBConnection db;
public ZigBeeHalDataStore(DBConnection db) {
this.db = db;
}
@Override
public Set<IeeeAddress> readNetworkNodes() {
Set<IeeeAddress> ieeeAddresses = new HashSet<>();
try {
PreparedStatement stmt = db.getPreparedStatement( "SELECT address FROM zigbee_node" );
List<String> strAddresses = DBConnection.exec(stmt, new ListSQLResult<String>());
for (String address : strAddresses) {
ieeeAddresses.add(new IeeeAddress(address));
}
} catch (SQLException e) {
e.printStackTrace();
}
return ieeeAddresses;
}
@Override
public ZigBeeNodeDao readNode(IeeeAddress address) {
try {
ZigbeeNodeDSO dso = ZigbeeNodeDSO.load(db, address.toString());
if (dso != null)
return dso.getConfig();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public void writeNode(ZigBeeNodeDao node) {
try {
logger.fine("[Node: " + node.getIeeeAddress() + "]: Storing Zigbee Node in DB: " +
"NetAddr: " + node.getNetworkAddress() + ", " +
"binding: " + node.getBindingTable() + ", " +
"description: " + node.getNodeDescriptor() + ", " +
"endpoints: " + node.getEndpoints() + ", " +
"Power: " + node.getPowerDescriptor()
);
ZigbeeNodeDSO dso = ZigbeeNodeDSO.load(db, node.getIeeeAddress().toString());
if (dso == null) {
dso = new ZigbeeNodeDSO();
dso.address = node.getIeeeAddress().toString();
}
dso.setConfig(node);
dso.save(db);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void removeNode(IeeeAddress address) {
try {
logger.fine("[Node: " + address + "]: Removing Node from DB.");
ZigbeeNodeDSO dso = ZigbeeNodeDSO.load(db, address.toString());
if (dso != null)
dso.delete(db);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* A private data storage object connected to the DB schema.
*/
private static class ZigbeeNodeDSO extends DBBean {
protected String address;
protected String config;
public static ZigbeeNodeDSO load(DBConnection db, String address) throws SQLException{
PreparedStatement stmt = db.getPreparedStatement( "SELECT * FROM zigbee_node WHERE ? == zigbee_node.address" );
stmt.setString(1, address);
return DBConnection.exec(stmt, DBBeanSQLResultHandler.create(ZigbeeNodeDSO.class, db));
}
protected void setConfig(ZigBeeNodeDao node) {
config = JSONObjectOutputStream.toString(node);
}
protected ZigBeeNodeDao getConfig() {
JSONObjectInputStream in = new JSONObjectInputStream(new StringInputStream(config));
in.registerRootClass(ZigBeeNodeDao.class);
return (ZigBeeNodeDao) in.readObject();
}
}
}

View file

@ -34,14 +34,13 @@ import java.util.Set;
import java.util.logging.Logger;
public class ZigBeeDataStore implements ZigBeeNetworkDataStore {
public class ZigBeeMemoryDataStore implements ZigBeeNetworkDataStore {
private static final Logger logger = LogUtil.getLogger();
private static ZigBeeDataStore instance;
private HashMap<IeeeAddress,ZigBeeNodeDao> devices = new HashMap<>();
private ZigBeeDataStore() {}
private ZigBeeMemoryDataStore() {}
@Override
@ -58,9 +57,9 @@ public class ZigBeeDataStore implements ZigBeeNetworkDataStore {
public void writeNode(ZigBeeNodeDao node) {
logger.fine("[Node: " + node.getIeeeAddress() + "]: Storing Zigbee Node in DB: " +
"NetAddr: " + node.getNetworkAddress() + ", " +
"binding: " + node.getBindingTable() + ", " +
"description: " + node.getNodeDescriptor() + ", " +
"endpoints: " + node.getEndpoints() + ", " +
"Binding: " + node.getBindingTable() + ", " +
"Description: " + node.getNodeDescriptor() + ", " +
"Endpoints: " + node.getEndpoints() + ", " +
"Power: " + node.getPowerDescriptor()
);
@ -73,11 +72,4 @@ public class ZigBeeDataStore implements ZigBeeNetworkDataStore {
devices.remove(address);
}
public static ZigBeeDataStore getInstance() {
if (instance == null)
instance = new ZigBeeDataStore();
return instance;
}
}

View file

@ -36,7 +36,7 @@ import java.util.logging.Logger;
/**
* Controller that will connect to a Zigbee USB coordinator.
*/
public class HalZigbeeController implements HalSensorController,
public class ZigbeeController implements HalSensorController,
HalEventController,
HalAutostartController,
HalScannableController,
@ -61,7 +61,7 @@ public class HalZigbeeController implements HalSensorController,
private List<ZigbeeHalDeviceConfig> registeredDevices = new ArrayList<>();
public HalZigbeeController() {}
public ZigbeeController() {}
// ------------------------------------------
// Lifecycle Methods
@ -86,7 +86,7 @@ public class HalZigbeeController implements HalSensorController,
ZigBeeTransportTransmit dongle = getDongle(dongleName, serialPort, transportOptions);
networkManager = new ZigBeeNetworkManager(dongle);
networkManager.setNetworkDataStore(ZigBeeDataStore.getInstance());
networkManager.setNetworkDataStore(new ZigBeeHalDataStore(HalContext.getDB()));
networkManager.setSerializer(DefaultSerializer.class, DefaultDeserializer.class);
networkManager.addAnnounceListener(this);
networkManager.addNetworkNodeListener(this);

View file

@ -5,25 +5,25 @@ import com.zsmartsystems.zigbee.zcl.ZclAttribute;
import se.hal.intf.HalAbstractController;
import se.hal.intf.HalDeviceConfig;
import se.hal.intf.HalDeviceData;
import se.hal.plugin.zigbee.HalZigbeeController;
import se.hal.plugin.zigbee.ZigbeeController;
import zutil.ui.conf.Configurator;
import java.util.Objects;
/**
* A generic class that is extended by all Endpoint config classes.
*/
public abstract class ZigbeeHalDeviceConfig implements HalDeviceConfig {
@Configurator.Configurable(value = "Node IeeeAddress")
private String zigbeeNodeAddressStr;
private transient IeeeAddress zigbeeNodeAddress;
public void setZigbeeNodeAddress(IeeeAddress zigbeeNodeAddress) {
this.zigbeeNodeAddress = zigbeeNodeAddress;
this.zigbeeNodeAddressStr = zigbeeNodeAddress.toString();
}
public IeeeAddress getZigbeeNodeAddress() {
if (zigbeeNodeAddress == null && zigbeeNodeAddressStr != null)
zigbeeNodeAddress = new IeeeAddress(zigbeeNodeAddressStr);
return zigbeeNodeAddress;
return new IeeeAddress(zigbeeNodeAddressStr);
}
// --------------------------
@ -47,17 +47,16 @@ public abstract class ZigbeeHalDeviceConfig implements HalDeviceConfig {
@Override
public Class<? extends HalAbstractController> getDeviceControllerClass() {
return HalZigbeeController.class;
return ZigbeeController.class;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!(o instanceof ZigbeeHalDeviceConfig)) return false;
ZigbeeHalDeviceConfig that = (ZigbeeHalDeviceConfig) o;
return zigbeeNodeAddress.equals(that.zigbeeNodeAddress) &&
getZigbeeClusterId() == that.getZigbeeClusterId();
return Objects.equals(zigbeeNodeAddressStr, that.zigbeeNodeAddressStr);
}

View file

@ -5,7 +5,7 @@ import se.hal.HalContext;
import se.hal.intf.HalAbstractController;
import se.hal.intf.HalAbstractControllerManager;
import se.hal.intf.HalWebPage;
import se.hal.plugin.zigbee.HalZigbeeController;
import se.hal.plugin.zigbee.ZigbeeController;
import zutil.io.file.FileUtil;
import zutil.parser.Templator;
@ -29,8 +29,8 @@ public class ZigbeeNodeOverviewPage extends HalWebPage {
Set<ZigBeeNode> nodes = null;
for (HalAbstractController controller : HalAbstractControllerManager.getControllers()) {
if (controller instanceof HalZigbeeController) {
nodes = ((HalZigbeeController) controller).getNodes();
if (controller instanceof ZigbeeController) {
nodes = ((ZigbeeController) controller).getNodes();
break;
}
}

View file

@ -3,7 +3,12 @@
"name": "Hal-Zigbee",
"description": "A Zigbee plugin for directly connecting to a CC2531 device over serial port.",
"interfaces": [
{"se.hal.intf.HalAutostartController": "se.hal.plugin.zigbee.HalZigbeeController"},
{"se.hal.intf.HalEventConfig": "se.hal.plugin.zigbee.device.ZigbeeOnOffConfig"},
{"se.hal.intf.HalSensorConfig": "se.hal.plugin.zigbee.device.ZigbeeHumidityConfig"},
{"se.hal.intf.HalSensorConfig": "se.hal.plugin.zigbee.device.ZigbeePressureConfig"},
{"se.hal.intf.HalSensorConfig": "se.hal.plugin.zigbee.device.ZigbeeTemperatureConfig"},
{"se.hal.intf.HalAutostartController": "se.hal.plugin.zigbee.ZigbeeController"},
{"se.hal.intf.HalWebPage": "se.hal.plugin.zigbee.page.ZigbeeNodeOverviewPage"}
]

View file

@ -47,8 +47,8 @@ public class HalZigbeeControllerTest {
LogUtil.setGlobalFormatter(new CompactLogFormatter());
LogUtil.setGlobalLevel(Level.ALL);
HalZigbeeController controller = new HalZigbeeController();
controller.initialize("COM5", HalZigbeeController.ZIGBEE_DONGLE_CC2531);
ZigbeeController controller = new ZigbeeController();
controller.initialize("COM5", ZigbeeController.ZIGBEE_DONGLE_CC2531);
controller.addListener(new HalDeviceReportListener() {
@Override
public void reportReceived(HalDeviceConfig deviceConfig, HalDeviceData deviceData) {