Added Sensor overview page. issue 7
Former-commit-id: 60dec1d1a95f568404371ecd3c2cc38bc8a4a355
This commit is contained in:
parent
e269faec13
commit
113bbdbfb8
7 changed files with 181 additions and 30 deletions
|
|
@ -79,6 +79,7 @@ public class HalServer {
|
||||||
HalHttpPage.getRootNav().addSubNav(new HalNavigation("sensors", "Sensors"));
|
HalHttpPage.getRootNav().addSubNav(new HalNavigation("sensors", "Sensors"));
|
||||||
HalHttpPage.getRootNav().addSubNav(new HalNavigation("events", "Events"));
|
HalHttpPage.getRootNav().addSubNav(new HalNavigation("events", "Events"));
|
||||||
pages = new HalHttpPage[]{
|
pages = new HalHttpPage[]{
|
||||||
|
new SensorOverviewHttpPage(),
|
||||||
new PCOverviewHttpPage(),
|
new PCOverviewHttpPage(),
|
||||||
new PCHeatMapHttpPage(),
|
new PCHeatMapHttpPage(),
|
||||||
new SensorConfigHttpPage(),
|
new SensorConfigHttpPage(),
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,16 @@ package se.hal.page;
|
||||||
|
|
||||||
import se.hal.ControllerManager;
|
import se.hal.ControllerManager;
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalEventData;
|
|
||||||
import se.hal.intf.HalHttpPage;
|
import se.hal.intf.HalHttpPage;
|
||||||
import se.hal.struct.Event;
|
import se.hal.struct.Event;
|
||||||
import se.hal.struct.SwitchEventData;
|
import se.hal.struct.SwitchEventData;
|
||||||
import se.hal.struct.User;
|
import se.hal.util.HistoryDataListSqlResult;
|
||||||
|
import se.hal.util.HistoryDataListSqlResult.*;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.db.SQLResultHandler;
|
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.parser.Templator;
|
import zutil.parser.Templator;
|
||||||
import zutil.ui.Configurator;
|
|
||||||
import zutil.ui.Configurator.ConfigurationParam;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -74,25 +67,4 @@ public class EventOverviewHttpPage extends HalHttpPage {
|
||||||
return tmpl;
|
return tmpl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected static class HistoryData{
|
|
||||||
public long timestamp;
|
|
||||||
public double data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class HistoryDataListSqlResult implements SQLResultHandler<List<HistoryData>> {
|
|
||||||
@Override
|
|
||||||
public List<HistoryData> handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
|
|
||||||
ArrayList<HistoryData> list = new ArrayList<HistoryData>();
|
|
||||||
while(result.next()){
|
|
||||||
HistoryData data = new HistoryData();
|
|
||||||
data.timestamp = result.getLong("timestamp");
|
|
||||||
data.data = result.getLong("data");
|
|
||||||
list.add(data);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
src/se/hal/page/SensorOverviewHttpPage.java
Executable file
62
src/se/hal/page/SensorOverviewHttpPage.java
Executable file
|
|
@ -0,0 +1,62 @@
|
||||||
|
package se.hal.page;
|
||||||
|
|
||||||
|
import se.hal.ControllerManager;
|
||||||
|
import se.hal.HalContext;
|
||||||
|
import se.hal.intf.HalHttpPage;
|
||||||
|
import se.hal.struct.Event;
|
||||||
|
import se.hal.struct.Sensor;
|
||||||
|
import se.hal.struct.SwitchEventData;
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import se.hal.util.HistoryDataListSqlResult;
|
||||||
|
import se.hal.util.HistoryDataListSqlResult.*;
|
||||||
|
import zutil.io.file.FileUtil;
|
||||||
|
import zutil.parser.Templator;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SensorOverviewHttpPage extends HalHttpPage {
|
||||||
|
private static final int HISTORY_LIMIT = 1000;
|
||||||
|
private static final String OVERVIEW_TEMPLATE = "web-resource/sensor_overview.tmpl";
|
||||||
|
private static final String DETAIL_TEMPLATE = "web-resource/sensor_detail.tmpl";
|
||||||
|
|
||||||
|
|
||||||
|
public SensorOverviewHttpPage(){
|
||||||
|
super("Overview", "sensor_overview");
|
||||||
|
super.getRootNav().getSubNav("sensors").addSubNav(super.getNav());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Templator httpRespond(
|
||||||
|
Map<String, Object> session,
|
||||||
|
Map<String, String> cookie,
|
||||||
|
Map<String, String> request)
|
||||||
|
throws Exception{
|
||||||
|
|
||||||
|
DBConnection db = HalContext.getDB();
|
||||||
|
int id = (request.containsKey("id") ? Integer.parseInt(request.get("id")) : -1);
|
||||||
|
|
||||||
|
// Save new input
|
||||||
|
if(id >= 0){
|
||||||
|
Sensor sensor = Sensor.getSensor(db, id);
|
||||||
|
|
||||||
|
// get history data
|
||||||
|
PreparedStatement stmt = db.getPreparedStatement("SELECT * FROM sensor_data_raw WHERE sensor_id == ? LIMIT ?");
|
||||||
|
stmt.setLong(1, sensor.getId());
|
||||||
|
stmt.setLong(2, HISTORY_LIMIT);
|
||||||
|
List<HistoryData> history = DBConnection.exec(stmt, new HistoryDataListSqlResult());
|
||||||
|
|
||||||
|
Templator tmpl = new Templator(FileUtil.find(DETAIL_TEMPLATE));
|
||||||
|
tmpl.set("sensor", sensor);
|
||||||
|
tmpl.set("history", history);
|
||||||
|
return tmpl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Templator tmpl = new Templator(FileUtil.find(OVERVIEW_TEMPLATE));
|
||||||
|
tmpl.set("sensors", Sensor.getLocalSensors(db));
|
||||||
|
return tmpl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/se/hal/util/HistoryDataListSqlResult.java
Executable file
28
src/se/hal/util/HistoryDataListSqlResult.java
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
package se.hal.util;
|
||||||
|
|
||||||
|
import zutil.db.SQLResultHandler;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HistoryDataListSqlResult implements SQLResultHandler<List<HistoryDataListSqlResult.HistoryData>> {
|
||||||
|
public static class HistoryData{
|
||||||
|
public long timestamp;
|
||||||
|
public double data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HistoryData> handleQueryResult(Statement stmt, ResultSet result) throws SQLException {
|
||||||
|
ArrayList<HistoryData> list = new ArrayList<HistoryData>();
|
||||||
|
while(result.next()){
|
||||||
|
HistoryData data = new HistoryData();
|
||||||
|
data.timestamp = result.getLong("timestamp");
|
||||||
|
data.data = result.getLong("data");
|
||||||
|
list.add(data);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
<th class="text-right">Type:</th>
|
<th class="text-right">Type:</th>
|
||||||
<td>{{event.getDeviceData().getClass().getSimpleName()}}</td>
|
<td>{{event.getDeviceData().getClass().getSimpleName()}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="text-right">Owner:</th>
|
||||||
|
<td>{{event.getUser().getUsername()}}</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
50
web-resource/sensor_detail.tmpl
Executable file
50
web-resource/sensor_detail.tmpl
Executable file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<h1 class="page-header">Details for <a href="#">{{sensor.getName()}}</a></h1>
|
||||||
|
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="panel panel-default drop-shadow">
|
||||||
|
<div class="panel-heading">Configuration</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-hover table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-right">Name:</th>
|
||||||
|
<td>{{sensor.getName()}}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-right">Type:</th>
|
||||||
|
<td>{{sensor.getDeviceData().getClass().getSimpleName()}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="text-right">Public:</th>
|
||||||
|
<td>{{sensor.isSynced()}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="text-right">Owner:</th>
|
||||||
|
<td>{{sensor.getUser().getUsername()}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="panel panel-default drop-shadow">
|
||||||
|
<div class="panel-heading">History data</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
<table class="table table-hover table-condensed">
|
||||||
|
<thead>
|
||||||
|
<th class="col-md-6">Timestamp</th>
|
||||||
|
<th class="col-md-2">Data</th>
|
||||||
|
</thead>
|
||||||
|
{{#history}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.timestamp}}</a></td>
|
||||||
|
<td>{{.data}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/history}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
34
web-resource/sensor_overview.tmpl
Executable file
34
web-resource/sensor_overview.tmpl
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<h1 class="page-header">Sensor Overview</h1>
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-default drop-shadow">
|
||||||
|
<div class="panel-heading">Local Sensors</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
<table class="table table-hover table-condensed">
|
||||||
|
<thead>
|
||||||
|
<th class="col-md-4">Name</th>
|
||||||
|
<th class="col-md-3">Type</th>
|
||||||
|
<th class="col-md-2">Data</th>
|
||||||
|
<th class="col-md-2">Last Update</th>
|
||||||
|
</thead>
|
||||||
|
{{#sensors}}
|
||||||
|
<tr>
|
||||||
|
<td><a href="?id={{.getId()}}">{{.getName()}}</a></td>
|
||||||
|
<td>{{.getDeviceData().getClass().getSimpleName()}}</td>
|
||||||
|
<td>{{.getDeviceData().getData()}}</td>
|
||||||
|
<td>1 min ago</td>
|
||||||
|
</tr>
|
||||||
|
{{/sensors}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function (){
|
||||||
|
$(".toggle-switch").on("switchChange.bootstrapSwitch", function (event, state) {
|
||||||
|
$(this).closest('form').submit();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue