Preparations for a major refactoring

This commit is contained in:
Ziver Koc 2016-08-16 16:12:44 +02:00
parent bd54762bac
commit 1526e58b06
13 changed files with 62 additions and 66 deletions

View file

@ -5,7 +5,6 @@ import se.hal.struct.Event;
import se.hal.struct.Sensor; import se.hal.struct.Sensor;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import zutil.plugin.PluginData;
import zutil.plugin.PluginManager; import zutil.plugin.PluginManager;
import zutil.ui.Configurator; import zutil.ui.Configurator;
import zutil.ui.Configurator.PostConfigurationActionListener; import zutil.ui.Configurator.PostConfigurationActionListener;
@ -57,27 +56,27 @@ public class ControllerManager implements HalSensorReportListener,
/////////////////////////////// SENSORS /////////////////////////////////// /////////////////////////////// SENSORS ///////////////////////////////////
public void register(Sensor sensor) { public void register(Sensor sensor) {
if(sensor.getDeviceData() == null) { if(sensor.getDeviceConfig() == null) {
logger.warning("Sensor data is null: "+ sensor); logger.warning("Sensor data is null: "+ sensor);
return; return;
} }
if(!availableSensors.contains(sensor.getDeviceData().getClass())) { if(!availableSensors.contains(sensor.getDeviceConfig().getClass())) {
logger.warning("Sensor data plugin not available: "+ sensor.getDeviceData().getClass()); logger.warning("Sensor data plugin not available: "+ sensor.getDeviceConfig().getClass());
return; return;
} }
logger.info("Registering new sensor(id: "+ sensor.getId() +"): "+ sensor.getDeviceData().getClass()); logger.info("Registering new sensor(id: "+ sensor.getId() +"): "+ sensor.getDeviceConfig().getClass());
Class<? extends HalSensorController> c = sensor.getController(); Class<? extends HalSensorController> c = sensor.getController();
HalSensorController controller = getControllerInstance(c); HalSensorController controller = getControllerInstance(c);
if(controller != null) if(controller != null)
controller.register(sensor.getDeviceData()); controller.register(sensor.getDeviceConfig());
registeredSensors.add(sensor); registeredSensors.add(sensor);
detectedSensors.remove(findSensor(sensor.getDeviceData(), detectedSensors)); // Remove if this device was detected detectedSensors.remove(findSensor(sensor.getDeviceConfig(), detectedSensors)); // Remove if this device was detected
} }
public void deregister(Sensor sensor){ public void deregister(Sensor sensor){
if(sensor.getDeviceData() == null) { if(sensor.getDeviceConfig() == null) {
logger.warning("Sensor data is null: "+ sensor); logger.warning("Sensor data is null: "+ sensor);
return; return;
} }
@ -85,8 +84,8 @@ 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.getDeviceData().getClass()); logger.info("Deregistering sensor(id: "+ sensor.getId() +"): "+ sensor.getDeviceConfig().getClass());
controller.deregister(sensor.getDeviceData()); controller.deregister(sensor.getDeviceConfig());
registeredSensors.remove(sensor); registeredSensors.remove(sensor);
removeControllerIfEmpty(controller); removeControllerIfEmpty(controller);
} else { } else {
@ -126,7 +125,7 @@ public class ControllerManager implements HalSensorReportListener,
detectedSensors.add(sensor); detectedSensors.add(sensor);
} }
} }
sensor.setDeviceData(sensorData); // Set the latest data sensor.setDeviceConfig(sensorData); // 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);
@ -136,7 +135,7 @@ public class ControllerManager implements HalSensorReportListener,
private static Sensor findSensor(HalSensorData sensorData, List<Sensor> list){ private static Sensor findSensor(HalSensorData 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.getDeviceData())) { if (sensorData.equals(s.getDeviceConfig())) {
return s; return s;
} }
} }
@ -146,27 +145,27 @@ public class ControllerManager implements HalSensorReportListener,
//////////////////////////////// EVENTS /////////////////////////////////// //////////////////////////////// EVENTS ///////////////////////////////////
public void register(Event event) { public void register(Event event) {
if(event.getDeviceData() == null) { if(event.getDeviceConfig() == null) {
logger.warning("Event data is null: "+ event); logger.warning("Event data is null: "+ event);
return; return;
} }
if(!availableEvents.contains(event.getDeviceData().getClass())) { if(!availableEvents.contains(event.getDeviceConfig().getClass())) {
logger.warning("Event data plugin not available: "+ event.getDeviceData().getClass()); logger.warning("Event data plugin not available: "+ event.getDeviceConfig().getClass());
return; return;
} }
logger.info("Registering new event(id: "+ event.getId() +"): "+ event.getDeviceData().getClass()); logger.info("Registering new event(id: "+ event.getId() +"): "+ event.getDeviceConfig().getClass());
Class<? extends HalEventController> c = event.getController(); Class<? extends HalEventController> c = event.getController();
HalEventController controller = getControllerInstance(c); HalEventController controller = getControllerInstance(c);
if(controller != null) if(controller != null)
controller.register(event.getDeviceData()); controller.register(event.getDeviceConfig());
registeredEvents.add(event); registeredEvents.add(event);
detectedEvents.remove(findEvent(event.getDeviceData(), detectedEvents)); // Remove if this device was detected detectedEvents.remove(findEvent(event.getDeviceConfig(), detectedEvents)); // Remove if this device was detected
} }
public void deregister(Event event){ public void deregister(Event event){
if(event.getDeviceData() == null) { if(event.getDeviceConfig() == null) {
logger.warning("Event data is null: "+ event); logger.warning("Event data is null: "+ event);
return; return;
} }
@ -174,8 +173,8 @@ public class ControllerManager implements HalSensorReportListener,
Class<? extends HalEventController> c = event.getController(); Class<? extends HalEventController> c = event.getController();
HalEventController controller = (HalEventController) controllerMap.get(c); HalEventController controller = (HalEventController) controllerMap.get(c);
if (controller != null) { if (controller != null) {
logger.info("Deregistering event(id: "+ event.getId() +"): "+ event.getDeviceData().getClass()); logger.info("Deregistering event(id: "+ event.getId() +"): "+ event.getDeviceConfig().getClass());
controller.deregister(event.getDeviceData()); controller.deregister(event.getDeviceConfig());
registeredEvents.remove(event); registeredEvents.remove(event);
removeControllerIfEmpty(controller); removeControllerIfEmpty(controller);
} else { } else {
@ -215,7 +214,7 @@ public class ControllerManager implements HalSensorReportListener,
detectedEvents.add(event); detectedEvents.add(event);
} }
} }
event.setDeviceData(eventData); // Set the latest data event.setDeviceConfig(eventData); // 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);
@ -225,7 +224,7 @@ public class ControllerManager implements HalSensorReportListener,
private static Event findEvent(HalEventData eventData, List<Event> list){ private static Event findEvent(HalEventData 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.getDeviceData())) { if (eventData.equals(e.getDeviceConfig())) {
return e; return e;
} }
} }
@ -235,8 +234,8 @@ public class ControllerManager implements HalSensorReportListener,
public void send(Event event){ public void send(Event event){
HalEventController controller = getControllerInstance(event.getController()); HalEventController controller = getControllerInstance(event.getController());
if(controller != null) { if(controller != null) {
controller.send(event.getDeviceData()); controller.send(event.getDeviceConfig());
reportReceived(event.getDeviceData()); // save action to db reportReceived(event.getDeviceConfig()); // 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());

View file

@ -83,7 +83,7 @@ public class PCDataSynchronizationClient implements HalDaemon {
sensor.setType(sensorDTO.type); sensor.setType(sensorDTO.type);
sensor.setUser(user); sensor.setUser(user);
sensor.getDeviceConfig().setValues(JSONParser.read(sensorDTO.config)).applyConfiguration(); sensor.getDeviceConfigurator().setValues(JSONParser.read(sensorDTO.config)).applyConfiguration();
sensor.save(db); sensor.save(db);
} catch (Exception e){ } catch (Exception e){
logger.warning("Unable to register external sensor: " + logger.warning("Unable to register external sensor: " +

View file

@ -90,7 +90,7 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
dto.sensorId = sensor.getId(); dto.sensorId = sensor.getId();
dto.name = sensor.getName(); dto.name = sensor.getName();
dto.type = sensor.getType(); dto.type = sensor.getType();
dto.config = JSONWriter.toString(sensor.getDeviceConfig().getValuesAsNode()); dto.config = JSONWriter.toString(sensor.getDeviceConfigurator().getValuesAsNode());
rsp.sensors.add(dto); rsp.sensors.add(dto);
} }
} }

View file

@ -55,11 +55,11 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
} }
public void aggregateSensor(Sensor sensor) { public void aggregateSensor(Sensor sensor) {
if(sensor.getDeviceData() == null){ if(sensor.getDeviceConfig() == null){
logger.fine("The sensor type is not supported - ignoring it"); logger.fine("The sensor type is not supported - ignoring it");
return; return;
} }
logger.fine("The sensor is of type: " + sensor.getDeviceData().getClass().getName()); logger.fine("The sensor is of type: " + sensor.getDeviceConfig().getClass().getName());
long aggregationStartTime = System.currentTimeMillis(); long aggregationStartTime = System.currentTimeMillis();
@ -83,7 +83,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
*/ */
private void aggregateRawData(Sensor sensor, AggregationPeriodLength aggrPeriodLength, long ageLimitInMs, int expectedSampleCount, long aggregationStartTime){ private void aggregateRawData(Sensor sensor, AggregationPeriodLength aggrPeriodLength, long ageLimitInMs, int expectedSampleCount, long aggregationStartTime){
long sensorId = sensor.getId(); long sensorId = sensor.getId();
AggregationMethod aggrMethod = sensor.getDeviceData().getAggregationMethod(); AggregationMethod aggrMethod = sensor.getDeviceConfig().getAggregationMethod();
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
PreparedStatement stmt = null; PreparedStatement stmt = null;
try { try {

View file

@ -7,7 +7,6 @@ import se.hal.struct.Event;
import se.hal.struct.User; import se.hal.struct.User;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
import zutil.net.http.HttpHeader;
import zutil.parser.Templator; import zutil.parser.Templator;
import zutil.ui.Configurator; import zutil.ui.Configurator;
import zutil.ui.Configurator.ConfigurationParam; import zutil.ui.Configurator.ConfigurationParam;
@ -60,7 +59,7 @@ public class EventConfigHttpPage extends HalHttpPage {
event.setName(request.get("name")); event.setName(request.get("name"));
event.setType(request.get("type")); event.setType(request.get("type"));
event.setUser(localUser); event.setUser(localUser);
event.getDeviceConfig().setValues(request).applyConfiguration(); event.getDeviceConfigurator().setValues(request).applyConfiguration();
event.save(db); event.save(db);
ControllerManager.getInstance().register(event); ControllerManager.getInstance().register(event);
break; break;
@ -70,7 +69,7 @@ public class EventConfigHttpPage extends HalHttpPage {
event.setName(request.get("name")); event.setName(request.get("name"));
event.setType(request.get("type")); event.setType(request.get("type"));
event.setUser(localUser); event.setUser(localUser);
event.getDeviceConfig().setValues(request).applyConfiguration(); event.getDeviceConfigurator().setValues(request).applyConfiguration();
event.save(db); event.save(db);
} }
break; break;

View file

@ -10,7 +10,6 @@ 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;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
import zutil.net.http.HttpHeader;
import zutil.parser.Templator; import zutil.parser.Templator;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -41,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.getDeviceData(); HalEventData 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

@ -19,7 +19,6 @@ import zutil.parser.Templator;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
/** /**
@ -113,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.getDeviceData().getData()); sensorNode.set("data", sensor.getDeviceConfig().getData());
sensorsNode.add(sensorNode); sensorsNode.add(sensorNode);
} }
root.set("sensors", sensorsNode); root.set("sensors", sensorsNode);
@ -121,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.getDeviceData().getData()); eventNode.set("data", event.getDeviceConfig().getData());
eventsNode.add(eventNode); eventsNode.add(eventNode);
} }
root.set("events", eventsNode); root.set("events", eventsNode);

View file

@ -11,7 +11,6 @@ import se.hal.util.AggregateDataListSqlResult.AggregateData;
import se.hal.util.UTCTimeUtility; import se.hal.util.UTCTimeUtility;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
import zutil.net.http.HttpHeader;
import zutil.parser.DataNode; import zutil.parser.DataNode;
import zutil.parser.Templator; import zutil.parser.Templator;
@ -114,8 +113,8 @@ public class PCOverviewHttpPage extends HalHttpPage implements HalHttpPage.HalJs
private List<Sensor> getSensorList(DBConnection db) throws SQLException { private List<Sensor> getSensorList(DBConnection db) throws SQLException {
List<Sensor> sensors = new ArrayList<>(); List<Sensor> sensors = new ArrayList<>();
for (Sensor sensor : Sensor.getSensors(db)) { for (Sensor sensor : Sensor.getSensors(db)) {
if (sensor.getDeviceData() != null && if (sensor.getDeviceConfig() != null &&
sensor.getDeviceData() instanceof PowerConsumptionSensorData) sensor.getDeviceConfig() instanceof PowerConsumptionSensorData)
sensors.add(sensor); sensors.add(sensor);
} }
return sensors; return sensors;

View file

@ -7,7 +7,6 @@ import se.hal.struct.Sensor;
import se.hal.struct.User; import se.hal.struct.User;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
import zutil.net.http.HttpHeader;
import zutil.parser.Templator; import zutil.parser.Templator;
import zutil.ui.Configurator; import zutil.ui.Configurator;
import zutil.ui.Configurator.ConfigurationParam; import zutil.ui.Configurator.ConfigurationParam;
@ -62,7 +61,7 @@ public class SensorConfigHttpPage extends HalHttpPage {
sensor.setType(request.get("type")); sensor.setType(request.get("type"));
sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
sensor.setUser(localUser); sensor.setUser(localUser);
sensor.getDeviceConfig().setValues(request).applyConfiguration(); sensor.getDeviceConfigurator().setValues(request).applyConfiguration();
sensor.save(db); sensor.save(db);
ControllerManager.getInstance().register(sensor); ControllerManager.getInstance().register(sensor);
break; break;
@ -72,7 +71,7 @@ public class SensorConfigHttpPage extends HalHttpPage {
sensor.setName(request.get("name")); sensor.setName(request.get("name"));
sensor.setType(request.get("type")); sensor.setType(request.get("type"));
sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
sensor.getDeviceConfig().setValues(request).applyConfiguration(); sensor.getDeviceConfigurator().setValues(request).applyConfiguration();
sensor.save(db); sensor.save(db);
} }
break; break;

View file

@ -13,7 +13,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* Created by ezivkoc on 2016-01-15. * Created by Ziver on 2016-01-15.
*/ */
public abstract class AbstractDevice<T> extends DBBean { public abstract class AbstractDevice<T> extends DBBean {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
@ -21,10 +21,12 @@ public abstract class AbstractDevice<T> extends DBBean {
// Sensor specific data // Sensor specific data
private String name; private String name;
private String type; private String type;
private String config; // only used to store the deviceData configuration in DB private String config; // only used to store the deviceConfig configuration in DB
// Sensor specific data /** Sensor specific configuration **/
private transient T deviceData; private transient T deviceConfig;
/** latest device data received **/
private transient Object latestDeviceData;
// User configuration // User configuration
@DBColumn("user_id") @DBColumn("user_id")
@ -38,8 +40,8 @@ public abstract class AbstractDevice<T> extends DBBean {
public Configurator<T> getDeviceConfig() { public Configurator<T> getDeviceConfigurator() {
T obj = getDeviceData(); T obj = getDeviceConfig();
if (obj != null) { if (obj != null) {
Configurator<T> configurator = new Configurator<>(obj); Configurator<T> configurator = new Configurator<>(obj);
configurator.setPreConfigurationListener(ControllerManager.getInstance()); configurator.setPreConfigurationListener(ControllerManager.getInstance());
@ -48,18 +50,18 @@ public abstract class AbstractDevice<T> extends DBBean {
} }
return null; return null;
} }
public T getDeviceData() { public T getDeviceConfig() {
if (deviceData == null || !deviceData.getClass().getName().equals(type)) { if (deviceConfig == null || !deviceConfig.getClass().getName().equals(type)) {
try { try {
Class c = Class.forName(type); Class c = Class.forName(type);
deviceData = (T) c.newInstance(); deviceConfig = (T) c.newInstance();
applyConfig(); applyConfig();
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Unable instantiate DeviceData: "+type, e); logger.log(Level.SEVERE, "Unable instantiate DeviceData: "+type, e);
} }
} }
return deviceData; return deviceConfig;
} }
/** /**
@ -67,20 +69,20 @@ public abstract class AbstractDevice<T> extends DBBean {
* And the current config will be applied on the new DeviceData. * And the current config will be applied on the new DeviceData.
* DeviceData will be reset if the input is set as null. * DeviceData will be reset if the input is set as null.
*/ */
public void setDeviceData(T data) { public void setDeviceConfig(T data) {
if(data != null) { if(data != null) {
deviceData = data; deviceConfig = data;
type = data.getClass().getName(); type = data.getClass().getName();
applyConfig(); // TODO: this is a bit clunky, should probably be solved in another way applyConfig(); // TODO: this is a bit clunky, should probably be solved in another way
} else { } else {
deviceData = null; deviceConfig = null;
type = null; type = null;
config = null; config = null;
} }
} }
public void save(DBConnection db) throws SQLException { public void save(DBConnection db) throws SQLException {
if (deviceData != null) if (deviceConfig != null)
updateConfigString(); updateConfigString();
else else
this.config = null; this.config = null;
@ -91,7 +93,7 @@ public abstract class AbstractDevice<T> extends DBBean {
* Will update the config String that will be stored in DB. * Will update the config String that will be stored in DB.
*/ */
protected void updateConfigString() { protected void updateConfigString() {
Configurator<T> configurator = getDeviceConfig(); Configurator<T> configurator = getDeviceConfigurator();
this.config = JSONWriter.toString(configurator.getValuesAsNode()); this.config = JSONWriter.toString(configurator.getValuesAsNode());
} }
/** /**
@ -100,7 +102,7 @@ public abstract class AbstractDevice<T> extends DBBean {
*/ */
protected void applyConfig(){ protected void applyConfig(){
if (config != null && !config.isEmpty()) { if (config != null && !config.isEmpty()) {
Configurator<T> configurator = getDeviceConfig(); Configurator<T> configurator = getDeviceConfigurator();
configurator.setValues(JSONParser.read(config)); configurator.setValues(JSONParser.read(config));
configurator.applyConfiguration(); configurator.applyConfiguration();
} }
@ -131,7 +133,7 @@ public abstract class AbstractDevice<T> extends DBBean {
if (this.type == null || !this.type.equals(type)) { if (this.type == null || !this.type.equals(type)) {
this.type = type; this.type = type;
this.config = null; this.config = null;
this.deviceData = null; // invalidate current sensor data object this.deviceConfig = null; // invalidate current sensor data object
} }
} }

View file

@ -32,6 +32,6 @@ public class Event extends AbstractDevice<HalEventData>{
public Class<? extends HalEventController> getController(){ public Class<? extends HalEventController> getController(){
return getDeviceData().getEventController(); return getDeviceConfig().getEventController();
} }
} }

View file

@ -108,6 +108,6 @@ public class Sensor extends AbstractDevice<HalSensorData>{
public Class<? extends HalSensorController> getController(){ public Class<? extends HalSensorController> getController(){
return getDeviceData().getSensorController(); return getDeviceConfig().getSensorController();
} }
} }

View file

@ -83,13 +83,13 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
float estimatedData = data/confidence; //estimate the "real" value of the data by looking at the confidence value float estimatedData = data/confidence; //estimate the "real" value of the data by looking at the confidence value
// Add null data point to list if one or more periods of data is missing before this // Add null data point to list if one or more periods of data is missing before this
if (previousTimestampEnd != -1 && sensor.getDeviceData() != null){ if (previousTimestampEnd != -1 && sensor.getDeviceConfig() != null){
boolean shortInterval = timestampEnd-timestampStart < sensor.getDeviceData().getDataInterval(); boolean shortInterval = timestampEnd-timestampStart < sensor.getDeviceConfig().getDataInterval();
long distance = timestampStart - (previousTimestampEnd + 1); long distance = timestampStart - (previousTimestampEnd + 1);
if (// Only add nulls if the report interval is smaller than the aggregated interval if (// Only add nulls if the report interval is smaller than the aggregated interval
!shortInterval && distance > 0 || !shortInterval && distance > 0 ||
// Only add nulls if space between aggr is larger than sensor report interval // Only add nulls if space between aggr is larger than sensor report interval
shortInterval && distance > sensor.getDeviceData().getDataInterval()) shortInterval && distance > sensor.getDeviceConfig().getDataInterval())
list.add(new AggregateData(id, previousTimestampEnd + 1, null /*Float.NaN*/, username)); list.add(new AggregateData(id, previousTimestampEnd + 1, null /*Float.NaN*/, username));
} }