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 // TEMPERATURE SENSOR
#define TEMPERATURE_ENABLED // comment out to disable 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_PROTOCOL ProtocolOregon(11, DEVICE_BASE_ID + 2)
#define TEMPERATURE_TIMER_MULTIPLIER 10 #define TEMPERATURE_TIMER_MULTIPLIER 10

View file

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

View file

@ -91,39 +91,33 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
PreparedStatement stmt = null; PreparedStatement stmt = null;
try { try {
Long maxAggrTimestampInDB = getLatestAggrTimestamp(db, sensor, aggrPeriodLength);
stmt = db.getPreparedStatement("SELECT MAX(timestamp_end) FROM sensor_data_aggr" if(maxAggrTimestampInDB == null)
+ " WHERE sensor_id == ?" maxAggrTimestampInDB = 0l;
+ " 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 latestCompletePeriodEndTimestamp = new UTCTimePeriod(aggregationStartTime, aggrPeriodLength).getPreviosPeriod().getEndTimestamp(); long latestCompletePeriodEndTimestamp = new UTCTimePeriod(aggregationStartTime, aggrPeriodLength).getPreviosPeriod().getEndTimestamp();
long oldestPeriodStartTimestamp = new UTCTimePeriod(aggregationStartTime-ageLimitInMs, aggrPeriodLength).getStartTimestamp(); long oldestPeriodStartTimestamp = new UTCTimePeriod(aggregationStartTime-ageLimitInMs, aggrPeriodLength).getStartTimestamp();
if(latestCompletePeriodEndTimestamp == maxTimestampFoundForSensor){ // Check if the sensor has stopped responding for 15 min or 3 times the data interval and alert the user
logger.fine("no new data to evaluate - aggregation is up to date"); if (aggrPeriodLength == AggregationPeriodLength.FIVE_MINUTES) {
// Check if the sensor has stopped responding Long maxRawTimestampInDB = getLatestRawTimestamp(db, sensor);
if (maxTimestampFoundForSensor + sensor.getDeviceConfig().getDataInterval()*3 < System.currentTimeMillis()){ 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"); logger.fine("Sensor \"" + sensorId + "\" has stopped sending data");
HalAlertManager.getInstance().addAlert(new HalAlert(AlertLevel.WARNING, HalAlertManager.getInstance().addAlert(new HalAlert(AlertLevel.WARNING,
"Sensor \""+sensor.getName()+"\" has stopped responding", AlertTTL.DISMISSED)); "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; return;
}else{ }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" stmt = db.getPreparedStatement("SELECT *, 1 AS confidence FROM sensor_data_raw"
@ -133,7 +127,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
+ " AND timestamp >= ? " + " AND timestamp >= ? "
+" ORDER BY timestamp ASC"); +" ORDER BY timestamp ASC");
stmt.setLong(1, sensorId); stmt.setLong(1, sensorId);
stmt.setLong(2, maxTimestampFoundForSensor); stmt.setLong(2, maxAggrTimestampInDB);
stmt.setLong(3, latestCompletePeriodEndTimestamp); stmt.setLong(3, latestCompletePeriodEndTimestamp);
stmt.setLong(4, oldestPeriodStartTimestamp); stmt.setLong(4, oldestPeriodStartTimestamp);
DBConnection.exec(stmt, new DataAggregator(sensorId, aggrPeriodLength, expectedSampleCount, aggrMethod, aggregationStartTime)); 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); 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 * Internal class for aggregating data to the aggregated DB table
*/ */

View file

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