Added data class getter in device config so that we can load generic device data

This commit is contained in:
Ziver Koc 2016-08-22 16:58:38 +02:00
parent 6b4b565a62
commit 95240dd392
19 changed files with 179 additions and 29 deletions

View file

@ -22,4 +22,6 @@ public abstract class HalDeviceData {
* @return serialized event data converted to double that will be saved in DB.
*/
public abstract double getData();
public abstract void setData(double data);
}

View file

@ -7,7 +7,12 @@ package se.hal.intf;
*/
public interface HalEventConfig {
Class<? extends HalEventController> getEventController();
Class<? extends HalEventController> getEventControllerClass();
/**
* @return the class that should be instantiated and used for data received from this event
*/
Class<? extends HalEventData> getEventDataClass();
/**
* This method needs to be implemented.

View file

@ -26,7 +26,12 @@ public interface HalSensorConfig {
/**
* @return the Controller class where SensorData should be registered on
*/
Class<? extends HalSensorController> getSensorController();
Class<? extends HalSensorController> getSensorControllerClass();
/**
* @return the class that should be instantiated and used for data received from this sensor
*/
Class<? extends HalSensorData> getSensorDataClass();
/**
* NOTE: it should only static or unique data for the sensor type.

View file

@ -26,7 +26,7 @@ public class NutUpsDevice implements HalSensorConfig{
protected HalSensorData read(NutUPSClient.UPSDevice ups){
PowerConsumptionSensorData data = new PowerConsumptionSensorData();
data.setTimestamp(System.currentTimeMillis());
data.setConsumption(ups.getPowerUsage() * 1/60.0); // convert watt min to watt hour
data.setData(ups.getPowerUsage() * 1/60.0); // convert watt min to watt hour
return data;
}
@ -57,7 +57,11 @@ public class NutUpsDevice implements HalSensorConfig{
return AggregationMethod.SUM;
}
@Override
public Class<? extends HalSensorController> getSensorController() {
public Class<? extends HalSensorController> getSensorControllerClass() {
return NutUpsController.class;
}
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return PowerConsumptionSensorData.class;
}
}

View file

@ -2,6 +2,7 @@ package se.hal.plugin.raspberry;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.struct.devicedata.PowerConsumptionSensorData;
import zutil.ui.Configurator;
@ -29,10 +30,15 @@ public class RPiPowerConsumptionSensor implements HalSensorConfig {
}
@Override
public Class<? extends HalSensorController> getSensorController() {
public Class<? extends HalSensorController> getSensorControllerClass() {
return RPiController.class;
}
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return PowerConsumptionSensorData.class;
}
@Override
public boolean equals(Object obj){
if(obj instanceof RPiPowerConsumptionSensor)

View file

@ -2,6 +2,7 @@ package se.hal.plugin.raspberry;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.ui.Configurator;
@ -29,10 +30,15 @@ public class RPiTemperatureSensor implements HalSensorConfig {
}
@Override
public Class<? extends HalSensorController> getSensorController() {
public Class<? extends HalSensorController> getSensorControllerClass() {
return RPiController.class;
}
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return TemperatureSensorData.class;
}
@Override
public boolean equals(Object obj){
if(obj instanceof RPiTemperatureSensor && w1Address != null)

View file

@ -24,10 +24,14 @@ package se.hal.plugin.tellstick.device;
import se.hal.intf.HalEventConfig;
import se.hal.intf.HalEventController;
import se.hal.intf.HalEventData;
import se.hal.intf.HalSensorData;
import se.hal.plugin.tellstick.TellstickDevice;
import se.hal.plugin.tellstick.TellstickDeviceGroup;
import se.hal.plugin.tellstick.TellstickSerialComm;
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
import se.hal.struct.devicedata.SwitchEventData;
import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.parser.binary.BinaryStruct;
import zutil.ui.Configurator;
@ -99,11 +103,16 @@ public class NexaSelfLearning implements HalEventConfig,TellstickDevice,Tellstic
}
public Class<? extends HalEventController> getEventController() {
@Override
public Class<? extends HalEventController> getEventControllerClass() {
return TellstickSerialComm.class;
}
@Override
public Class<? extends HalEventData> getEventDataClass() {
return SwitchEventData.class;
}
@Override
public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; }
@Override

View file

@ -3,10 +3,12 @@ package se.hal.plugin.tellstick.device;
import se.hal.intf.HalEventController;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.plugin.tellstick.TellstickDevice;
import se.hal.plugin.tellstick.TellstickProtocol;
import se.hal.plugin.tellstick.TellstickSerialComm;
import se.hal.plugin.tellstick.protocol.Oregon0x1A2DProtocol;
import se.hal.struct.devicedata.PowerConsumptionSensorData;
import zutil.log.LogUtil;
import zutil.ui.Configurator;
@ -55,10 +57,14 @@ public class Oregon0x1A2D implements HalSensorConfig,TellstickDevice {
}
@Override
public Class<? extends HalSensorController> getSensorController() {
public Class<? extends HalSensorController> getSensorControllerClass() {
return TellstickSerialComm.class;
}
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return PowerConsumptionSensorData.class; // TODO: needs to support all data, add enum?
}
@Override
public String getProtocolName() { return Oregon0x1A2DProtocol.PROTOCOL; }

View file

@ -1,6 +1,7 @@
package se.hal.struct;
import se.hal.ControllerManager;
import se.hal.HalContext;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.log.LogUtil;
@ -74,7 +75,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
if(data != null) {
type = data.getClass().getName();
deviceConfig = data;
deviceData = readDeviceData();
deviceData = getLatestDeviceData(HalContext.getDB());
} else {
deviceConfig = null;
deviceData = null;
@ -127,9 +128,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
/**
* Reads latest device data from DB
*/
private D readDeviceData(){
return null; // TODO: how to do this in a good way?
}
protected abstract D getLatestDeviceData(DBConnection db);
/**************** OTHER ******************/

View file

@ -1,16 +1,23 @@
package se.hal.struct;
import se.hal.intf.HalDeviceData;
import se.hal.intf.HalEventController;
import se.hal.intf.HalEventConfig;
import se.hal.intf.HalEventData;
import se.hal.util.DeviceDataSqlResult;
import zutil.db.DBConnection;
import zutil.db.SQLResultHandler;
import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.handler.SimpleSQLResult;
import zutil.log.LogUtil;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
@ -26,13 +33,33 @@ public class Event extends AbstractDevice<HalEventConfig,HalEventData>{
}
public static List<Event> getLocalEvents(DBConnection db) throws SQLException {
PreparedStatement stmt = db.getPreparedStatement( "SELECT event.* FROM event,user WHERE user.external == 0 AND user.id == event.user_id" );
return DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(Event.class, db) );
PreparedStatement stmt = db.getPreparedStatement(
"SELECT event.* FROM event,user WHERE user.external == 0 AND user.id == event.user_id");
return DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(Event.class, db));
}
public Class<? extends HalEventController> getController(){
return getDeviceConfig().getEventController();
return getDeviceConfig().getEventControllerClass();
}
@Override
protected HalEventData getLatestDeviceData(DBConnection db) {
try {
Class deviceDataClass = getDeviceConfig().getEventDataClass();
if (deviceDataClass == null)
throw new ClassNotFoundException("Unknown device data class for: " + getDeviceConfig().getClass());
PreparedStatement stmt = db.getPreparedStatement(
"SELECT data FROM event_data_raw WHERE event_id == ? ORDER BY timestamp DESC LIMIT 1");
stmt.setLong(1, getId());
return (HalEventData)
DBConnection.exec(stmt, new DeviceDataSqlResult(deviceDataClass));
} catch (Exception e){
logger.log(Level.WARNING, null, e);
}
return null;
}
}

