Added synchronizer daemon

Former-commit-id: ee3100d97cad83de5498f38467ac61a922398cb6
This commit is contained in:
dcollin 2015-12-04 07:36:07 +01:00
parent 6c5a5585c2
commit c27620d63d
7 changed files with 32 additions and 29 deletions

BIN
hal.db

Binary file not shown.

View file

@ -2,6 +2,7 @@ package se.koc.hal;
import se.koc.hal.deamon.DataAggregatorDaemon; import se.koc.hal.deamon.DataAggregatorDaemon;
import se.koc.hal.deamon.DataSynchronizationDaemon;
import se.koc.hal.deamon.HalDaemon; import se.koc.hal.deamon.HalDaemon;
import se.koc.hal.page.PCConfigureHttpPage; import se.koc.hal.page.PCConfigureHttpPage;
import se.koc.hal.page.PCHeatMapHttpPage; import se.koc.hal.page.PCHeatMapHttpPage;
@ -20,21 +21,20 @@ import java.util.logging.Level;
* Created by Ziver on 2015-12-03. * Created by Ziver on 2015-12-03.
*/ */
public class PowerChallenge { public class PowerChallenge {
public static DBConnection db;
private static HalDaemon[] daemons = new HalDaemon[]{ private static HalDaemon[] daemons = new HalDaemon[]{
new DataAggregatorDaemon() new DataAggregatorDaemon(),
new DataSynchronizationDaemon()
}; };
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
HalContext.initialize();
// init logging // init logging
LogUtil.setGlobalLevel(Level.ALL); LogUtil.setGlobalLevel(Level.ALL);
LogUtil.setGlobalFormatter(new CompactLogFormatter()); LogUtil.setGlobalFormatter(new CompactLogFormatter());
// init Database
db = new DBConnection(DBConnection.DBMS.SQLite, "hal.db");
// init daemons // init daemons
Timer daemonTimer = new Timer(); Timer daemonTimer = new Timer();

View file

@ -11,7 +11,7 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.logging.Logger; import java.util.logging.Logger;
import se.koc.hal.PowerChallenge; import se.koc.hal.HalContext;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.SQLResultHandler; import zutil.db.SQLResultHandler;
import zutil.db.handler.SimpleSQLHandler; import zutil.db.handler.SimpleSQLHandler;
@ -31,14 +31,13 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
public void initiate(Timer timer){ public void initiate(Timer timer){
timer.schedule(this, FIVE_MINUTES_IN_MS); timer.schedule(this, 0, FIVE_MINUTES_IN_MS);
run();
} }
@Override @Override
public void run(){ public void run(){
try { try {
List<Integer> sensorIdList = PowerChallenge.db.exec("SELECT id FROM sensor", new SQLResultHandler<List<Integer>>(){ List<Integer> sensorIdList = HalContext.db.exec("SELECT id FROM sensor", new SQLResultHandler<List<Integer>>(){
@Override @Override
public List<Integer> handleQueryResult(Statement stmt, ResultSet result) throws SQLException { public List<Integer> handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
ArrayList<Integer> list = new ArrayList<>(); ArrayList<Integer> list = new ArrayList<>();
@ -58,7 +57,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
} }
public void aggregateSensor(int sensorId) { public void aggregateSensor(int sensorId) {
DBConnection db = PowerChallenge.db; DBConnection db = HalContext.db;
try { try {
Long maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE sensor_id == "+sensorId, new SimpleSQLHandler<Long>()); Long maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE sensor_id == "+sensorId, new SimpleSQLHandler<Long>());
if(maxDBTimestamp == null) if(maxDBTimestamp == null)
@ -122,7 +121,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
} }
public static Integer getNextSequenceId(long sensorId) throws SQLException{ public static Integer getNextSequenceId(long sensorId) throws SQLException{
Integer id = PowerChallenge.db.exec("SELECT MAX(sequence_id) FROM sensor_data_aggr WHERE sensor_id == "+ sensorId, new SimpleSQLHandler<Integer>()); Integer id = HalContext.db.exec("SELECT MAX(sequence_id) FROM sensor_data_aggr WHERE sensor_id == "+ sensorId, new SimpleSQLHandler<Integer>());
return (id != null ? id+1 : 1); return (id != null ? id+1 : 1);
} }
@ -138,7 +137,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){ if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){
float confidence = Math.min(count / 5f, 1.0f); float confidence = Math.min(count / 5f, 1.0f);
logger.finer("Calculated minute period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ confidence); logger.finer("Calculated minute period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ confidence);
PowerChallenge.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)", HalContext.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)",
result.getInt("sensor_id"), result.getInt("sensor_id"),
getNextSequenceId(result.getInt("sensor_id")), getNextSequenceId(result.getInt("sensor_id")),
currentPeriodTimestamp, currentPeriodTimestamp,
@ -170,7 +169,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){ if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){
float aggrConfidence = confidenceSum / 12f; float aggrConfidence = confidenceSum / 12f;
logger.finer("Calculated hour period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ aggrConfidence); logger.finer("Calculated hour period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ aggrConfidence);
PowerChallenge.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)", HalContext.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)",
result.getInt("sensor_id"), result.getInt("sensor_id"),
getNextSequenceId(result.getInt("sensor_id")), getNextSequenceId(result.getInt("sensor_id")),
currentPeriodTimestamp, currentPeriodTimestamp,
@ -187,7 +186,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
confidenceSum += result.getFloat("confidence"); confidenceSum += result.getFloat("confidence");
//TODO: SHould not be here! //TODO: SHould not be here!
PowerChallenge.db.exec("DELETE FROM sensor_data_aggr " HalContext.db.exec("DELETE FROM sensor_data_aggr "
+ "WHERE sensor_id == "+ result.getInt("sensor_id") +" AND sequence_id == "+ result.getInt("sequence_id")); + "WHERE sensor_id == "+ result.getInt("sensor_id") +" AND sequence_id == "+ result.getInt("sequence_id"));
} }
return null; return null;
@ -207,7 +206,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){ if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){
float aggrConfidence = confidenceSum / 24f; float aggrConfidence = confidenceSum / 24f;
logger.finer("Calculated day period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ aggrConfidence+ " samples: " + samples); logger.finer("Calculated day period: "+ currentPeriodTimestamp +" sum: "+ sum +" confidence: "+ aggrConfidence+ " samples: " + samples);
PowerChallenge.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)", HalContext.db.exec(String.format(Locale.US, "INSERT INTO sensor_data_aggr(sensor_id, sequence_id, timestamp_start, timestamp_end, data, confidence) VALUES(%d, %d, %d, %d, %d, %f)",
result.getInt("sensor_id"), result.getInt("sensor_id"),
getNextSequenceId(result.getInt("sensor_id")), getNextSequenceId(result.getInt("sensor_id")),
currentPeriodTimestamp, currentPeriodTimestamp,
@ -226,7 +225,7 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon {
samples++; samples++;
//TODO: SHould not be here! //TODO: SHould not be here!
PowerChallenge.db.exec("DELETE FROM sensor_data_aggr " HalContext.db.exec("DELETE FROM sensor_data_aggr "
+ "WHERE sensor_id == "+ result.getInt("sensor_id") +" AND sequence_id == "+ result.getInt("sequence_id")); + "WHERE sensor_id == "+ result.getInt("sensor_id") +" AND sequence_id == "+ result.getInt("sequence_id"));
} }
return null; return null;

View file

@ -4,7 +4,7 @@ import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map; import java.util.Map;
import se.koc.hal.PowerChallenge; import se.koc.hal.HalContext;
import se.koc.hal.struct.Sensor; import se.koc.hal.struct.Sensor;
import se.koc.hal.struct.User; import se.koc.hal.struct.User;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -22,7 +22,7 @@ public class PCConfigureHttpPage implements HttpPage {
Map<String, String> request) throws IOException { Map<String, String> request) throws IOException {
try { try {
DBConnection db = PowerChallenge.db; DBConnection db = HalContext.db;
Templator tmpl = new Templator(FileUtil.find("web-resource/configure.html")); Templator tmpl = new Templator(FileUtil.find("web-resource/configure.html"));
tmpl.set("user", User.getLocalUser(db)); tmpl.set("user", User.getLocalUser(db));

View file

@ -7,7 +7,7 @@ import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import se.koc.hal.PowerChallenge; import se.koc.hal.HalContext;
import se.koc.hal.deamon.DataAggregatorDaemon; import se.koc.hal.deamon.DataAggregatorDaemon;
import zutil.db.SQLResultHandler; import zutil.db.SQLResultHandler;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@ -22,21 +22,21 @@ public class PCOverviewHttpPage implements HttpPage {
public void respond(HttpPrintStream out, HttpHeaderParser client_info, Map<String, Object> session, Map<String, String> cookie, Map<String, String> request) throws IOException { public void respond(HttpPrintStream out, HttpHeaderParser client_info, Map<String, Object> session, Map<String, String> cookie, Map<String, String> request) throws IOException {
try { try {
ArrayList<PowerData> minDataList = PowerChallenge.db.exec( ArrayList<PowerData> minDataList = HalContext.db.exec(
"SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data "
+ "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 user.id = sensor.user_id " + "AND user.id = sensor.user_id "
+ "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.FIVE_MINUTES_IN_MS-1), + "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.FIVE_MINUTES_IN_MS-1),
new SQLPowerDataBuilder()); new SQLPowerDataBuilder());
ArrayList<PowerData> hourDataList = PowerChallenge.db.exec( ArrayList<PowerData> hourDataList = HalContext.db.exec(
"SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data "
+ "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 user.id = sensor.user_id " + "AND user.id = sensor.user_id "
+ "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.HOUR_IN_MS-1), + "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.HOUR_IN_MS-1),
new SQLPowerDataBuilder()); new SQLPowerDataBuilder());
ArrayList<PowerData> dayDataList = PowerChallenge.db.exec( ArrayList<PowerData> dayDataList = HalContext.db.exec(
"SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data "
+ "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 "

View file

@ -12,7 +12,7 @@
<link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet"> <link href="css/main.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="js/jquery-1.11.3.min.js"></script>
<script src="js/bootstrap.min.js"></script> <script src="js/bootstrap.min.js"></script>
</head> </head>
@ -49,6 +49,7 @@
<div class="panel-heading">Profile Information</div> <div class="panel-heading">Profile Information</div>
<div class="panel-body"> <div class="panel-body">
<form> <form>
<hidden id="id" value="{{user.getId()}}">
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="username">Username</label> <label for="username">Username</label>
<input type="text" class="form-control" id="username" value="{{user.username}}"> <input type="text" class="form-control" id="username" value="{{user.username}}">

View file

@ -13,16 +13,19 @@
<link href="css/main.css" rel="stylesheet"> <link href="css/main.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="js/jquery-1.11.3.min.js"></script>
<script src="js/bootstrap.min.js"></script> <script src="js/bootstrap.min.js"></script>
<script src="js/morris.min.js"></script> <script src="js/morris.min.js"></script>
<script> <script>
$(function(){ $(function(){
chartData("min-power-chart", chartData("min-power-chart",
[{{#minData}} [
{ y: {{.timestamp}}, {{.username}}: {{.data}}/1000 }, {{#minData}}
{{/minData}}] { y: {{.timestamp}}, {{.username}}: {{.data}}/1000 },
{{/minData}}
{ y: Date.now() },
]
); );
chartData("hour-power-chart", chartData("hour-power-chart",
[{{#hourData}} [{{#hourData}}
@ -31,7 +34,7 @@
); );
chartData("day-power-chart", chartData("day-power-chart",
[{{#dayData}} [{{#dayData}}
{ y: {{.timestamp}}, {{.username}}: {{.data}}/1000 }, { y: {{.timestamp}}, {{.username}}: {{.data}}/1000 },
{{/dayData}}] {{/dayData}}]
); );
}); });