Added data report interval so the null values in the graphs are specific to different protocols
This commit is contained in:
parent
3be4168cf2
commit
1983f3a55d
10 changed files with 76 additions and 21 deletions
|
|
@ -15,6 +15,6 @@ public interface HalEventData {
|
|||
* 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);
|
||||
boolean equals(HalEventData obj);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,26 @@ public interface HalSensorData {
|
|||
|
||||
double getData();
|
||||
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* This method needs to be implemented.
|
||||
* NOTE: it should not compare data and timestamp, only static or unique data for the event type.
|
||||
* 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);
|
||||
boolean equals(HalSensorData obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,13 @@ public class MapHttpPage extends HalHttpPage implements HalHttpPage.HalJsonPage
|
|||
} else if (request.containsKey("bgimage")) {
|
||||
if (bgImage == null)
|
||||
loadBgImage();
|
||||
out.setHeader("Content-Type", "image/"+bgType);
|
||||
out.setHeader("Content-Length", ""+bgImage.length);
|
||||
if (bgImage == null)
|
||||
out.setStatusCode(404);
|
||||
else {
|
||||
out.setHeader("Content-Type", "image/" + bgType);
|
||||
out.setHeader("Content-Length", "" + bgImage.length);
|
||||
out.write(bgImage);
|
||||
}
|
||||
} else { // Run default Hal behaviour
|
||||
super.respond(out, header, session, cookie, request);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@ public class NutUpsDevice implements PowerConsumptionSensorData{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
public long getDataInterval(){
|
||||
return 60*1000; // 1 min
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalSensorData obj){
|
||||
if (obj instanceof NutUpsDevice)
|
||||
return deviceId != null && deviceId.equals(((NutUpsDevice)obj).deviceId);
|
||||
return false;
|
||||
|
|
|
|||
8
src/se/hal/plugin/raspberry/RPiPowerConsumptionSensor.java
Normal file → Executable file
8
src/se/hal/plugin/raspberry/RPiPowerConsumptionSensor.java
Normal file → Executable file
|
|
@ -1,6 +1,7 @@
|
|||
package se.hal.plugin.raspberry;
|
||||
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.struct.PowerConsumptionSensorData;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
|
|
@ -32,6 +33,11 @@ public class RPiPowerConsumptionSensor implements PowerConsumptionSensorData {
|
|||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataInterval(){
|
||||
return 60*1000; // 1 min
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
return AggregationMethod.SUM;
|
||||
|
|
@ -42,7 +48,7 @@ public class RPiPowerConsumptionSensor implements PowerConsumptionSensorData {
|
|||
return RPiController.class;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj){
|
||||
public boolean equals(HalSensorData obj){
|
||||
if(!(obj instanceof RPiPowerConsumptionSensor))
|
||||
return false;
|
||||
return ((RPiPowerConsumptionSensor)obj).gpioPin == gpioPin;
|
||||
|
|
|
|||
8
src/se/hal/plugin/raspberry/RPiTemperatureSensor.java
Normal file → Executable file
8
src/se/hal/plugin/raspberry/RPiTemperatureSensor.java
Normal file → Executable file
|
|
@ -1,6 +1,7 @@
|
|||
package se.hal.plugin.raspberry;
|
||||
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.struct.TemperatureSensorData;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
|
|
@ -31,6 +32,11 @@ public class RPiTemperatureSensor implements TemperatureSensorData {
|
|||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataInterval() {
|
||||
return 10*60*1000; // 10 min
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
return AggregationMethod.AVERAGE;
|
||||
|
|
@ -41,7 +47,7 @@ public class RPiTemperatureSensor implements TemperatureSensorData {
|
|||
return RPiController.class;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj){
|
||||
public boolean equals(HalSensorData obj){
|
||||
if(obj instanceof RPiTemperatureSensor)
|
||||
return obj == this;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,4 @@ public abstract class TellstickProtocol {
|
|||
public abstract String encode();
|
||||
public abstract void decode(byte[] data);
|
||||
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
package se.hal.plugin.tellstick.protocols;
|
||||
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.plugin.tellstick.TellstickGroupProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.struct.SwitchEventData;
|
||||
|
|
@ -147,7 +148,7 @@ public class NexaSelfLearning extends TellstickProtocol
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
public boolean equals(HalEventData obj){
|
||||
if(obj instanceof NexaSelfLearning)
|
||||
return ((NexaSelfLearning) obj).house == house &&
|
||||
((NexaSelfLearning) obj).group == group &&
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package se.hal.plugin.tellstick.protocols;
|
||||
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.struct.PowerConsumptionSensorData;
|
||||
import zutil.log.LogUtil;
|
||||
|
|
@ -15,15 +16,19 @@ public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionS
|
|||
|
||||
@Configurator.Configurable("Address")
|
||||
private int address = 0;
|
||||
@Configurator.Configurable("Report Interval(ms)")
|
||||
private int interval = 60*1000; // default 1 min
|
||||
|
||||
private double temperature = 0;
|
||||
private double humidity = 0;
|
||||
|
||||
|
||||
|
||||
public Oregon0x1A2D(){
|
||||
super("oregon", "0x1A2D");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return null;
|
||||
|
|
@ -63,7 +68,7 @@ public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionS
|
|||
|
||||
}
|
||||
|
||||
public boolean equals(Object obj){
|
||||
public boolean equals(HalSensorData obj){
|
||||
if(! (obj instanceof Oregon0x1A2D))
|
||||
return false;
|
||||
return ((Oregon0x1A2D)obj).address == this.address;
|
||||
|
|
@ -90,6 +95,11 @@ public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionS
|
|||
return temperature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
return AggregationMethod.SUM;
|
||||
|
|
|
|||
|
|
@ -54,15 +54,23 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
|
|||
default: throw new IllegalArgumentException("selected aggrPeriodLength is not supported");
|
||||
}
|
||||
stmt.setLong(4, (System.currentTimeMillis() - ageLimitInMs) );
|
||||
return DBConnection.exec(stmt , new AggregateDataListSqlResult());
|
||||
return DBConnection.exec(stmt , new AggregateDataListSqlResult(sensor));
|
||||
}
|
||||
|
||||
|
||||
private Sensor sensor;
|
||||
|
||||
private AggregateDataListSqlResult(Sensor sensor){
|
||||
this.sensor = sensor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<AggregateData> handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
|
||||
ArrayList<AggregateData> list = new ArrayList<>();
|
||||
long previousTimestampEnd = -1;
|
||||
while(result.next()){
|
||||
while (result.next()){
|
||||
|
||||
int id = result.getInt("id");
|
||||
long timestampStart = result.getLong("timestamp_start");
|
||||
|
|
@ -70,18 +78,22 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
|
|||
String username = result.getString("username");
|
||||
float confidence = result.getFloat("confidence");
|
||||
|
||||
//Calculate the data point
|
||||
// Calculate the data point
|
||||
float data = result.getFloat("data"); //the "raw" recorded data
|
||||
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
|
||||
if(previousTimestampEnd != -1 && previousTimestampEnd+1 < timestampStart){
|
||||
list.add(new AggregateData(id, previousTimestampEnd+1, null /*Float.NaN*/, username));
|
||||
// Only add nulls if the report interval is smaller than the aggregated interval
|
||||
if (sensor.getDeviceData() == null ||
|
||||
timestampStart-timestampEnd > sensor.getDeviceData().getDataInterval()) {
|
||||
// Add null data point to list if one or more periods of data is missing before this
|
||||
if (previousTimestampEnd != -1 && previousTimestampEnd + 1 < timestampStart) {
|
||||
list.add(new AggregateData(id, previousTimestampEnd + 1, null /*Float.NaN*/, username));
|
||||
}
|
||||
}
|
||||
|
||||
list.add(new AggregateData(id, timestampEnd, (estimatedData/1000f), username)); //add this data point to list
|
||||
|
||||
//update previous end timestamp
|
||||
// Update previous end timestamp
|
||||
previousTimestampEnd = timestampEnd;
|
||||
}
|
||||
return list;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue