Adding week aggregation with no age limit + small big fix where charts did cast all floating data points to int.
Former-commit-id: e8f027e2272271f1e54a5bb822529df7a8af6a6c
This commit is contained in:
parent
5352f876e9
commit
14608d80eb
5 changed files with 44 additions and 51 deletions
|
|
@ -57,6 +57,9 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
|
||||||
|
|
||||||
logger.fine("aggregating raw data into one day periods");
|
logger.fine("aggregating raw data into one day periods");
|
||||||
aggregateRawData(sensor, TimeUtility.DAY_IN_MS, TimeUtility.INFINITY, 60*24);
|
aggregateRawData(sensor, TimeUtility.DAY_IN_MS, TimeUtility.INFINITY, 60*24);
|
||||||
|
|
||||||
|
logger.fine("aggregating raw data into one week periods");
|
||||||
|
aggregateRawData(sensor, TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY, 60*24*7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ public class SensorDataCleanupDaemon implements HalDaemon {
|
||||||
if (sensor.getUser() != null) {
|
if (sensor.getUser() != null) {
|
||||||
cleanupSensorData(sensor.getId(), TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS); //clear 5-minute data older than a day
|
cleanupSensorData(sensor.getId(), TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS); //clear 5-minute data older than a day
|
||||||
cleanupSensorData(sensor.getId(), TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS); //clear 1-hour data older than a week
|
cleanupSensorData(sensor.getId(), TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS); //clear 1-hour data older than a week
|
||||||
|
//cleanupSensorData(sensor.getId(), TimeUtility.DAY_IN_MS, TimeUtility.INFINITY); //clear 1-day data older than infinity
|
||||||
|
//cleanupSensorData(sensor.getId(), TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY); //clear 1-week data older than infinity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,12 @@ import se.hal.HalContext;
|
||||||
import se.hal.intf.HalHttpPage;
|
import se.hal.intf.HalHttpPage;
|
||||||
import se.hal.util.AggregateDataListSqlResult;
|
import se.hal.util.AggregateDataListSqlResult;
|
||||||
import se.hal.util.AggregateDataListSqlResult.*;
|
import se.hal.util.AggregateDataListSqlResult.*;
|
||||||
import se.hal.util.TimeUtility;
|
|
||||||
import se.hal.struct.Sensor;
|
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.parser.Templator;
|
import zutil.parser.Templator;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -38,6 +36,7 @@ public class PCOverviewHttpPage extends HalHttpPage {
|
||||||
ArrayList<AggregateData> minDataList = new ArrayList<>();
|
ArrayList<AggregateData> minDataList = new ArrayList<>();
|
||||||
ArrayList<AggregateData> hourDataList = new ArrayList<>();
|
ArrayList<AggregateData> hourDataList = new ArrayList<>();
|
||||||
ArrayList<AggregateData> dayDataList = new ArrayList<>();
|
ArrayList<AggregateData> dayDataList = new ArrayList<>();
|
||||||
|
ArrayList<AggregateData> weekDataList = new ArrayList<>();
|
||||||
|
|
||||||
for(User user : users){
|
for(User user : users){
|
||||||
List<Sensor> userSensors = Sensor.getSensors(db, user);
|
List<Sensor> userSensors = Sensor.getSensors(db, user);
|
||||||
|
|
@ -47,6 +46,8 @@ public class PCOverviewHttpPage extends HalHttpPage {
|
||||||
hourDataList.addAll(AggregateDataListSqlResult.getHourAggregateData(db, sensor));
|
hourDataList.addAll(AggregateDataListSqlResult.getHourAggregateData(db, sensor));
|
||||||
|
|
||||||
dayDataList.addAll(AggregateDataListSqlResult.getDayAggregateData(db, sensor));
|
dayDataList.addAll(AggregateDataListSqlResult.getDayAggregateData(db, sensor));
|
||||||
|
|
||||||
|
weekDataList.addAll(AggregateDataListSqlResult.getWeekAggregateData(db, sensor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,6 +56,7 @@ public class PCOverviewHttpPage extends HalHttpPage {
|
||||||
tmpl.set("minData", minDataList);
|
tmpl.set("minData", minDataList);
|
||||||
tmpl.set("hourData", hourDataList);
|
tmpl.set("hourData", hourDataList);
|
||||||
tmpl.set("dayData", dayDataList);
|
tmpl.set("dayData", dayDataList);
|
||||||
|
tmpl.set("weekData", weekDataList);
|
||||||
tmpl.set("username", User.getUsers(db));
|
tmpl.set("username", User.getUsers(db));
|
||||||
|
|
||||||
return tmpl;
|
return tmpl;
|
||||||
|
|
|
||||||
|
|
@ -26,36 +26,29 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
|
||||||
|
|
||||||
|
|
||||||
public static List<AggregateData> getFiveMinuteAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
public static List<AggregateData> getFiveMinuteAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
||||||
PreparedStatement stmt = db.getPreparedStatement(
|
return getAggregateDataForPeriod(db, sensor, TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS);
|
||||||
"SELECT user.username as username,"
|
|
||||||
+ " sensor_data_aggr.timestamp_start as timestamp_start,"
|
|
||||||
+ " sensor_data_aggr.timestamp_end as timestamp_end,"
|
|
||||||
+ " sensor_data_aggr.data as data,"
|
|
||||||
+ " sensor_data_aggr.confidence as confidence,"
|
|
||||||
+ TimeUtility.FIVE_MINUTES_IN_MS + " as period_length"
|
|
||||||
+ " FROM sensor_data_aggr, user, sensor"
|
|
||||||
+ " WHERE sensor.id = sensor_data_aggr.sensor_id"
|
|
||||||
+ " AND sensor.id = ?"
|
|
||||||
+ " AND user.id = sensor.user_id"
|
|
||||||
+ " AND user.id = ?"
|
|
||||||
+ " AND timestamp_end-timestamp_start == ?"
|
|
||||||
+ " AND timestamp_start > ?"
|
|
||||||
+ " ORDER BY timestamp_start ASC");
|
|
||||||
stmt.setLong(1, sensor.getId());
|
|
||||||
stmt.setLong(2, sensor.getUser().getId());
|
|
||||||
stmt.setLong(3, TimeUtility.FIVE_MINUTES_IN_MS-1);
|
|
||||||
stmt.setLong(4, (System.currentTimeMillis() - TimeUtility.DAY_IN_MS) );
|
|
||||||
return DBConnection.exec(stmt , new AggregateDataListSqlResult());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<AggregateData> getHourAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
public static List<AggregateData> getHourAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
||||||
|
return getAggregateDataForPeriod(db, sensor, TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AggregateData> getDayAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
||||||
|
return getAggregateDataForPeriod(db, sensor, TimeUtility.DAY_IN_MS, TimeUtility.INFINITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AggregateData> getWeekAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
||||||
|
return getAggregateDataForPeriod(db, sensor, TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<AggregateData> getAggregateDataForPeriod(DBConnection db, Sensor sensor, long periodLengthInMs, long ageLimitInMs) throws SQLException {
|
||||||
PreparedStatement stmt = db.getPreparedStatement(
|
PreparedStatement stmt = db.getPreparedStatement(
|
||||||
"SELECT user.username as username,"
|
"SELECT user.username as username,"
|
||||||
+ " sensor_data_aggr.timestamp_start as timestamp_start,"
|
+ " sensor_data_aggr.timestamp_start as timestamp_start,"
|
||||||
+ " sensor_data_aggr.timestamp_end as timestamp_end,"
|
+ " sensor_data_aggr.timestamp_end as timestamp_end,"
|
||||||
+ " sensor_data_aggr.data as data,"
|
+ " sensor_data_aggr.data as data,"
|
||||||
+ " sensor_data_aggr.confidence as confidence,"
|
+ " sensor_data_aggr.confidence as confidence,"
|
||||||
+ TimeUtility.HOUR_IN_MS + " as period_length"
|
+ periodLengthInMs + " as period_length"
|
||||||
+ " FROM sensor_data_aggr, user, sensor"
|
+ " FROM sensor_data_aggr, user, sensor"
|
||||||
+ " WHERE sensor.id = sensor_data_aggr.sensor_id"
|
+ " WHERE sensor.id = sensor_data_aggr.sensor_id"
|
||||||
+ " AND sensor.id = ?"
|
+ " AND sensor.id = ?"
|
||||||
|
|
@ -66,30 +59,9 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
|
||||||
+ " ORDER BY timestamp_start ASC");
|
+ " ORDER BY timestamp_start ASC");
|
||||||
stmt.setLong(1, sensor.getId());
|
stmt.setLong(1, sensor.getId());
|
||||||
stmt.setLong(2, sensor.getUser().getId());
|
stmt.setLong(2, sensor.getUser().getId());
|
||||||
stmt.setLong(3, TimeUtility.HOUR_IN_MS - 1);
|
stmt.setLong(3, periodLengthInMs-1);
|
||||||
stmt.setLong(4, (System.currentTimeMillis() - TimeUtility.WEEK_IN_MS));
|
stmt.setLong(4, (System.currentTimeMillis() - ageLimitInMs) );
|
||||||
return DBConnection.exec(stmt, new AggregateDataListSqlResult());
|
return DBConnection.exec(stmt , new AggregateDataListSqlResult());
|
||||||
}
|
|
||||||
|
|
||||||
public static List<AggregateData> getDayAggregateData(DBConnection db, Sensor sensor) throws SQLException {
|
|
||||||
PreparedStatement stmt = db.getPreparedStatement(
|
|
||||||
"SELECT user.username as username,"
|
|
||||||
+ " sensor_data_aggr.timestamp_start as timestamp_start,"
|
|
||||||
+ " sensor_data_aggr.timestamp_end as timestamp_end,"
|
|
||||||
+ " sensor_data_aggr.data as data,"
|
|
||||||
+ " sensor_data_aggr.confidence as confidence,"
|
|
||||||
+ TimeUtility.DAY_IN_MS + " as period_length"
|
|
||||||
+ " FROM sensor_data_aggr, user, sensor"
|
|
||||||
+ " WHERE sensor.id = sensor_data_aggr.sensor_id"
|
|
||||||
+ " AND sensor.id = ?"
|
|
||||||
+ " AND user.id = sensor.user_id"
|
|
||||||
+ " AND user.id = ?"
|
|
||||||
+ " AND timestamp_end-timestamp_start == ?"
|
|
||||||
+ " ORDER BY timestamp_start ASC");
|
|
||||||
stmt.setLong(1, sensor.getId());
|
|
||||||
stmt.setLong(2, sensor.getUser().getId());
|
|
||||||
stmt.setLong(3, TimeUtility.DAY_IN_MS-1);
|
|
||||||
return DBConnection.exec(stmt, new AggregateDataListSqlResult());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -102,17 +74,20 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
|
||||||
long timestampStart = result.getLong("timestamp_start");
|
long timestampStart = result.getLong("timestamp_start");
|
||||||
long timestampEnd = result.getLong("timestamp_end");
|
long timestampEnd = result.getLong("timestamp_end");
|
||||||
long periodLength = result.getLong("period_length");
|
long periodLength = result.getLong("period_length");
|
||||||
int data = result.getInt("data");
|
float data = result.getFloat("data");
|
||||||
String username = result.getString("username");
|
String username = result.getString("username");
|
||||||
float confidence = result.getFloat("confidence");
|
float confidence = result.getFloat("confidence");
|
||||||
|
|
||||||
|
//Calculate values for future use
|
||||||
|
float estimatedData = data/confidence; //estimate the "real" value of the data by looking at the confidence value
|
||||||
|
Float limitedEstimatedData = (confidence > 0.5 ? estimatedData : null); //only present data with a confidence over 50%
|
||||||
|
|
||||||
//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 && timestampStart-previousTimestampEnd > periodLength){
|
if(previousTimestampEnd != -1 && timestampStart-previousTimestampEnd > periodLength){
|
||||||
list.add(new AggregateData(previousTimestampEnd+1, "null", username));
|
list.add(new AggregateData(previousTimestampEnd+1, "null", username));
|
||||||
}
|
}
|
||||||
|
|
||||||
//add this data point to list
|
list.add(new AggregateData(timestampStart, ""+ (data/1000.0), username)); //add this data point to list
|
||||||
list.add(new AggregateData(timestampStart, ""+ (data/1000.0), username));
|
|
||||||
|
|
||||||
//update previous end timestamp
|
//update previous end timestamp
|
||||||
previousTimestampEnd = timestampEnd;
|
previousTimestampEnd = timestampEnd;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@
|
||||||
<H1>All History (kWh/day)</H1>
|
<H1>All History (kWh/day)</H1>
|
||||||
<div id="day-power-chart" style="height:450px;"></div>
|
<div id="day-power-chart" style="height:450px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row placeholders">
|
||||||
|
<H1>All History (kWh/week)</H1>
|
||||||
|
<div id="week-power-chart" style="height:450px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
@ -40,6 +44,13 @@
|
||||||
{ y: Date.now() }
|
{ y: Date.now() }
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
chartData("week-power-chart",
|
||||||
|
[{{#weekData}}
|
||||||
|
{ y: {{.timestamp}}, "{{.username}}": {{.data}} },
|
||||||
|
{{/weekData}}
|
||||||
|
{ y: Date.now() }
|
||||||
|
]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
var userArray = [ {{#username}} "{{.getUsername()}}", {{/username}} ];
|
var userArray = [ {{#username}} "{{.getUsername()}}", {{/username}} ];
|
||||||
function chartData(elementId, data){
|
function chartData(elementId, data){
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue