diff --git a/src/se/koc/hal/PCConfigureHttpPage.java b/src/se/koc/hal/PCConfigureHttpPage.java new file mode 100644 index 00000000..27ef1eab --- /dev/null +++ b/src/se/koc/hal/PCConfigureHttpPage.java @@ -0,0 +1,26 @@ +package se.koc.hal; + +import java.io.IOException; +import java.util.Map; + +import zutil.io.file.FileUtil; +import zutil.net.http.HttpHeaderParser; +import zutil.net.http.HttpPage; +import zutil.net.http.HttpPrintStream; +import zutil.parser.Templator; + +public class PCConfigureHttpPage implements HttpPage { + + @Override + public void respond(HttpPrintStream out, HttpHeaderParser client_info, + Map session, Map cookie, + Map request) throws IOException { + + Templator tmpl = new Templator(FileUtil.find("web-resource/configure.html")); + + out.print(tmpl.compile()); + + + } + +} diff --git a/src/se/koc/hal/PowerChallengeHttpPage.java b/src/se/koc/hal/PCOverviewHttpPage.java similarity index 53% rename from src/se/koc/hal/PowerChallengeHttpPage.java rename to src/se/koc/hal/PCOverviewHttpPage.java index e3cebea0..c1d8e342 100644 --- a/src/se/koc/hal/PowerChallengeHttpPage.java +++ b/src/se/koc/hal/PCOverviewHttpPage.java @@ -15,23 +15,32 @@ import zutil.net.http.HttpPage; import zutil.net.http.HttpPrintStream; import zutil.parser.Templator; -public class PowerChallengeHttpPage implements HttpPage { +public class PCOverviewHttpPage implements HttpPage { @Override public void respond(HttpPrintStream out, HttpHeaderParser client_info, Map session, Map cookie, Map request) throws IOException { try { ArrayList minDataList = PowerChallenge.db.exec( - "SELECT * FROM sensor_data_aggr " - + "WHERE sensor_id == 1 AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.FIVE_MINUTES_IN_MS-1), + "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " + + "FROM sensor_data_aggr, user, sensor " + + "WHERE sensor.id = sensor_data_aggr.sensor_id " + + "AND user.id = sensor.user_id " + + "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.FIVE_MINUTES_IN_MS-1), new SQLPowerDataBuilder()); ArrayList hourDataList = PowerChallenge.db.exec( - "SELECT * FROM sensor_data_aggr " - + "WHERE sensor_id == 1 AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.HOUR_IN_MS-1), + "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " + + "FROM sensor_data_aggr, user, sensor " + + "WHERE sensor.id = sensor_data_aggr.sensor_id " + + "AND user.id = sensor.user_id " + + "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.HOUR_IN_MS-1), new SQLPowerDataBuilder()); ArrayList dayDataList = PowerChallenge.db.exec( - "SELECT * FROM sensor_data_aggr " - + "WHERE sensor_id == 1 AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.DAY_IN_MS-1), + "SELECT user.username as username, sensor_data_aggr.timestamp_start as timestamp, sensor_data_aggr.data as data " + + "FROM sensor_data_aggr, user, sensor " + + "WHERE sensor.id = sensor_data_aggr.sensor_id " + + "AND user.id = sensor.user_id " + + "AND timestamp_end-timestamp_start == " + (DataAggregatorDaemon.DAY_IN_MS-1), new SQLPowerDataBuilder()); @@ -39,7 +48,7 @@ public class PowerChallengeHttpPage implements HttpPage { tmpl.set("minData", minDataList); tmpl.set("hourData", hourDataList); tmpl.set("dayData", dayDataList); - tmpl.set("username", "Ziver"); + tmpl.set("username", new String[]{"Ziver", "Daniel"}); out.print(tmpl.compile()); @@ -51,9 +60,11 @@ public class PowerChallengeHttpPage implements HttpPage { public static class PowerData{ long timestamp; int data; - public PowerData(long time, int data) { + String username; + public PowerData(long time, int data, String uname) { this.timestamp = time; this.data = data; + this.username = uname; } } @@ -62,7 +73,7 @@ public class PowerChallengeHttpPage implements HttpPage { public ArrayList handleQueryResult(Statement stmt, ResultSet result) throws SQLException { ArrayList list = new ArrayList<>(); while(result.next()){ - list.add(new PowerData(result.getLong("timestamp_start"), result.getInt("data"))); + list.add(new PowerData(result.getLong("timestamp"), result.getInt("data"), result.getString("username"))); } return list; } diff --git a/src/se/koc/hal/PowerChallenge.java b/src/se/koc/hal/PowerChallenge.java index 09ce8f01..735e9910 100755 --- a/src/se/koc/hal/PowerChallenge.java +++ b/src/se/koc/hal/PowerChallenge.java @@ -41,7 +41,8 @@ public class PowerChallenge { HttpServer http = new HttpServer(8080); http.setDefaultPage(new HttpFilePage(FileUtil.find("web-resource/"))); - http.setPage("/", new PowerChallengeHttpPage()); + http.setPage("/", new PCOverviewHttpPage()); + http.setPage("/configure", new PCConfigureHttpPage()); http.start(); } } diff --git a/src/se/koc/hal/deamon/DataAggregatorDaemon.java b/src/se/koc/hal/deamon/DataAggregatorDaemon.java index 82719811..483a4400 100755 --- a/src/se/koc/hal/deamon/DataAggregatorDaemon.java +++ b/src/se/koc/hal/deamon/DataAggregatorDaemon.java @@ -3,7 +3,9 @@ package se.koc.hal.deamon; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; import java.util.Calendar; +import java.util.List; import java.util.Locale; import java.util.Timer; import java.util.TimerTask; @@ -33,41 +35,61 @@ public class DataAggregatorDaemon extends TimerTask implements HalDaemon { run(); } - @Override - public void run() { + public void run(){ + try { + List sensorIdList = PowerChallenge.db.exec("SELECT id FROM sensor", new SQLResultHandler>(){ + @Override + public List handleQueryResult(Statement stmt, ResultSet result) throws SQLException { + ArrayList list = new ArrayList<>(); + while(result.next()){ + list.add(result.getInt("id")); + } + return list; + } + }); + for(int id : sensorIdList){ + logger.fine("Aggregating sensor_id: " + id); + aggregateSensor(id); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void aggregateSensor(int sensorId) { DBConnection db = PowerChallenge.db; try { - Long maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr", new SimpleSQLHandler()); + Long maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE sensor_id == "+sensorId, new SimpleSQLHandler()); if(maxDBTimestamp == null) maxDBTimestamp = 0l; // 5 minute aggregation long minPeriodTimestamp = getTimestampMinutePeriodStart(5, System.currentTimeMillis()); logger.fine("Calculating 5 min periods... (from:"+ maxDBTimestamp +", to:"+ minPeriodTimestamp +")"); db.exec("SELECT * FROM sensor_data_raw " - + "WHERE timestamp > " + maxDBTimestamp + " AND timestamp < " + minPeriodTimestamp + + "WHERE sensor_id == "+sensorId+" AND timestamp > " + maxDBTimestamp + " AND timestamp < " + minPeriodTimestamp + " ORDER BY timestamp ASC", new FiveMinuteAggregator()); // hour aggregation - maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE timestamp_end-timestamp_start == " + (HOUR_IN_MS-1), new SimpleSQLHandler()); + maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE sensor_id == "+sensorId+" AND timestamp_end-timestamp_start == " + (HOUR_IN_MS-1), new SimpleSQLHandler()); if(maxDBTimestamp == null) maxDBTimestamp = 0l; long hourPeriodTimestamp = getTimestampMinutePeriodStart(60, System.currentTimeMillis()-HOUR_AGGREGATION_OFFSET); logger.fine("Calculating hour periods... (from:"+ maxDBTimestamp +", to:"+ hourPeriodTimestamp +")"); db.exec("SELECT * FROM sensor_data_aggr " - + "WHERE " + maxDBTimestamp + " < timestamp_start AND timestamp_start < " + hourPeriodTimestamp + " AND timestamp_end-timestamp_start == " + (FIVE_MINUTES_IN_MS-1) + + "WHERE sensor_id == "+sensorId+" AND " + maxDBTimestamp + " < timestamp_start AND timestamp_start < " + hourPeriodTimestamp + " AND timestamp_end-timestamp_start == " + (FIVE_MINUTES_IN_MS-1) +" ORDER BY timestamp_start ASC", new HourAggregator()); // day aggregation - maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE timestamp_end-timestamp_start == " + (DAY_IN_MS-1), new SimpleSQLHandler()); + maxDBTimestamp = db.exec("SELECT MAX(timestamp_end) FROM sensor_data_aggr WHERE sensor_id == "+sensorId+" AND timestamp_end-timestamp_start == " + (DAY_IN_MS-1), new SimpleSQLHandler()); if(maxDBTimestamp == null) maxDBTimestamp = 0l; long dayPeriodTimestamp = getTimestampHourPeriodStart(24, System.currentTimeMillis()-DAY_AGGREGATION_OFFSET); logger.fine("Calculating day periods... (from:"+ maxDBTimestamp +", to:"+ dayPeriodTimestamp +")"); db.exec("SELECT * FROM sensor_data_aggr " - + "WHERE " + maxDBTimestamp + " < timestamp_start AND timestamp_start < " + dayPeriodTimestamp + " AND timestamp_end-timestamp_start == " + (HOUR_IN_MS-1) + + "WHERE sensor_id == "+sensorId+" AND " + maxDBTimestamp + " < timestamp_start AND timestamp_start < " + dayPeriodTimestamp + " AND timestamp_end-timestamp_start == " + (HOUR_IN_MS-1) +" ORDER BY timestamp_start ASC", new DayAggregator()); diff --git a/web-resource/configure.html b/web-resource/configure.html new file mode 100644 index 00000000..3e33fd40 --- /dev/null +++ b/web-resource/configure.html @@ -0,0 +1,54 @@ + + + + + + + + + Power;Challenge + + + + + + + + + + + + + + +
+
+ +
+

Configuration

+ + + +
+
+
+ + diff --git a/web-resource/css/main.css b/web-resource/css/main.css index 2eaf38e3..38d4177f 100644 --- a/web-resource/css/main.css +++ b/web-resource/css/main.css @@ -90,7 +90,7 @@ body { */ .placeholders { - margin-bottom: 30px; + margin-bottom: 200px; text-align: center; } .placeholders h4 { diff --git a/web-resource/index.html b/web-resource/index.html index e50edad8..16d4882a 100644 --- a/web-resource/index.html +++ b/web-resource/index.html @@ -6,7 +6,7 @@ - Dashboard Template for Bootstrap + Power;Challenge @@ -19,55 +19,36 @@ @@ -91,53 +72,28 @@
-

Dashboard

+

Overview

-

Last 24 hours

-
+

Last 24 hours

+
-
-

Previous two days

-
+

Previous two days

+
-
-

Long term

-
-
- -

Section title

-
- - - - - - - - - - - - - - - - - - - -
#HeaderHeaderHeaderHeader
1,001Loremipsumdolorsit
+

Long term

+
+