Made alerts bold, fixed sensor not responding alert, refactored aggregator a small bit
This commit is contained in:
parent
0b41bbc446
commit
33de44b166
4 changed files with 66 additions and 41 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<span aria-hidden="true">×</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">×</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">×</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">×</span>
|
||||
</button>
|
||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
||||
<strong>Info:</strong> {{.getMessage()}}
|
||||
<strong>{{.getMessage()}}</strong>
|
||||
</div>
|
||||
{{/.isInfo()}}
|
||||
{{/alerts}}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue