From 0b41bbc44676648012a22fdabcd7a68c0b6d3198 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Wed, 18 Jan 2017 17:44:53 +0100 Subject: [PATCH] Added alerts for non responding sensors and user actions. issue #32 --- .../daemon/PCDataSynchronizationClient.java | 5 +++ .../daemon/SensorDataAggregatorDaemon.java | 10 ++++++ src/se/hal/intf/HalHttpPage.java | 2 +- src/se/hal/page/EventConfigHttpPage.java | 15 ++++++++ src/se/hal/page/HalAlertManager.java | 9 +++++ src/se/hal/page/SensorConfigHttpPage.java | 35 ++++++++++++++++++- src/se/hal/page/UserConfigHttpPage.java | 5 +++ 7 files changed, 79 insertions(+), 2 deletions(-) mode change 100644 => 100755 src/se/hal/daemon/PCDataSynchronizationClient.java mode change 100644 => 100755 src/se/hal/daemon/SensorDataAggregatorDaemon.java diff --git a/src/se/hal/daemon/PCDataSynchronizationClient.java b/src/se/hal/daemon/PCDataSynchronizationClient.java old mode 100644 new mode 100755 index 6a828301..8592a5c1 --- a/src/se/hal/daemon/PCDataSynchronizationClient.java +++ b/src/se/hal/daemon/PCDataSynchronizationClient.java @@ -6,6 +6,9 @@ import se.hal.daemon.PCDataSynchronizationDaemon.SensorDTO; import se.hal.daemon.PCDataSynchronizationDaemon.SensorDataDTO; import se.hal.daemon.PCDataSynchronizationDaemon.SensorDataListDTO; import se.hal.intf.HalDaemon; +import se.hal.page.HalAlertManager; +import se.hal.page.HalAlertManager.AlertTTL; +import se.hal.page.HalAlertManager.HalAlert; import se.hal.struct.Sensor; import se.hal.struct.User; import zutil.db.DBConnection; @@ -132,6 +135,8 @@ public class PCDataSynchronizationClient implements HalDaemon { } catch (NoRouteToHostException|UnknownHostException|ConnectException e) { logger.warning("Unable to connect to "+ user.getHostname()+":"+user.getPort() +", "+ e.getMessage()); + HalAlertManager.getInstance().addAlert(new HalAlert(HalAlertManager.AlertLevel.WARNING, + "Unable to connect to user with host: "+user.getHostname(), AlertTTL.DISMISSED)); } catch (Exception e) { logger.log(Level.SEVERE, null, e); } diff --git a/src/se/hal/daemon/SensorDataAggregatorDaemon.java b/src/se/hal/daemon/SensorDataAggregatorDaemon.java old mode 100644 new mode 100755 index 64715bc5..7bd9d1e1 --- a/src/se/hal/daemon/SensorDataAggregatorDaemon.java +++ b/src/se/hal/daemon/SensorDataAggregatorDaemon.java @@ -3,6 +3,10 @@ package se.hal.daemon; import se.hal.HalContext; import se.hal.intf.HalDaemon; import se.hal.intf.HalSensorConfig.AggregationMethod; +import se.hal.page.HalAlertManager; +import se.hal.page.HalAlertManager.AlertLevel; +import se.hal.page.HalAlertManager.AlertTTL; +import se.hal.page.HalAlertManager.HalAlert; import se.hal.struct.Sensor; import se.hal.util.UTCTimePeriod; import se.hal.util.UTCTimeUtility; @@ -111,6 +115,12 @@ public class SensorDataAggregatorDaemon implements HalDaemon { 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()){ + logger.fine("Sensor \"" + sensorId + "\" has stopped sending data"); + HalAlertManager.getInstance().addAlert(new HalAlert(AlertLevel.WARNING, + "Sensor \""+sensor.getName()+"\" has stopped responding", AlertTTL.DISMISSED)); + } return; }else{ logger.fine("evaluating period: "+ (maxTimestampFoundForSensor+1) + "=>" + latestCompletePeriodEndTimestamp + " (" + UTCTimeUtility.getDateString(maxTimestampFoundForSensor+1) + "=>" + UTCTimeUtility.getDateString(latestCompletePeriodEndTimestamp) + ") with expected sample count: " + expectedSampleCount); diff --git a/src/se/hal/intf/HalHttpPage.java b/src/se/hal/intf/HalHttpPage.java index 9124ca20..fa0c0a25 100755 --- a/src/se/hal/intf/HalHttpPage.java +++ b/src/se/hal/intf/HalHttpPage.java @@ -55,8 +55,8 @@ public abstract class HalHttpPage implements HttpPage{ } tmpl.set("rootNav", rootNav.createPagedNavInstance(header).getSubNavs()); tmpl.set("userNav", userNav.createPagedNavInstance(header).getSubNavs()); - tmpl.set("alerts", HalAlertManager.getInstance().generateAlerts()); tmpl.set("content", httpRespond(session, cookie, request)); + tmpl.set("alerts", HalAlertManager.getInstance().generateAlerts()); // do last so we don't miss any alerts out.print(tmpl.compile()); } catch (Exception e) { throw new IOException(e); diff --git a/src/se/hal/page/EventConfigHttpPage.java b/src/se/hal/page/EventConfigHttpPage.java index 3a84b473..847ec507 100755 --- a/src/se/hal/page/EventConfigHttpPage.java +++ b/src/se/hal/page/EventConfigHttpPage.java @@ -3,6 +3,9 @@ package se.hal.page; import se.hal.ControllerManager; import se.hal.HalContext; import se.hal.intf.HalHttpPage; +import se.hal.page.HalAlertManager.AlertLevel; +import se.hal.page.HalAlertManager.AlertTTL; +import se.hal.page.HalAlertManager.HalAlert; import se.hal.struct.Event; import se.hal.struct.User; import zutil.db.DBConnection; @@ -62,6 +65,8 @@ public class EventConfigHttpPage extends HalHttpPage { event.getDeviceConfigurator().setValues(request).applyConfiguration(); event.save(db); ControllerManager.getInstance().register(event); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully created new event: "+event.getName(), AlertTTL.ONE_VIEW)); break; case "modify_local_event": event = Event.getEvent(db, id); @@ -71,6 +76,11 @@ public class EventConfigHttpPage extends HalHttpPage { event.setUser(localUser); event.getDeviceConfigurator().setValues(request).applyConfiguration(); event.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully saved event: "+event.getName(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown event id: "+id, AlertTTL.ONE_VIEW)); } break; case "remove_local_event": @@ -78,6 +88,11 @@ public class EventConfigHttpPage extends HalHttpPage { if(event != null) { ControllerManager.getInstance().deregister(event); event.delete(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully deleted event: "+event.getName(), AlertTTL.ONE_VIEW)); + }else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown event id: "+id, AlertTTL.ONE_VIEW)); } break; } diff --git a/src/se/hal/page/HalAlertManager.java b/src/se/hal/page/HalAlertManager.java index 2c0bfc96..e71f0e80 100755 --- a/src/se/hal/page/HalAlertManager.java +++ b/src/se/hal/page/HalAlertManager.java @@ -42,6 +42,7 @@ public class HalAlertManager implements HttpPage { } public void addAlert(HalAlert alert){ + alerts.remove(alert); // We don't want to flood the user with duplicate alerts alerts.add(alert); } @@ -137,5 +138,13 @@ public class HalAlertManager implements HttpPage { public String getMessage() { return msg; } + + @Override + public boolean equals(Object obj){ + if (obj instanceof HalAlert) + return level == ((HalAlert) obj).level && + msg.equals(((HalAlert) obj).msg); + return false; + } } } diff --git a/src/se/hal/page/SensorConfigHttpPage.java b/src/se/hal/page/SensorConfigHttpPage.java index 048e6c45..186695fa 100755 --- a/src/se/hal/page/SensorConfigHttpPage.java +++ b/src/se/hal/page/SensorConfigHttpPage.java @@ -3,6 +3,9 @@ package se.hal.page; import se.hal.ControllerManager; import se.hal.HalContext; import se.hal.intf.HalHttpPage; +import se.hal.page.HalAlertManager.AlertLevel; +import se.hal.page.HalAlertManager.AlertTTL; +import se.hal.page.HalAlertManager.HalAlert; import se.hal.struct.Sensor; import se.hal.struct.User; import zutil.db.DBConnection; @@ -64,6 +67,8 @@ public class SensorConfigHttpPage extends HalHttpPage { sensor.getDeviceConfigurator().setValues(request).applyConfiguration(); sensor.save(db); ControllerManager.getInstance().register(sensor); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully created new sensor: "+sensor.getName(), AlertTTL.ONE_VIEW)); break; case "modify_local_sensor": sensor = Sensor.getSensor(db, id); @@ -73,6 +78,11 @@ public class SensorConfigHttpPage extends HalHttpPage { sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.getDeviceConfigurator().setValues(request).applyConfiguration(); sensor.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully saved sensor: "+sensor.getName(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown sensor id: "+id, AlertTTL.ONE_VIEW)); } break; case "remove_local_sensor": @@ -80,6 +90,11 @@ public class SensorConfigHttpPage extends HalHttpPage { if(sensor != null) { ControllerManager.getInstance().deregister(sensor); sensor.delete(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully deleted sensor: "+sensor.getName(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown sensor id: "+id, AlertTTL.ONE_VIEW)); } break; @@ -90,6 +105,8 @@ public class SensorConfigHttpPage extends HalHttpPage { user.setPort(Integer.parseInt(request.get("port"))); user.setExternal(true); user.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully created new external user with host: "+user.getHostname(), AlertTTL.ONE_VIEW)); break; case "modify_external_user": user = User.getUser(db, id); @@ -97,12 +114,23 @@ public class SensorConfigHttpPage extends HalHttpPage { user.setHostname(request.get("hostname")); user.setPort(Integer.parseInt(request.get("port"))); user.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully saved external user with host: "+user.getHostname(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown user id: "+id, AlertTTL.ONE_VIEW)); } break; case "remove_external_user": user = User.getUser(db, id); - if(user != null) + if (user != null) { user.delete(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully deleted user with host: "+user.getHostname(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown user id: "+id, AlertTTL.ONE_VIEW)); + } break; // External Sensors @@ -111,6 +139,11 @@ public class SensorConfigHttpPage extends HalHttpPage { if(sensor != null){ sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully saved external sensor: "+sensor.getName(), AlertTTL.ONE_VIEW)); + } else { + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.ERROR, "Unknown sensor id: "+id, AlertTTL.ONE_VIEW)); } break; } diff --git a/src/se/hal/page/UserConfigHttpPage.java b/src/se/hal/page/UserConfigHttpPage.java index 6e8d9ece..283121a5 100755 --- a/src/se/hal/page/UserConfigHttpPage.java +++ b/src/se/hal/page/UserConfigHttpPage.java @@ -2,6 +2,9 @@ package se.hal.page; import se.hal.HalContext; import se.hal.intf.HalHttpPage; +import se.hal.page.HalAlertManager.AlertLevel; +import se.hal.page.HalAlertManager.AlertTTL; +import se.hal.page.HalAlertManager.HalAlert; import se.hal.struct.User; import zutil.db.DBConnection; import zutil.io.file.FileUtil; @@ -43,6 +46,8 @@ public class UserConfigHttpPage extends HalHttpPage { localUser.setEmail(request.get("email")); localUser.setAddress(request.get("address")); localUser.save(db); + HalAlertManager.getInstance().addAlert(new HalAlert( + AlertLevel.SUCCESS, "Successfully saved profile changes", AlertTTL.ONE_VIEW)); break; } }