Made alerts bold, fixed sensor not responding alert, refactored aggregator a small bit

This commit is contained in:
Ziver Koc 2017-01-21 19:26:15 +01:00
parent 0b41bbc446
commit 33de44b166
4 changed files with 66 additions and 41 deletions

View file

@ -16,7 +16,7 @@
// TEMPERATURE SENSOR
#define TEMPERATURE_ENABLED // comment out to disable sensor
#define TEMPERATURE_SENSOR SensorDHT(DHT11, 10)
#define TEMPERATURE_SENSOR SensorDHT(DHT22, 10)
#define TEMPERATURE_PROTOCOL ProtocolOregon(11, DEVICE_BASE_ID + 2)
#define TEMPERATURE_TIMER_MULTIPLIER 10

View file

@ -5,7 +5,7 @@
<span aria-hidden="true">&times;</span>
</button>
<span class="glyphicon glyphicon-minus-sign" aria-hidden="true"></span>
<strong>Error:</strong> {{.getMessage()}}
<strong>{{.getMessage()}}</strong>
</div>
{{/.isError()}}
{{#.isWarning()}}
@ -14,7 +14,7 @@
<span aria-hidden="true">&times;</span>
</button>
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"></span>
<strong>Warning:</strong> {{.getMessage()}}
<strong>{{.getMessage()}}</strong>
</div>
{{/.isWarning()}}
{{#.isSuccess()}}
@ -23,7 +23,7 @@
<span aria-hidden="true">&times;</span>
</button>
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span>
<strong>Success:</strong> {{.getMessage()}}
<strong>{{.getMessage()}}</strong>
</div>
{{/.isSuccess()}}
{{#.isInfo()}}
@ -32,7 +32,7 @@
<span aria-hidden="true">&times;</span>
</button>
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
<strong>Info:</strong> {{.getMessage()}}
<strong>{{.getMessage()}}</strong>
</div>
{{/.isInfo()}}
{{/alerts}}

View file

@ -91,39 +91,33 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
DBConnection db = HalContext.getDB();
PreparedStatement stmt = null;
try {
stmt = db.getPreparedStatement("SELECT MAX(timestamp_end) FROM sensor_data_aggr"
+ " WHERE sensor_id == ?"
+ " AND timestamp_end-timestamp_start == ?");
stmt.setLong(1, sensorId);
switch(aggrPeriodLength){
case SECOND: stmt.setLong(2, UTCTimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(2, UTCTimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(2, UTCTimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(2, UTCTimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(2, UTCTimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(2, UTCTimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(2, UTCTimeUtility.WEEK_IN_MS-1); break;
default: logger.warning("aggregation period length is not supported."); return;
}
Long maxTimestampFoundForSensor = DBConnection.exec(stmt, new SimpleSQLResult<Long>());
if(maxTimestampFoundForSensor == null)
maxTimestampFoundForSensor = 0l;
Long maxAggrTimestampInDB = getLatestAggrTimestamp(db, sensor, aggrPeriodLength);
if(maxAggrTimestampInDB == null)
maxAggrTimestampInDB = 0l;
long latestCompletePeriodEndTimestamp = new UTCTimePeriod(aggregationStartTime, aggrPeriodLength).getPreviosPeriod().getEndTimestamp();
long oldestPeriodStartTimestamp = new UTCTimePeriod(aggregationStartTime-ageLimitInMs, aggrPeriodLength).getStartTimestamp();
if(latestCompletePeriodEndTimestamp == maxTimestampFoundForSensor){
logger.fine("no new data to evaluate - aggregation is up to date");
// Check if the sensor has stopped responding
if (maxTimestampFoundForSensor + sensor.getDeviceConfig().getDataInterval()*3 < System.currentTimeMillis()){
// Check if the sensor has stopped responding for 15 min or 3 times the data interval and alert the user
if (aggrPeriodLength == AggregationPeriodLength.FIVE_MINUTES) {
Long maxRawTimestampInDB = getLatestRawTimestamp(db, sensor);
long dataInterval = sensor.getDeviceConfig().getDataInterval();
if (dataInterval < UTCTimeUtility.FIVE_MINUTES_IN_MS)
dataInterval = UTCTimeUtility.FIVE_MINUTES_IN_MS;
if (maxRawTimestampInDB != null &&
maxRawTimestampInDB + (dataInterval * 3) < System.currentTimeMillis()) {
logger.fine("Sensor \"" + sensorId + "\" has stopped sending data");
HalAlertManager.getInstance().addAlert(new HalAlert(AlertLevel.WARNING,
"Sensor \""+sensor.getName()+"\" has stopped responding", AlertTTL.DISMISSED));
}
HalAlertManager.getInstance().addAlert(new HalAlert(AlertLevel.WARNING,
"Sensor \"" + sensor.getName() + "\" has stopped responding " +
"since <span class=\"timestamp\">"+maxRawTimestampInDB+"</span>", AlertTTL.DISMISSED));
}
}
if(latestCompletePeriodEndTimestamp == maxAggrTimestampInDB){
logger.fine("no new data to evaluate - aggregation is up to date");
return;
}else{
logger.fine("evaluating period: "+ (maxTimestampFoundForSensor+1) + "=>" + latestCompletePeriodEndTimestamp + " (" + UTCTimeUtility.getDateString(maxTimestampFoundForSensor+1) + "=>" + UTCTimeUtility.getDateString(latestCompletePeriodEndTimestamp) + ") with expected sample count: " + expectedSampleCount);
logger.fine("evaluating period: "+ (maxAggrTimestampInDB+1) + "=>" + latestCompletePeriodEndTimestamp + " (" + UTCTimeUtility.getDateString(maxAggrTimestampInDB+1) + "=>" + UTCTimeUtility.getDateString(latestCompletePeriodEndTimestamp) + ") with expected sample count: " + expectedSampleCount);
}
stmt = db.getPreparedStatement("SELECT *, 1 AS confidence FROM sensor_data_raw"
@ -133,7 +127,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
+ " AND timestamp >= ? "
+" ORDER BY timestamp ASC");
stmt.setLong(1, sensorId);
stmt.setLong(2, maxTimestampFoundForSensor);
stmt.setLong(2, maxAggrTimestampInDB);
stmt.setLong(3, latestCompletePeriodEndTimestamp);
stmt.setLong(4, oldestPeriodStartTimestamp);
DBConnection.exec(stmt, new DataAggregator(sensorId, aggrPeriodLength, expectedSampleCount, aggrMethod, aggregationStartTime));
@ -141,7 +135,32 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
logger.log(Level.SEVERE, null, e);
}
}
private Long getLatestAggrTimestamp(DBConnection db, Sensor sensor, AggregationPeriodLength aggrPeriodLength) throws SQLException {
PreparedStatement stmt = db.getPreparedStatement("SELECT MAX(timestamp_end) FROM sensor_data_aggr"
+ " WHERE sensor_id == ?"
+ " AND timestamp_end-timestamp_start == ?");
stmt.setLong(1, sensor.getId());
switch(aggrPeriodLength){
case SECOND: stmt.setLong(2, UTCTimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(2, UTCTimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(2, UTCTimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(2, UTCTimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(2, UTCTimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(2, UTCTimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(2, UTCTimeUtility.WEEK_IN_MS-1); break;
default:
throw new IllegalArgumentException("aggregation period length is not supported.");
}
return DBConnection.exec(stmt, new SimpleSQLResult<Long>());
}
private Long getLatestRawTimestamp(DBConnection db, Sensor sensor) throws SQLException {
PreparedStatement stmt = db.getPreparedStatement("SELECT MAX(timestamp) FROM sensor_data_raw WHERE sensor_id == ?");
stmt.setLong(1, sensor.getId());
return DBConnection.exec(stmt, new SimpleSQLResult<Long>());
}
/**
* Internal class for aggregating data to the aggregated DB table
*/

View file

@ -46,6 +46,7 @@ public class HalAlertManager implements HttpPage {
alerts.add(alert);
}
public Templator generateAlerts(){
try {
// clone alert list and update ttl of alerts
@ -110,23 +111,19 @@ public class HalAlertManager implements HttpPage {
private int id;
private AlertLevel level;
private String msg;
protected int ttl;
private int ttl;
public HalAlert(AlertLevel level, String msg, AlertTTL ttl) {
this.id = nextId++;
this.level = level;
this.msg = msg;
switch (ttl){
case ONE_VIEW: this.ttl = 1; break;
case DISMISSED: this.ttl = Integer.MAX_VALUE; break;
}
setTTL(ttl);
}
public int getId() {
return id;
}
public AlertLevel getLevel() {
return level;
}
@ -134,11 +131,20 @@ public class HalAlertManager implements HttpPage {
public boolean isWarning(){ return level == AlertLevel.WARNING; }
public boolean isSuccess(){ return level == AlertLevel.SUCCESS; }
public boolean isInfo(){ return level == AlertLevel.INFO; }
public String getMessage() {
return msg;
}
public void setTTL(AlertTTL ttl){
switch (ttl){
case ONE_VIEW: this.ttl = 1; break;
case DISMISSED: this.ttl = Integer.MAX_VALUE; break;
}
}
public void dissmiss(){
ttl = -1;
}
@Override
public boolean equals(Object obj){
if (obj instanceof HalAlert)