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. * @return serialized event data converted to double that will be saved in DB.
*/ */
public abstract double getData(); public abstract double getData();
public abstract void setData(double data);
} }

View file

@ -7,7 +7,12 @@ package se.hal.intf;
*/ */
public interface HalEventConfig { 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. * 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 * @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. * 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){ protected HalSensorData read(NutUPSClient.UPSDevice ups){
PowerConsumptionSensorData data = new PowerConsumptionSensorData(); PowerConsumptionSensorData data = new PowerConsumptionSensorData();
data.setTimestamp(System.currentTimeMillis()); 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; return data;
} }
@ -57,7 +57,11 @@ public class NutUpsDevice implements HalSensorConfig{
return AggregationMethod.SUM; return AggregationMethod.SUM;
} }
@Override @Override
public Class<? extends HalSensorController> getSensorController() { public Class<? extends HalSensorController> getSensorControllerClass() {
return NutUpsController.class; 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.HalSensorConfig;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.struct.devicedata.PowerConsumptionSensorData; import se.hal.struct.devicedata.PowerConsumptionSensorData;
import zutil.ui.Configurator; import zutil.ui.Configurator;
@ -29,10 +30,15 @@ public class RPiPowerConsumptionSensor implements HalSensorConfig {
} }
@Override @Override
public Class<? extends HalSensorController> getSensorController() { public Class<? extends HalSensorController> getSensorControllerClass() {
return RPiController.class; return RPiController.class;
} }
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return PowerConsumptionSensorData.class;
}
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj){
if(obj instanceof RPiPowerConsumptionSensor) if(obj instanceof RPiPowerConsumptionSensor)

View file

@ -2,6 +2,7 @@ package se.hal.plugin.raspberry;
import se.hal.intf.HalSensorConfig; import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData;
import se.hal.struct.devicedata.TemperatureSensorData; import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.ui.Configurator; import zutil.ui.Configurator;
@ -29,10 +30,15 @@ public class RPiTemperatureSensor implements HalSensorConfig {
} }
@Override @Override
public Class<? extends HalSensorController> getSensorController() { public Class<? extends HalSensorController> getSensorControllerClass() {
return RPiController.class; return RPiController.class;
} }
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return TemperatureSensorData.class;
}
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj){
if(obj instanceof RPiTemperatureSensor && w1Address != null) 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.HalEventConfig;
import se.hal.intf.HalEventController; 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.TellstickDevice;
import se.hal.plugin.tellstick.TellstickDeviceGroup; import se.hal.plugin.tellstick.TellstickDeviceGroup;
import se.hal.plugin.tellstick.TellstickSerialComm; import se.hal.plugin.tellstick.TellstickSerialComm;
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol; 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.parser.binary.BinaryStruct;
import zutil.ui.Configurator; import zutil.ui.Configurator;
@ -99,11 +103,16 @@ public class NexaSelfLearning implements HalEventConfig,TellstickDevice,Tellstic
} }
@Override
public Class<? extends HalEventController> getEventController() { public Class<? extends HalEventController> getEventControllerClass() {
return TellstickSerialComm.class; return TellstickSerialComm.class;
} }
@Override
public Class<? extends HalEventData> getEventDataClass() {
return SwitchEventData.class;
}
@Override @Override
public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; } public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; }
@Override @Override

View file

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

View file

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

View file

@ -1,16 +1,23 @@
package se.hal.struct; package se.hal.struct;
import se.hal.intf.HalDeviceData;
import se.hal.intf.HalEventController; import se.hal.intf.HalEventController;
import se.hal.intf.HalEventConfig; import se.hal.intf.HalEventConfig;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventData;
import se.hal.util.DeviceDataSqlResult;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.SQLResultHandler;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler; import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.handler.SimpleSQLResult;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger; 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 { 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" ); PreparedStatement stmt = db.getPreparedStatement(
return DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(Event.class, db) ); "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(){ 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.HalSensorController;
import se.hal.intf.HalSensorConfig; import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorData;
import se.hal.util.DeviceDataSqlResult;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler; import zutil.db.bean.DBBeanSQLResultHandler;
@ -13,6 +14,7 @@ import zutil.log.LogUtil;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -109,6 +111,24 @@ public class Sensor extends AbstractDevice<HalSensorConfig,HalSensorData>{
public Class<? extends HalSensorController> getController(){ 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() { public double getData() {
return dimmValue; 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() { public double getData() {
return humidity; 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 * @return int representing Watt/Hour
*/ */
@ -33,4 +28,9 @@ public class PowerConsumptionSensorData extends HalSensorData {
public double getData() { public double getData() {
return wattHours; 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(){ public boolean isOn(){
return enabled; return enabled;
} }
@Override @Override
public double getData() { public double getData() {
return (enabled ? 1.0 : 0.0); 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() { public double getData() {
return temperature; 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.Before;
import org.junit.Test; import org.junit.Test;
import se.hal.intf.*; import se.hal.intf.*;
import se.hal.struct.devicedata.DimmerEventData;
import se.hal.struct.devicedata.SwitchEventData; import se.hal.struct.devicedata.SwitchEventData;
import se.hal.struct.devicedata.TemperatureSensorData; import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.converter.Converter; import zutil.converter.Converter;
@ -95,14 +96,18 @@ public class TelstickSerialCommEventTest {
ArrayList<TellstickDecodedEntry> list = new ArrayList<>(); ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
list.add(new TellstickDecodedEntry( list.add(new TellstickDecodedEntry(
this, new TemperatureSensorData(testData) this, new DimmerEventData(testData)
)); ));
return list; return list;
} }
@Override @Override
public Class<? extends HalEventController> getEventController() { return null; } public Class<? extends HalEventController> getEventControllerClass() { return null; }
@Override
public Class<? extends HalEventData> getEventDataClass() {
return null;
}
@Override @Override
public boolean equals(Object obj) {return testData == ((TestEvent)obj).testData;} 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.Before;
import org.junit.Test; import org.junit.Test;
import se.hal.intf.HalSensorConfig; import se.hal.intf.*;
import se.hal.intf.HalSensorController; import se.hal.struct.devicedata.SwitchEventData;
import se.hal.intf.HalSensorData;
import se.hal.intf.HalSensorReportListener;
import se.hal.struct.devicedata.TemperatureSensorData; import se.hal.struct.devicedata.TemperatureSensorData;
import zutil.converter.Converter; import zutil.converter.Converter;
@ -97,6 +95,10 @@ public class TelstickSerialCommSensorTest {
@Override @Override
public AggregationMethod getAggregationMethod() { return null; } public AggregationMethod getAggregationMethod() { return null; }
@Override @Override
public Class<? extends HalSensorController> getSensorController() { return null; } public Class<? extends HalSensorController> getSensorControllerClass() { return null; }
@Override
public Class<? extends HalSensorData> getSensorDataClass() {
return null;
}
} }
} }