View file

@ -4,6 +4,7 @@ import se.hal.HalContext;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorData;
import se.hal.util.DeviceDataSqlResult;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler;
@ -13,6 +14,7 @@ import zutil.log.LogUtil;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -109,6 +111,24 @@ public class Sensor extends AbstractDevice<HalSensorConfig,HalSensorData>{
public Class<? extends HalSensorController> getController(){
return getDeviceConfig().getSensorController();
return getDeviceConfig().getSensorControllerClass();
}
@Override
protected HalSensorData getLatestDeviceData(DBConnection db) {
try {
Class deviceDataClass = getDeviceConfig().getSensorDataClass();
if (deviceDataClass == null)
throw new ClassNotFoundException("Unknown device data class for: " + getDeviceConfig().getClass());
PreparedStatement stmt = db.getPreparedStatement(
"SELECT data FROM event_data_raw WHERE event_id == ? ORDER BY timestamp DESC LIMIT 1");
stmt.setLong(1, getId());
return (HalSensorData)
DBConnection.exec(stmt, new DeviceDataSqlResult(deviceDataClass));
} catch (Exception e){
logger.log(Level.WARNING, null, e);
}
return null;
}
}

View file

@ -42,4 +42,8 @@ public class DimmerEventData extends HalEventData {
public double getData() {
return dimmValue;
}
@Override
public void setData(double dimmValue) {
this.dimmValue = dimmValue;
}
}

