Initial refactoring of device structure

This commit is contained in:
Ziver Koc 2016-08-17 15:46:10 +02:00
parent 1526e58b06
commit 52afc53660
35 changed files with 318 additions and 268 deletions

View file

@ -29,7 +29,7 @@ public class ControllerManager implements HalSensorReportListener,
/** All available sensor plugins **/ /** All available sensor plugins **/
private List<Class<? extends HalSensorData>> availableSensors = new ArrayList<>(); private List<Class<? extends HalSensorConfig>> availableSensors = new ArrayList<>();
/** List of all registered sensors **/ /** List of all registered sensors **/
private List<Sensor> registeredSensors = Collections.synchronizedList(new ArrayList<Sensor>()); private List<Sensor> registeredSensors = Collections.synchronizedList(new ArrayList<Sensor>());
/** List of auto detected sensors **/ /** List of auto detected sensors **/
@ -39,7 +39,7 @@ public class ControllerManager implements HalSensorReportListener,
/** All available event plugins **/ /** All available event plugins **/
private List<Class<? extends HalEventData>> availableEvents = new ArrayList<>(); private List<Class<? extends HalEventConfig>> availableEvents = new ArrayList<>();
/** List of all registered events **/ /** List of all registered events **/
private List<Event> registeredEvents = Collections.synchronizedList(new ArrayList<Event>()); private List<Event> registeredEvents = Collections.synchronizedList(new ArrayList<Event>());
/** List of auto detected events **/ /** List of auto detected events **/
@ -82,7 +82,7 @@ public class ControllerManager implements HalSensorReportListener,
} }
Class<? extends HalSensorController> c = sensor.getController(); Class<? extends HalSensorController> c = sensor.getController();
HalSensorController controller = (HalSensorController) controllerMap.get(c);; HalSensorController controller = (HalSensorController) controllerMap.get(c);
if (controller != null) { if (controller != null) {
logger.info("Deregistering sensor(id: "+ sensor.getId() +"): "+ sensor.getDeviceConfig().getClass()); logger.info("Deregistering sensor(id: "+ sensor.getId() +"): "+ sensor.getDeviceConfig().getClass());
controller.deregister(sensor.getDeviceConfig()); controller.deregister(sensor.getDeviceConfig());
@ -93,7 +93,7 @@ public class ControllerManager implements HalSensorReportListener,
} }
} }
public List<Class<? extends HalSensorData>> getAvailableSensors(){ public List<Class<? extends HalSensorConfig>> getAvailableSensors(){
return availableSensors; return availableSensors;
} }
@ -102,37 +102,37 @@ public class ControllerManager implements HalSensorReportListener,
} }
@Override @Override
public void reportReceived(HalSensorData sensorData) { public void reportReceived(HalSensorConfig sensorConfig, HalSensorData sensorData) {
try{ try{
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
Sensor sensor = findSensor(sensorData, registeredSensors); Sensor sensor = findSensor(sensorConfig, registeredSensors);
if (sensor != null) { if (sensor != null) {
logger.finest("Received report from sensor("+sensorData.getClass().getSimpleName()+"): "+ sensorData); logger.finest("Received report from sensor("+sensorConfig.getClass().getSimpleName()+"): "+ sensorConfig);
PreparedStatement stmt = PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO sensor_data_raw (timestamp, sensor_id, data) VALUES(?, ?, ?)"); db.getPreparedStatement("INSERT INTO sensor_data_raw (timestamp, sensor_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, sensorData.getTimestamp()); stmt.setLong(1, sensorData.getTimestamp());
stmt.setLong(2, sensor.getId()); stmt.setLong(2, sensor.getId());
stmt.setDouble(3, sensorData.getData()); stmt.setDouble(3, sensorData.getData());
db.exec(stmt); DBConnection.exec(stmt);
} }
else { // unknown sensor else { // unknown sensor
logger.finest("Received report from unregistered sensor" + logger.finest("Received report from unregistered sensor" +
"("+sensorData.getClass().getSimpleName()+"): "+ sensorData); "("+sensorConfig.getClass().getSimpleName()+"): "+ sensorConfig);
sensor = findSensor(sensorData, detectedSensors); sensor = findSensor(sensorConfig, detectedSensors);
if(sensor == null) { if(sensor == null) {
sensor = new Sensor(); sensor = new Sensor();
detectedSensors.add(sensor); detectedSensors.add(sensor);
} }
} }
sensor.setDeviceConfig(sensorData); // Set the latest data sensor.setDeviceConfig(sensorConfig); // Set the latest data
}catch (SQLException e){ }catch (SQLException e){
logger.log(Level.WARNING, "Unable to store sensor report", e); logger.log(Level.WARNING, "Unable to store sensor report", e);
} }
} }
private static Sensor findSensor(HalSensorData sensorData, List<Sensor> list){ private static Sensor findSensor(HalSensorConfig sensorData, List<Sensor> list){
for (int i=0; i<list.size(); ++i) { // Don't use foreach for concurrency reasons for (int i=0; i<list.size(); ++i) { // Don't use foreach for concurrency reasons
Sensor s = list.get(i); Sensor s = list.get(i);
if (sensorData.equals(s.getDeviceConfig())) { if (sensorData.equals(s.getDeviceConfig())) {
@ -182,7 +182,7 @@ public class ControllerManager implements HalSensorReportListener,
} }
} }
public List<Class<? extends HalEventData>> getAvailableEvents(){ public List<Class<? extends HalEventConfig>> getAvailableEvents(){
return availableEvents; return availableEvents;
} }
@ -191,37 +191,37 @@ public class ControllerManager implements HalSensorReportListener,
} }
@Override @Override
public void reportReceived(HalEventData eventData) { public void reportReceived(HalEventConfig eventConfig, HalEventData eventData) {
try { try {
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
Event event = findEvent(eventData, registeredEvents); Event event = findEvent(eventConfig, registeredEvents);
if (event != null) { if (event != null) {
logger.finest("Received report from event("+eventData.getClass().getSimpleName()+"): "+ eventData); logger.finest("Received report from event("+eventConfig.getClass().getSimpleName()+"): "+ eventConfig);
PreparedStatement stmt = PreparedStatement stmt =
db.getPreparedStatement("INSERT INTO event_data_raw (timestamp, event_id, data) VALUES(?, ?, ?)"); db.getPreparedStatement("INSERT INTO event_data_raw (timestamp, event_id, data) VALUES(?, ?, ?)");
stmt.setLong(1, eventData.getTimestamp()); stmt.setLong(1, eventData.getTimestamp());
stmt.setLong(2, event.getId()); stmt.setLong(2, event.getId());
stmt.setDouble(3, eventData.getData()); stmt.setDouble(3, eventData.getData());
db.exec(stmt); DBConnection.exec(stmt);
} }
else { // unknown sensor else { // unknown sensor
logger.info("Received report from unregistered event" + logger.info("Received report from unregistered event" +
"("+eventData.getClass().getSimpleName()+"): "+ eventData); "("+eventConfig.getClass().getSimpleName()+"): "+ eventConfig);
event = findEvent(eventData, detectedEvents); event = findEvent(eventConfig, detectedEvents);
if(event == null) { if(event == null) {
event = new Event(); event = new Event();
detectedEvents.add(event); detectedEvents.add(event);
} }
} }
event.setDeviceConfig(eventData); // Set the latest data event.setDeviceConfig(eventConfig); // Set the latest data
}catch (SQLException e){ }catch (SQLException e){
logger.log(Level.WARNING, "Unable to store event report", e); logger.log(Level.WARNING, "Unable to store event report", e);
} }
} }
private static Event findEvent(HalEventData eventData, List<Event> list){ private static Event findEvent(HalEventConfig eventData, List<Event> list){
for (int i=0; i<list.size(); ++i) { // Don't use foreach for concurrency reasons for (int i=0; i<list.size(); ++i) { // Don't use foreach for concurrency reasons
Event e = list.get(i); Event e = list.get(i);
if (eventData.equals(e.getDeviceConfig())) { if (eventData.equals(e.getDeviceConfig())) {
@ -235,7 +235,7 @@ public class ControllerManager implements HalSensorReportListener,
HalEventController controller = getControllerInstance(event.getController()); HalEventController controller = getControllerInstance(event.getController());
if(controller != null) { if(controller != null) {
controller.send(event.getDeviceConfig()); controller.send(event.getDeviceConfig());
reportReceived(event.getDeviceConfig()); // save action to db reportReceived(event.getDeviceConfig(), event.getDeviceData()); // save action to db
} }
else else
logger.warning("No controller found for event id: "+ event.getId()); logger.warning("No controller found for event id: "+ event.getId());
@ -245,15 +245,15 @@ public class ControllerManager implements HalSensorReportListener,
@Override @Override
public void preConfigurationAction(Configurator configurator, Object obj) { public void preConfigurationAction(Configurator configurator, Object obj) {
if(obj instanceof HalSensorData) { if(obj instanceof HalSensorConfig) {
Sensor sensor = findSensor((HalSensorData) obj, registeredSensors); Sensor sensor = findSensor((HalSensorConfig) obj, registeredSensors);
if(sensor != null){ if(sensor != null){
deregister(sensor); deregister(sensor);
limboSensors.add(sensor); limboSensors.add(sensor);
} }
} }
else if(obj instanceof HalEventData) { else if(obj instanceof HalEventConfig) {
Event event = findEvent((HalEventData) obj, registeredEvents); Event event = findEvent((HalEventConfig) obj, registeredEvents);
if(event != null){ if(event != null){
deregister(event); deregister(event);
limboEvents.add(event); limboEvents.add(event);
@ -263,15 +263,15 @@ public class ControllerManager implements HalSensorReportListener,
@Override @Override
public void postConfigurationAction(Configurator configurator, Object obj) { public void postConfigurationAction(Configurator configurator, Object obj) {
if(obj instanceof HalSensorData) { if(obj instanceof HalSensorConfig) {
Sensor sensor = findSensor((HalSensorData) obj, limboSensors); Sensor sensor = findSensor((HalSensorConfig) obj, limboSensors);
if(sensor != null){ if(sensor != null){
register(sensor); register(sensor);
limboSensors.remove(sensor); limboSensors.remove(sensor);
} }
} }
else if(obj instanceof HalEventData) { else if(obj instanceof HalEventConfig) {
Event event = findEvent((HalEventData) obj, limboEvents); Event event = findEvent((HalEventConfig) obj, limboEvents);
if(event != null){ if(event != null){
register(event); register(event);
limboEvents.remove(event); limboEvents.remove(event);
@ -280,7 +280,7 @@ public class ControllerManager implements HalSensorReportListener,
} }
private <T> T getControllerInstance(Class<T> c){ private <T> T getControllerInstance(Class<T> c){
Object controller = null; Object controller;
if (controllerMap.containsKey(c)) if (controllerMap.containsKey(c))
controller = controllerMap.get(c); controller = controllerMap.get(c);
else { else {
@ -341,13 +341,13 @@ public class ControllerManager implements HalSensorReportListener,
public static void initialize(PluginManager pluginManager){ public static void initialize(PluginManager pluginManager){
ControllerManager manager = new ControllerManager(); ControllerManager manager = new ControllerManager();
for (Iterator<Class<? extends HalSensorData>> it=pluginManager.getClassIterator(HalSensorData.class); for (Iterator<Class<? extends HalSensorConfig>> it = pluginManager.getClassIterator(HalSensorConfig.class);
it.hasNext(); ){ it.hasNext(); ){
manager.availableSensors.add(it.next()); manager.availableSensors.add(it.next());
} }
for (Iterator<Class<? extends HalEventData>> it=pluginManager.getClassIterator(HalEventData.class); for (Iterator<Class<? extends HalEventConfig>> it = pluginManager.getClassIterator(HalEventConfig.class);
it.hasNext(); ){ it.hasNext(); ){
manager.availableEvents.add(it.next()); manager.availableEvents.add(it.next());
} }

View file

@ -4,7 +4,7 @@ import se.hal.bot.AliceBot;
import se.hal.intf.HalBot; import se.hal.intf.HalBot;
import se.hal.intf.HalSpeachToText; import se.hal.intf.HalSpeachToText;
import se.hal.intf.HalTextToSpeach; import se.hal.intf.HalTextToSpeach;
import se.hal.struct.SwitchEventData; import se.hal.struct.devicedata.SwitchEventData;
import se.hal.stt.ManualSTTClient; import se.hal.stt.ManualSTTClient;
import se.hal.tts.MaryRemoteTTSClient; import se.hal.tts.MaryRemoteTTSClient;

View file

@ -2,7 +2,7 @@ package se.hal.deamon;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.intf.HalDaemon; import se.hal.intf.HalDaemon;
import se.hal.intf.HalSensorData.AggregationMethod; import se.hal.intf.HalSensorConfig.AggregationMethod;
import se.hal.struct.Sensor; import se.hal.struct.Sensor;
import se.hal.util.UTCTimePeriod; import se.hal.util.UTCTimePeriod;
import se.hal.util.UTCTimeUtility; import se.hal.util.UTCTimeUtility;

View file

@ -0,0 +1,18 @@
package se.hal.intf;
/**
* Interface representing event type specific configuration data.
*
* Created by Ziver on 2015-12-23.
*/
public interface HalEventConfig {
Class<? extends HalEventController> getEventController();
/**
* This method needs to be implemented.
* NOTE: it should not compare data and timestamp, only static or unique data for the event type.
*/
boolean equals(Object obj);
}

View file

@ -15,18 +15,18 @@ public interface HalEventController {
/** /**
* Will register an event type to be handled by this controller * Will register an event type to be handled by this controller
*/ */
void register(HalEventData event); void register(HalEventConfig event);
/** /**
* Deregisters an event from this controller, the controller * Deregisters an event from this controller, the controller
* will no longer handle that type of event * will no longer handle that type of event
*/ */
void deregister(HalEventData event); void deregister(HalEventConfig event);
/** /**
* @param event transmit this event if possible. * @param event transmit this event if possible.
*/ */
void send(HalEventData event); // TODO: where to put data? void send(HalEventConfig event); // TODO: where to put data?
/** /**
* @return the number of registered objects * @return the number of registered objects

View file

@ -1,20 +1,25 @@
package se.hal.intf; package se.hal.intf;
/** /**
* Created by Ziver on 2015-12-23. * Interface representing one report from an event
*
* Created by Ziver on 2016-08-17.
*/ */
public interface HalEventData { public abstract class HalEventData {
long getTimestamp(); private long timestamp = -1;
double getData();
Class<? extends HalEventController> getEventController(); public long getTimestamp(){
return timestamp;
}
public void setTimestamp(long timestamp){
this.timestamp = timestamp;
}
/** /**
* This method needs to be implemented. * @return serialized event data converted to double that will be saved in DB.
* NOTE: it should not compare data and timestamp, only static or unique data for the event type.
*/ */
boolean equals(Object obj); public abstract double getData();
} }

View file

@ -2,6 +2,6 @@ package se.hal.intf;
public interface HalEventReportListener { public interface HalEventReportListener {
void reportReceived(HalEventData e); void reportReceived(HalEventConfig e, HalEventData d);
} }

View file

@ -0,0 +1,36 @@
package se.hal.intf;
/**
* Interface representing sensor type specific configuration data.
*
* Created by Ziver on 2015-12-23.
*/
public interface HalSensorConfig {
enum AggregationMethod{
SUM,
AVERAGE
}
/**
* @return the intended data reporting interval in milliseconds.
*/
long getDataInterval();
/**
* @return which aggregation method that should be used to aggregate the reported data.
*/
AggregationMethod getAggregationMethod();
/**
* @return the Controller class where SensorData should be registered on
*/
Class<? extends HalSensorController> getSensorController();
/**
* NOTE: it should only static or unique data for the sensor type.
* This method is used to associate reported data with registered sensors
*/
boolean equals(Object obj);
}

View file

@ -15,13 +15,13 @@ public interface HalSensorController {
/** /**
* Will register a sensor type to be handled by this controller * Will register a sensor type to be handled by this controller
*/ */
void register(HalSensorData sensor); void register(HalSensorConfig sensor);
/** /**
* Deregisters a sensor from this controller, the controller * Deregisters a sensor from this controller, the controller
* will no longer handle that type of sensor * will no longer handle that type of sensor
*/ */
void deregister(HalSensorData sensor); void deregister(HalSensorConfig sensor);
/** /**
* @return the number of registered objects * @return the number of registered objects

View file

@ -1,39 +1,25 @@
package se.hal.intf; package se.hal.intf;
/** /**
* Created by Ziver on 2015-12-23. * Interface representing one data report from a sensor.
*
* Created by Ziver on 2016-08-17.
*/ */
public interface HalSensorData { public abstract class HalSensorData {
enum AggregationMethod{
SUM, private long timestamp = -1;
AVERAGE
public long getTimestamp(){
return timestamp;
}
public void setTimestamp(long timestamp){
this.timestamp = timestamp;
} }
long getTimestamp();
double getData();
/** /**
* @return the intended data reporting interval in milliseconds. * @return serialized sensor data converted to double that will be saved in DB.
*/ */
long getDataInterval(); public abstract double getData();
/**
* @return which aggregation method that should be used to aggregate the reported data.
*/
AggregationMethod getAggregationMethod();
/**
* @return the Controller class where SensorData should be registered on
*/
Class<? extends HalSensorController> getSensorController();
/**
* NOTE: it should only static or unique data for the sensor type.
* This method is used to associate reported data with registered sensors
*/
boolean equals(Object obj);
} }

View file

@ -2,6 +2,6 @@ package se.hal.intf;
public interface HalSensorReportListener { public interface HalSensorReportListener {
void reportReceived(HalSensorData s); void reportReceived(HalSensorConfig s, HalSensorData d);
} }

View file

@ -2,10 +2,10 @@ package se.hal.page;
import se.hal.ControllerManager; import se.hal.ControllerManager;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventConfig;
import se.hal.intf.HalHttpPage; import se.hal.intf.HalHttpPage;
import se.hal.struct.Event; import se.hal.struct.Event;
import se.hal.struct.SwitchEventData; import se.hal.struct.devicedata.SwitchEventData;
import se.hal.util.HistoryDataListSqlResult; import se.hal.util.HistoryDataListSqlResult;
import se.hal.util.HistoryDataListSqlResult.HistoryData; import se.hal.util.HistoryDataListSqlResult.HistoryData;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -40,7 +40,7 @@ public class EventOverviewHttpPage extends HalHttpPage {
if(request.containsKey("action")){ if(request.containsKey("action")){
// change event data // change event data
Event event = Event.getEvent(db, id); Event event = Event.getEvent(db, id);
HalEventData eventData = event.getDeviceConfig(); HalEventConfig eventData = event.getDeviceConfig();
if (eventData instanceof SwitchEventData){ if (eventData instanceof SwitchEventData){
if ( request.containsKey("data") && "on".equals(request.get("data"))) if ( request.containsKey("data") && "on".equals(request.get("data")))
((SwitchEventData)eventData).turnOn(); ((SwitchEventData)eventData).turnOn();

View file

@ -112,7 +112,7 @@ public class MapHttpPage extends HalHttpPage implements HalHttpPage.HalJsonPage
DataNode sensorsNode = new DataNode(DataNode.DataType.List); DataNode sensorsNode = new DataNode(DataNode.DataType.List);
for (Sensor sensor : Sensor.getLocalSensors(db)) { for (Sensor sensor : Sensor.getLocalSensors(db)) {
DataNode sensorNode = getDeviceNode(sensor); DataNode sensorNode = getDeviceNode(sensor);
sensorNode.set("data", sensor.getDeviceConfig().getData()); sensorNode.set("data", sensor.getDeviceData().getData());
sensorsNode.add(sensorNode); sensorsNode.add(sensorNode);
} }
root.set("sensors", sensorsNode); root.set("sensors", sensorsNode);
@ -120,7 +120,7 @@ public class MapHttpPage extends HalHttpPage implements HalHttpPage.HalJsonPage
DataNode eventsNode = new DataNode(DataNode.DataType.List); DataNode eventsNode = new DataNode(DataNode.DataType.List);
for (Event event : Event.getLocalEvents(db)) { for (Event event : Event.getLocalEvents(db)) {
DataNode eventNode = getDeviceNode(event); DataNode eventNode = getDeviceNode(event);
eventNode.set("data", event.getDeviceConfig().getData()); eventNode.set("data", event.getDeviceData().getData());
eventsNode.add(eventNode); eventsNode.add(eventNode);
} }
root.set("events", eventsNode); root.set("events", eventsNode);

View file

@ -3,7 +3,7 @@ package se.hal.page;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength;
import se.hal.intf.HalHttpPage; import se.hal.intf.HalHttpPage;
import se.hal.struct.PowerConsumptionSensorData; import se.hal.struct.devicedata.PowerConsumptionSensorData;
import se.hal.struct.Sensor; import se.hal.struct.Sensor;
import se.hal.struct.User; import se.hal.struct.User;
import se.hal.util.AggregateDataListSqlResult; import se.hal.util.AggregateDataListSqlResult;

View file

@ -3,11 +3,13 @@ package se.hal.plugin.nutups;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.intf.HalAutoScannableController; import se.hal.intf.HalAutoScannableController;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorReportListener; import se.hal.intf.HalSensorReportListener;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import zutil.osal.app.linux.NutUPSClient; import zutil.osal.app.linux.NutUPSClient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -21,6 +23,7 @@ public class NutUpsController implements HalSensorController, HalAutoScannableCo
public static Logger logger = LogUtil.getLogger(); public static Logger logger = LogUtil.getLogger();
private static final int SYNC_INTERVAL = 60 * 1000; private static final int SYNC_INTERVAL = 60 * 1000;
private HashMap<String,NutUpsDevice> registeredDevices = new HashMap<>();
private NutUPSClient client; private NutUPSClient client;
private ScheduledExecutorService executor; private ScheduledExecutorService executor;
private HalSensorReportListener listener; private HalSensorReportListener listener;
@ -56,7 +59,10 @@ public class NutUpsController implements HalSensorController, HalAutoScannableCo
try { try {
if (client != null && listener != null) { if (client != null && listener != null) {
for (NutUPSClient.UPSDevice ups : client.getUPSList()) { for (NutUPSClient.UPSDevice ups : client.getUPSList()) {
listener.reportReceived(new NutUpsDevice(ups)); NutUpsDevice device = registeredDevices.get(ups.getId());
if (device == null)
device = new NutUpsDevice(ups);
listener.reportReceived(device, device.read(ups));
} }
} }
} catch (Exception e){ } catch (Exception e){
@ -72,12 +78,12 @@ public class NutUpsController implements HalSensorController, HalAutoScannableCo
@Override @Override
public void register(HalSensorData sensor) { public void register(HalSensorConfig sensor) {
registeredDevices.put(((NutUpsDevice) sensor).getUpsId(), (NutUpsDevice) sensor);
} }
@Override @Override
public void deregister(HalSensorData sensor) { public void deregister(HalSensorConfig sensor) {
registeredDevices.remove(((NutUpsDevice) sensor).getUpsId());
} }
@Override @Override
public int size() { public int size() {

View file

@ -1,41 +1,41 @@
package se.hal.plugin.nutups; package se.hal.plugin.nutups;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorData;
import se.hal.struct.PowerConsumptionSensorData; import se.hal.struct.devicedata.PowerConsumptionSensorData;
import zutil.osal.app.linux.NutUPSClient; import zutil.osal.app.linux.NutUPSClient;
import zutil.ui.Configurator; import zutil.ui.Configurator;
/** /**
* Created by Ziver on 2016-05-25. * Created by Ziver on 2016-05-25.
*/ */
public class NutUpsDevice implements PowerConsumptionSensorData{ public class NutUpsDevice implements HalSensorConfig{
@Configurator.Configurable("UPS id") @Configurator.Configurable("UPS id")
private String deviceId; private String upsId;
private long timestamp;
private double consumption;
public NutUpsDevice(){} public NutUpsDevice(){}
protected NutUpsDevice(NutUPSClient.UPSDevice ups){ protected NutUpsDevice(NutUPSClient.UPSDevice ups){
this.deviceId = ups.getId(); this.upsId = ups.getId();
this.timestamp = System.currentTimeMillis();
this.consumption = ups.getPowerUsage() * 1/60.0; // convert watt min to watt hour
} }
@Override protected HalSensorData read(NutUPSClient.UPSDevice ups){
public long getTimestamp() { PowerConsumptionSensorData data = new PowerConsumptionSensorData();
return timestamp; data.setTimestamp(System.currentTimeMillis());
data.setConsumption(ups.getPowerUsage() * 1/60.0); // convert watt min to watt hour
return data;
} }
@Override
public double getData() { public String getUpsId(){
return consumption; return upsId;
} }
@Override @Override
public long getDataInterval(){ public long getDataInterval(){
return 60*1000; // 1 min return 60*1000; // 1 min
@ -44,13 +44,12 @@ public class NutUpsDevice implements PowerConsumptionSensorData{
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj){
if (obj instanceof NutUpsDevice) if (obj instanceof NutUpsDevice)
return deviceId != null && deviceId.equals(((NutUpsDevice)obj).deviceId); return upsId != null && upsId.equals(((NutUpsDevice)obj).upsId);
return false; return false;
} }
public String toString(){ public String toString(){
return "id: "+deviceId + return "id: "+ upsId;
", consumption: "+consumption;
} }
@Override @Override

View file

@ -1,7 +1,7 @@
package se.hal.plugin.raspberry; package se.hal.plugin.raspberry;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorReportListener; import se.hal.intf.HalSensorReportListener;
import se.hal.plugin.raspberry.hardware.RPiDS18B20; import se.hal.plugin.raspberry.hardware.RPiDS18B20;
import se.hal.plugin.raspberry.hardware.RPiInteruptPulseFlankCounter; import se.hal.plugin.raspberry.hardware.RPiInteruptPulseFlankCounter;
@ -27,7 +27,7 @@ public class RPiController implements HalSensorController {
} }
@Override @Override
public void register(HalSensorData sensor) { public void register(HalSensorConfig sensor) {
if(sensor instanceof RPiPowerConsumptionSensor){ if(sensor instanceof RPiPowerConsumptionSensor){
RPiPowerConsumptionSensor powerConsumptionSensor = (RPiPowerConsumptionSensor) sensor; RPiPowerConsumptionSensor powerConsumptionSensor = (RPiPowerConsumptionSensor) sensor;
int gpioPin = powerConsumptionSensor.getGpioPin(); int gpioPin = powerConsumptionSensor.getGpioPin();
@ -52,7 +52,7 @@ public class RPiController implements HalSensorController {
} }
@Override @Override
public void deregister(HalSensorData sensor) { public void deregister(HalSensorConfig sensor) {
if(sensor instanceof RPiPowerConsumptionSensor){ if(sensor instanceof RPiPowerConsumptionSensor){
RPiPowerConsumptionSensor powerConsumprtionSensor = (RPiPowerConsumptionSensor) sensor; RPiPowerConsumptionSensor powerConsumprtionSensor = (RPiPowerConsumptionSensor) sensor;
RPiSensor sensorToDeregister = pinToSensorMap.remove("GPIO_"+powerConsumprtionSensor.getGpioPin()); RPiSensor sensorToDeregister = pinToSensorMap.remove("GPIO_"+powerConsumprtionSensor.getGpioPin());
@ -89,9 +89,9 @@ public class RPiController implements HalSensorController {
} }
} }
public void sendDataReport(HalSensorData sensorData){ public void sendDataReport(HalSensorConfig sensorConfig){
if(sensorListener != null){ if(sensorListener != null){
sensorListener.reportReceived(sensorData); sensorListener.reportReceived(sensorConfig);
}else{ }else{
logger.log(Level.WARNING, "Could not report data. No registered listener"); logger.log(Level.WARNING, "Could not report data. No registered listener");
} }

View file

@ -1,37 +1,25 @@
package se.hal.plugin.raspberry; package se.hal.plugin.raspberry;
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.PowerConsumptionSensorData;
import zutil.ui.Configurator; import zutil.ui.Configurator;
public class RPiPowerConsumptionSensor implements PowerConsumptionSensorData { public class RPiPowerConsumptionSensor implements HalSensorConfig {
@Configurator.Configurable("GPIO-Pin") @Configurator.Configurable("GPIO-Pin")
private int gpioPin = -1; private int gpioPin = -1;
private double data;
private long timestamp;
public RPiPowerConsumptionSensor(){ public RPiPowerConsumptionSensor(){
//need to be empty for the framework to create an instance //need to be empty for the framework to create an instance
} }
public RPiPowerConsumptionSensor(int gpioPin, long timestamp, double data) { public RPiPowerConsumptionSensor(int gpioPin) {
this.gpioPin = gpioPin; this.gpioPin = gpioPin;
this.timestamp = timestamp;
this.data = data;
} }
@Override
public long getTimestamp() {
return timestamp;
}
@Override
public double getData() {
return data;
}
@Override @Override
public long getDataInterval(){ public long getDataInterval(){
@ -60,6 +48,6 @@ public class RPiPowerConsumptionSensor implements PowerConsumptionSensorData {
} }
public String toString(){ public String toString(){
return "gpioPin:" + gpioPin +", data:" + data; return "gpioPin:" + gpioPin;
} }
} }

View file

@ -1,36 +1,17 @@
package se.hal.plugin.raspberry; package se.hal.plugin.raspberry;
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.TemperatureSensorData;
import zutil.ui.Configurator; import zutil.ui.Configurator;
public class RPiTemperatureSensor implements TemperatureSensorData { public class RPiTemperatureSensor implements HalSensorConfig {
@Configurator.Configurable("1-Wire Address") @Configurator.Configurable("1-Wire Address")
private String w1Address = null; private String w1Address = null;
private double data;
private long timestamp;
public RPiTemperatureSensor(){
//need to be empty for the framework to create an instance
}
public RPiTemperatureSensor(long timestamp, double data) {
this.timestamp = timestamp;
this.data = data;
}
@Override
public long getTimestamp() {
return timestamp;
}
@Override
public double getData() {
return data;
}
@Override @Override
public long getDataInterval() { public long getDataInterval() {
@ -58,8 +39,4 @@ public class RPiTemperatureSensor implements TemperatureSensorData {
return w1Address; return w1Address;
} }
@Override
public double getTemperature() {
return data;
}
} }

View file

@ -53,7 +53,8 @@ public class RPiDS18B20 implements RPiSensor, Runnable {
public void run() { public void run() {
for(TemperatureSensor device : w1Mater.getDevices(TemperatureSensor.class)){ for(TemperatureSensor device : w1Mater.getDevices(TemperatureSensor.class)){
if(device.getName().equals(w1Address)){ if(device.getName().equals(w1Address)){
controller.sendDataReport(new RPiTemperatureSensor(System.currentTimeMillis(), device.getTemperature(TemperatureScale.CELSIUS))); controller.sendDataReport(
new RPiTemperatureSensor(System.currentTimeMillis(), device.getTemperature(TemperatureScale.CELSIUS)));
break; break;
} }
} }

View file

@ -123,10 +123,10 @@ public class TellstickSerialComm implements Runnable,
} }
} }
private void reportEvent(TellstickProtocol protocol){ private void reportEvent(TellstickProtocol protocol){
if (sensorListener != null && protocol instanceof HalSensorData) if (sensorListener != null && protocol instanceof HalSensorConfig)
sensorListener.reportReceived((HalSensorData) protocol); sensorListener.reportReceived((HalSensorConfig) protocol);
else if (eventListener != null && protocol instanceof HalEventData) else if (eventListener != null && protocol instanceof HalEventConfig)
eventListener.reportReceived((HalEventData) protocol); eventListener.reportReceived((HalEventConfig) protocol);
} }
/** /**
@ -181,7 +181,7 @@ public class TellstickSerialComm implements Runnable,
@Override @Override
public void send(HalEventData event) { public void send(HalEventConfig event) {
if(event instanceof TellstickProtocol) if(event instanceof TellstickProtocol)
write((TellstickProtocol) event); write((TellstickProtocol) event);
} }
@ -203,23 +203,23 @@ public class TellstickSerialComm implements Runnable,
@Override @Override
public void register(HalEventData event) { public void register(HalEventConfig event) {
if(event instanceof TellstickProtocol) if(event instanceof TellstickProtocol)
registeredDevices.add((TellstickProtocol) event); registeredDevices.add((TellstickProtocol) event);
} }
@Override @Override
public void register(HalSensorData sensor) { public void register(HalSensorConfig sensor) {
if(sensor instanceof TellstickProtocol) if(sensor instanceof TellstickProtocol)
registeredDevices.add((TellstickProtocol) sensor); registeredDevices.add((TellstickProtocol) sensor);
} }
@Override @Override
public void deregister(HalEventData event) { public void deregister(HalEventConfig event) {
if(event instanceof TellstickProtocol) if(event instanceof TellstickProtocol)
registeredDevices.remove((TellstickProtocol) event); registeredDevices.remove((TellstickProtocol) event);
} }
@Override @Override
public void deregister(HalSensorData sensor) { public void deregister(HalSensorConfig sensor) {
if(sensor instanceof TellstickProtocol) if(sensor instanceof TellstickProtocol)
registeredDevices.remove((TellstickProtocol) sensor); registeredDevices.remove((TellstickProtocol) sensor);
} }

View file

@ -22,10 +22,10 @@
package se.hal.plugin.tellstick.protocols; package se.hal.plugin.tellstick.protocols;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventConfig;
import se.hal.plugin.tellstick.TellstickGroupProtocol; import se.hal.plugin.tellstick.TellstickGroupProtocol;
import se.hal.plugin.tellstick.TellstickProtocol; import se.hal.plugin.tellstick.TellstickProtocol;
import se.hal.struct.SwitchEventData; import se.hal.struct.devicedata.SwitchEventData;
import zutil.ByteUtil; import zutil.ByteUtil;
import zutil.parser.binary.BinaryStruct; import zutil.parser.binary.BinaryStruct;
import zutil.parser.binary.BinaryStructInputStream; import zutil.parser.binary.BinaryStructInputStream;
@ -38,7 +38,7 @@ import java.io.IOException;
* Created by Ziver on 2015-02-18. * Created by Ziver on 2015-02-18.
*/ */
public class NexaSelfLearning extends TellstickProtocol public class NexaSelfLearning extends TellstickProtocol
implements SwitchEventData,TellstickGroupProtocol,BinaryStruct { implements HalEventConfig,TellstickGroupProtocol,BinaryStruct {
@BinaryField(index=1, length=26) @BinaryField(index=1, length=26)
@Configurator.Configurable("House code") @Configurator.Configurable("House code")
@ -128,16 +128,6 @@ public class NexaSelfLearning extends TellstickProtocol
this.unit = unit; this.unit = unit;
} }
public boolean isOn() {
return enable;
}
public void turnOn() {
enable = true;
}
public void turnOff() {
enable = false;
}
public String toString(){ public String toString(){
@ -168,8 +158,4 @@ public class NexaSelfLearning extends TellstickProtocol
this.enable = ((NexaSelfLearning) group).enable; this.enable = ((NexaSelfLearning) group).enable;
} }
@Override
public double getData() {
return (enable ? 1 : 0);
}
} }

View file

@ -1,8 +1,8 @@
package se.hal.plugin.tellstick.protocols; package se.hal.plugin.tellstick.protocols;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorConfig;
import se.hal.plugin.tellstick.TellstickProtocol; import se.hal.plugin.tellstick.TellstickProtocol;
import se.hal.struct.PowerConsumptionSensorData; import se.hal.struct.devicedata.PowerConsumptionSensorData;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import zutil.ui.Configurator; import zutil.ui.Configurator;
@ -11,7 +11,7 @@ import java.util.logging.Logger;
/** /**
* Created by Ziver on 2015-11-19. * Created by Ziver on 2015-11-19.
*/ */
public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionSensorData { public class Oregon0x1A2D extends TellstickProtocol implements HalSensorConfig {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
@Configurator.Configurable("Address") @Configurator.Configurable("Address")
@ -82,19 +82,6 @@ public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionS
} }
public double getTemperature(){
return temperature;
}
public double getHumidity(){
return humidity;
}
@Override
public double getData() {
return temperature;
}
@Override @Override
public long getDataInterval() { public long getDataInterval() {

View file

@ -15,7 +15,7 @@ import java.util.logging.Logger;
/** /**
* Created by Ziver on 2016-01-15. * Created by Ziver on 2016-01-15.
*/ */
public abstract class AbstractDevice<T> extends DBBean { public abstract class AbstractDevice<T,D> extends DBBean {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
// Sensor specific data // Sensor specific data
@ -26,7 +26,7 @@ public abstract class AbstractDevice<T> extends DBBean {
/** Sensor specific configuration **/ /** Sensor specific configuration **/
private transient T deviceConfig; private transient T deviceConfig;
/** latest device data received **/ /** latest device data received **/
private transient Object latestDeviceData; private transient D latestDeviceData;
// User configuration // User configuration
@DBColumn("user_id") @DBColumn("user_id")
@ -39,6 +39,7 @@ public abstract class AbstractDevice<T> extends DBBean {
private double y; private double y;
/**************** DEVICE CONFIG ******************/
public Configurator<T> getDeviceConfigurator() { public Configurator<T> getDeviceConfigurator() {
T obj = getDeviceConfig(); T obj = getDeviceConfig();
@ -109,6 +110,20 @@ public abstract class AbstractDevice<T> extends DBBean {
} }
/**************** DEVICE DATA ******************/
/**
* @return the latest known data from the device
*/
public D getDeviceData(){
return latestDeviceData;
}
public void setDeviceData(D latest){
this.latestDeviceData = latest;
}
/**************** OTHER VALUES ******************/
public String getName() { public String getName() {
return name; return name;

View file

@ -1,6 +1,7 @@
package se.hal.struct; package se.hal.struct;
import se.hal.intf.HalEventController; import se.hal.intf.HalEventController;
import se.hal.intf.HalEventConfig;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventData;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
@ -16,7 +17,7 @@ import java.util.logging.Logger;
* Created by Ziver on 2015-12-15. * Created by Ziver on 2015-12-15.
*/ */
@DBBean.DBTable(value="event", superBean=true) @DBBean.DBTable(value="event", superBean=true)
public class Event extends AbstractDevice<HalEventData>{ public class Event extends AbstractDevice<HalEventConfig,HalEventData>{
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();

View file

@ -1,11 +0,0 @@
package se.hal.struct;
import se.hal.intf.HalSensorData;
/**
* Created by Ziver on 2015-12-03.
*/
public interface HumiditySensorData extends HalSensorData {
double getHumidity();
}

View file

@ -1,11 +0,0 @@
package se.hal.struct;
import se.hal.intf.HalSensorData;
/**
* Should return Watt Hour as data
*
* Created by Ziver on 2015-12-03.
*/
public interface PowerConsumptionSensorData extends HalSensorData {
}

View file

@ -2,6 +2,7 @@ package se.hal.struct;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.intf.HalSensorController; import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorData; import se.hal.intf.HalSensorData;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
@ -16,7 +17,7 @@ import java.util.logging.Logger;
@DBBean.DBTable(value="sensor", superBean=true) @DBBean.DBTable(value="sensor", superBean=true)
public class Sensor extends AbstractDevice<HalSensorData>{ public class Sensor extends AbstractDevice<HalSensorConfig,HalSensorData>{
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private long external_id = -1; private long external_id = -1;

View file

@ -1,11 +0,0 @@
package se.hal.struct;
import se.hal.intf.HalSensorData;
/**
* Created by Ziver on 2015-12-03.
*/
public interface TemperatureSensorData extends HalSensorData {
double getTemperature();
}

View file

@ -20,13 +20,20 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package se.hal.struct; package se.hal.struct.devicedata;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventData;
/** /**
* Created by Ziver on 2015-05-07. * Created by Ziver on 2015-05-07.
*/ */
public abstract class DimmerEventData implements HalEventData { public class DimmerEventData extends HalEventData {
private double dimmValue;
@Override
public double getData() {
return dimmValue;
}
} }

View file

@ -0,0 +1,18 @@
package se.hal.struct.devicedata;
import se.hal.intf.HalSensorData;
/**
* Created by Ziver on 2015-12-03.
*/
public class HumiditySensorData extends HalSensorData {
private double humidity;
@Override
public double getData() {
return humidity;
}
}

View file

@ -0,0 +1,24 @@
package se.hal.struct.devicedata;
import se.hal.intf.HalSensorData;
/**
* Created by Ziver on 2015-12-03.
*/
public class PowerConsumptionSensorData extends HalSensorData {
private double wattHours;
public void setConsumption(double wattHours){
this.wattHours = wattHours;
}
/**
* @return int representing Watt/Hour
*/
@Override
public double getData() {
return wattHours;
}
}

View file

@ -20,17 +20,30 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package se.hal.struct; package se.hal.struct.devicedata;
import se.hal.intf.HalEventData; import se.hal.intf.HalEventData;
/** /**
* Created by Ziver on 2015-05-07. * Created by Ziver on 2015-05-07.
*/ */
public interface SwitchEventData extends HalEventData { public class SwitchEventData extends HalEventData {
boolean isOn(); private boolean enabled;
void turnOn();
void turnOff(); public void turnOn(){
enabled = true;
}
public void turnOff(){
enabled = false;
}
public boolean isOn(){
return enabled;
}
@Override
public double getData() {
return (enabled ? 1.0 : 0.0);
}
} }

View file

@ -0,0 +1,27 @@
package se.hal.struct.devicedata;
import se.hal.intf.HalSensorData;
/**
* Created by Ziver on 2015-12-03.
*/
public class TemperatureSensorData extends HalSensorData {
private double temperature;
/**
* @param data the temperature to set in degrees C
*/
public void setData(double data){
this.temperature = data;
}
/**
* @return temperature in degrees C
*/
@Override
public double getData() {
return temperature;
}
}

View file

@ -2,23 +2,11 @@ package se.hal.plugin.tellstick;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import se.hal.HalContext; import se.hal.intf.HalEventConfig;
import se.hal.intf.HalEventData;
import se.hal.intf.HalEventReportListener; import se.hal.intf.HalEventReportListener;
import se.hal.intf.HalSensorData;
import se.hal.intf.HalSensorReportListener;
import se.hal.plugin.tellstick.protocols.Oregon0x1A2D;
import zutil.converter.Converter; import zutil.converter.Converter;
import zutil.db.DBConnection;
import zutil.log.CompactLogFormatter;
import zutil.log.LogUtil;
import zutil.struct.MutableInt;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -54,10 +42,10 @@ public class TelstickSerialCommTest {
public void unregisteredEvent(){ public void unregisteredEvent(){
// Setup // Setup
TellstickSerialComm tellstick = new TellstickSerialComm(); TellstickSerialComm tellstick = new TellstickSerialComm();
final ArrayList<HalEventData> list = new ArrayList<>(); final ArrayList<HalEventConfig> list = new ArrayList<>();
tellstick.setListener(new HalEventReportListener() { tellstick.setListener(new HalEventReportListener() {
@Override @Override
public void reportReceived(HalEventData e) { public void reportReceived(HalEventConfig e) {
list.add(e); list.add(e);
} }
}); });
@ -72,10 +60,10 @@ public class TelstickSerialCommTest {
public void event(){ public void event(){
// Setup // Setup
TellstickSerialComm tellstick = new TellstickSerialComm(); TellstickSerialComm tellstick = new TellstickSerialComm();
final ArrayList<HalEventData> list = new ArrayList<>(); final ArrayList<HalEventConfig> list = new ArrayList<>();
tellstick.setListener(new HalEventReportListener() { tellstick.setListener(new HalEventReportListener() {
@Override @Override
public void reportReceived(HalEventData e) { public void reportReceived(HalEventConfig e) {
list.add(e); list.add(e);
} }
}); });
@ -91,7 +79,7 @@ public class TelstickSerialCommTest {
private static class TestEvent extends TellstickProtocol implements HalEventData{ private static class TestEvent extends TellstickProtocol implements HalEventConfig {
public int testData; public int testData;
public TestEvent(){ public TestEvent(){