View file

@ -21,4 +21,8 @@ public class HumiditySensorData extends HalSensorData {
public double getData() {
return humidity;
}
@Override
public void setData(double humidity) {
this.humidity = humidity;
}
}

View file

@ -21,11 +21,6 @@ public class PowerConsumptionSensorData extends HalSensorData {
}
public void setConsumption(double wattHours){
this.wattHours = wattHours;
}
/**
* @return int representing Watt/Hour
*/
@ -33,4 +28,9 @@ public class PowerConsumptionSensorData extends HalSensorData {
public double getData() {
return wattHours;
}
@Override
public void setData(double wattHours){
this.wattHours = wattHours;
}
}

View file

@ -47,8 +47,13 @@ public class SwitchEventData extends HalEventData {
public boolean isOn(){
return enabled;
}
@Override
public double getData() {
return (enabled ? 1.0 : 0.0);
}
@Override
public void setData(double enabled) {
this.enabled = enabled > 0;
}
}

View file

@ -33,5 +33,9 @@ public class TemperatureSensorData extends HalSensorData {
public double getData() {
return temperature;
}
@Override
public void setData(double temperature) {
this.temperature = temperature;
}
}

View file

@ -0,0 +1,37 @@
package se.hal.util;
import se.hal.intf.HalDeviceData;
import zutil.ClassUtil;
import zutil.db.SQLResultHandler;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Created by Ziver on 2016-08-22.
*/
public class DeviceDataSqlResult implements SQLResultHandler<HalDeviceData> {
private Class<? extends HalDeviceData> clazz;
public DeviceDataSqlResult(Class<? extends HalDeviceData> clazz){
this.clazz = clazz;
}
@Override
public HalDeviceData handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
try {
HalDeviceData dataObj = clazz.newInstance();
dataObj.setData(result.getDouble("data"));
dataObj.setTimestamp(result.getLong("timestamp"));
return dataObj;
} catch (SQLException e){
throw e;
} catch (Exception e){
throw new SQLException(e);
}
}
}

View file

@ -3,6 +3,7 @@ package se.hal.plugin.tellstick;
import org.junit.Before;
import org.junit.Test;
import se.hal.intf.*;
import se.hal.struct.devicedata.DimmerEventData;
import se.hal.struct.devicedata.SwitchEventData;
import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.converter.Converter;
@ -95,14 +96,18 @@ public class TelstickSerialCommEventTest {
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
list.add(new TellstickDecodedEntry(
this, new TemperatureSensorData(testData)
this, new DimmerEventData(testData)
));
return list;
}
@Override
public Class<? extends HalEventController> getEventController() { return null; }
public Class<? extends HalEventController> getEventControllerClass() { return null; }
@Override
public Class<? extends HalEventData> getEventDataClass() {
return null;
}
@Override
public boolean equals(Object obj) {return testData == ((TestEvent)obj).testData;}

View file

@ -2,10 +2,8 @@ package se.hal.plugin.tellstick;
import org.junit.Before;
import org.junit.Test;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.intf.HalSensorReportListener;
import se.hal.intf.*;
import se.hal.struct.devicedata.SwitchEventData;
import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.converter.Converter;
@ -97,6 +95,10 @@ public class TelstickSerialCommSensorTest {
@Override
public AggregationMethod getAggregationMethod() { return null; }
@Override
public Class<? extends HalSensorController> getSensorController() { return null; }
public Class<? extends HalSensorController> getSensorControllerClass() { return null; }
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return null;
}
}
}