Refactored alerts to be API based and not directly generated into the HTML
This commit is contained in:
parent
2ee0e775be
commit
ed04554a4a
27 changed files with 340 additions and 218 deletions
|
|
@ -1,6 +1,17 @@
|
||||||
{
|
{
|
||||||
"components": {
|
"components": {
|
||||||
"schemas": {
|
"schemas": {
|
||||||
|
"alertClass": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {"type": "integer"},
|
||||||
|
"level": {"type": "string"},
|
||||||
|
"ttl": {"type": "integer"},
|
||||||
|
"title": {"type": "string"},
|
||||||
|
"description": {"type": "string"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"eventClass": {
|
"eventClass": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -111,6 +122,50 @@
|
||||||
"openapi": "3.0.1",
|
"openapi": "3.0.1",
|
||||||
|
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/alert": {
|
||||||
|
"get": {
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/components/schemas/alertClass"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"poll",
|
||||||
|
"peek",
|
||||||
|
"dismiss"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"in": "query",
|
||||||
|
"name": "action",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"/event": {
|
"/event": {
|
||||||
"get": {
|
"get": {
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -119,12 +174,15 @@
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/components/schemas/eventClass"
|
"$ref": "#/components/schemas/eventClass"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
|
@ -163,12 +221,15 @@
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/components/schemas/roomClass"
|
"$ref": "#/components/schemas/roomClass"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
|
@ -191,12 +252,15 @@
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/components/schemas/sensorClass"
|
"$ref": "#/components/schemas/sensorClass"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
84
hal-core/resources/web/js/hal_alert.js
vendored
Normal file
84
hal-core/resources/web/js/hal_alert.js
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// Autostart
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var alertDivId = "alert-container"
|
||||||
|
var alertTemplate = {
|
||||||
|
ERROR: `
|
||||||
|
<div id="" data-alert-id="" class="alert alert-danger alert-dismissible fade in">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
<span class="glyphicon glyphicon-minus-sign"></span>
|
||||||
|
<strong class="alert-title"></strong>
|
||||||
|
<span class="alert-description"></span>
|
||||||
|
</div>`,
|
||||||
|
WARNING: `
|
||||||
|
<div id="" data-alert-id="" class="alert alert-warning alert-dismissible fade in">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
<span class="glyphicon glyphicon-warning-sign"></span>
|
||||||
|
<strong class="alert-title"></strong>
|
||||||
|
<span class="alert-description"></span>
|
||||||
|
</div>`,
|
||||||
|
SUCCESS: `
|
||||||
|
<div id="" data-alert-id="" class="alert alert-success alert-dismissible fade in">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
<span class="glyphicon glyphicon-ok-circle"></span>
|
||||||
|
<strong class="alert-title"></strong>
|
||||||
|
<span class="alert-description"></span>
|
||||||
|
</div>`,
|
||||||
|
INFO: `
|
||||||
|
<div id="" data-alert-id="" class="alert alert-info alert-dismissible fade in">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
<span class="glyphicon glyphicon-info-sign"></span>
|
||||||
|
<strong class="alert-title"></strong>
|
||||||
|
<span class="alert-description"></span>
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
updateAlerts();
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
updateAlerts();
|
||||||
|
}, 3000); // 3 sec
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateAlerts() {
|
||||||
|
fetch('/api/alert?action=poll')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(alert => {
|
||||||
|
var alertElement = $("#alert-id-" + alert.id);
|
||||||
|
if (alertElement.length <= 0) {
|
||||||
|
alertElement = $(alertTemplate[alert.level]);
|
||||||
|
$("#" + alertDivId).append(alertElement);
|
||||||
|
|
||||||
|
alertElement.attr("id", "alert-id-" + alert.id);
|
||||||
|
alertElement.data("alert-id", alert.id);
|
||||||
|
alertElement.find(".close").click(dismissEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
alertElement.find(".alert-title").html(alert.title);
|
||||||
|
alertElement.find(".alert-description").html(alert.description);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismissEvent(e) {
|
||||||
|
dismissAlert($(e.target).parent().parent().data("alert-id"));
|
||||||
|
}
|
||||||
|
function dismissAlert(id) {
|
||||||
|
fetch('/api/alert?action=dismiss&id=' + id)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
{{#alerts}}
|
|
||||||
{{#.isError()}}
|
|
||||||
<div class="alert alert-danger alert-dismissible fade in" role="alert">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close" data-id="{{.getId()}}">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<span class="glyphicon glyphicon-minus-sign" aria-hidden="true"></span>
|
|
||||||
<strong>{{.getTitle()}}</strong>
|
|
||||||
{{#.getMessage()}}{{.getMessage()}}{{/.getMessage()}}
|
|
||||||
</div>
|
|
||||||
{{/.isError()}}
|
|
||||||
{{#.isWarning()}}
|
|
||||||
<div class="alert alert-warning alert-dismissible fade in" role="alert">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close" data-id="{{.getId()}}">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"></span>
|
|
||||||
<strong>{{.getTitle()}}</strong>
|
|
||||||
{{#.getMessage()}}{{.getMessage()}}{{/.getMessage()}}
|
|
||||||
</div>
|
|
||||||
{{/.isWarning()}}
|
|
||||||
{{#.isSuccess()}}
|
|
||||||
<div class="alert alert-success alert-dismissible fade in" role="alert">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close" data-id="{{.getId()}}">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span>
|
|
||||||
<strong>{{.getTitle()}}</strong>
|
|
||||||
{{#.getMessage()}}{{.getMessage()}}{{/.getMessage()}}
|
|
||||||
</div>
|
|
||||||
{{/.isSuccess()}}
|
|
||||||
{{#.isInfo()}}
|
|
||||||
<div class="alert alert-info alert-dismissible fade in" role="alert">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close" data-id="{{.getId()}}">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
|
||||||
<strong>{{.getTitle()}}</strong>
|
|
||||||
{{#.getMessage()}}{{.getMessage()}}{{/.getMessage()}}
|
|
||||||
</div>
|
|
||||||
{{/.isInfo()}}
|
|
||||||
{{/alerts}}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(function(){
|
|
||||||
$(".alert .close").click(function(event){
|
|
||||||
$.get("{{serviceUrl}}?action=dismiss&id="+$(this).data("id"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
<script src="js/lib/bootstrap-switch.min.js"></script>
|
<script src="js/lib/bootstrap-switch.min.js"></script>
|
||||||
<script src="js/lib/moment.js"></script>
|
<script src="js/lib/moment.js"></script>
|
||||||
<script src="js/hal.js"></script>
|
<script src="js/hal.js"></script>
|
||||||
|
<script src="js/hal_alert.js"></script>
|
||||||
|
|
||||||
<!-- charts -->
|
<!-- charts -->
|
||||||
<script src="js/lib/d3.js"></script>
|
<script src="js/lib/d3.js"></script>
|
||||||
|
|
@ -37,7 +38,7 @@
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
{{/side_navigation}}
|
{{/side_navigation}}
|
||||||
{{^side_navigation}}<div class="main">{{/side_navigation}}
|
{{^side_navigation}}<div class="main">{{/side_navigation}}
|
||||||
{{alerts}}
|
<div id="alert-container"></div>
|
||||||
{{content}}
|
{{content}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
<script src="js/lib/svg.select.min.js"></script>
|
<script src="js/lib/svg.select.min.js"></script>
|
||||||
<script src="js/lib/svg.resize.min.js"></script>
|
<script src="js/lib/svg.resize.min.js"></script>
|
||||||
<script src="js/lib/svg.draggable.min.js"></script>
|
<script src="js/lib/svg.draggable.min.js"></script>
|
||||||
<script src="js/map.js"></script>
|
<script src="js/hal_map.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<!------------------ MODALS ---------------------->
|
<!------------------ MODALS ---------------------->
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import zutil.db.DBConnection;
|
||||||
import zutil.db.handler.PropertiesSQLResult;
|
import zutil.db.handler.PropertiesSQLResult;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.ui.UserMessageManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
@ -50,6 +51,7 @@ public class HalContext {
|
||||||
private static Properties fileConf = new Properties();
|
private static Properties fileConf = new Properties();
|
||||||
private static Properties dbConf = new Properties();
|
private static Properties dbConf = new Properties();
|
||||||
|
|
||||||
|
private static UserMessageManager messageManager = new UserMessageManager();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Set default values to get Hal up and running
|
// Set default values to get Hal up and running
|
||||||
|
|
@ -162,4 +164,8 @@ public class HalContext {
|
||||||
HalContext.db = db;
|
HalContext.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UserMessageManager getUserMessageManager() {
|
||||||
|
return messageManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package se.hal;
|
||||||
|
|
||||||
import se.hal.daemon.HalExternalWebDaemon;
|
import se.hal.daemon.HalExternalWebDaemon;
|
||||||
import se.hal.intf.*;
|
import se.hal.intf.*;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.page.StartupWebPage;
|
import se.hal.page.StartupWebPage;
|
||||||
import se.hal.struct.PluginConfig;
|
import se.hal.struct.PluginConfig;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -51,8 +50,6 @@ public class HalServer {
|
||||||
// init logging
|
// init logging
|
||||||
LogUtil.readConfiguration("logging.properties");
|
LogUtil.readConfiguration("logging.properties");
|
||||||
|
|
||||||
HalAlertManager.initialize();
|
|
||||||
|
|
||||||
http = new HttpServer(HalContext.getIntegerProperty(HalContext.CONFIG_HTTP_PORT));
|
http = new HttpServer(HalContext.getIntegerProperty(HalContext.CONFIG_HTTP_PORT));
|
||||||
http.setDefaultPage(new StartupWebPage());
|
http.setDefaultPage(new StartupWebPage());
|
||||||
http.start();
|
http.start();
|
||||||
|
|
@ -138,7 +135,6 @@ public class HalServer {
|
||||||
|
|
||||||
http.setDefaultPage(filePage);
|
http.setDefaultPage(filePage);
|
||||||
http.setPage("/", new HttpRedirectPage("/map"));
|
http.setPage("/", new HttpRedirectPage("/map"));
|
||||||
http.setPage(HalAlertManager.getInstance().getUrl(), HalAlertManager.getInstance());
|
|
||||||
|
|
||||||
for (Iterator<HalWebPage> it = pluginManager.getSingletonIterator(HalApiEndpoint.class); it.hasNext(); )
|
for (Iterator<HalWebPage> it = pluginManager.getSingletonIterator(HalApiEndpoint.class); it.hasNext(); )
|
||||||
registerPage(it.next());
|
registerPage(it.next());
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package se.hal.action;
|
package se.hal.action;
|
||||||
|
|
||||||
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalAction;
|
import se.hal.intf.HalAction;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
import zutil.ui.UserMessageManager.MessageTTL;
|
import zutil.ui.UserMessageManager.MessageTTL;
|
||||||
import zutil.ui.conf.Configurator;
|
import zutil.ui.conf.Configurator;
|
||||||
|
|
@ -20,17 +20,19 @@ public class AlertAction implements HalAction {
|
||||||
private MessageLevel severity = MessageLevel.INFO;
|
private MessageLevel severity = MessageLevel.INFO;
|
||||||
@Configurator.Configurable("Alert Message")
|
@Configurator.Configurable("Alert Message")
|
||||||
private MessageTTL ttl = MessageTTL.ONE_VIEW;
|
private MessageTTL ttl = MessageTTL.ONE_VIEW;
|
||||||
@Configurator.Configurable("Alert Message")
|
@Configurator.Configurable("Alert Title")
|
||||||
private String message = "";
|
private String title = "";
|
||||||
|
@Configurator.Configurable("Alert Description")
|
||||||
|
private String description = "";
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(severity, message, ttl));
|
HalContext.getUserMessageManager().add(new UserMessage(severity, title, description, ttl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "Send Alert: " + severity + ": " + message;
|
return "Send Alert: " + severity + ": " + title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import org.shredzone.acme4j.exception.AcmeException;
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalDaemon;
|
import se.hal.intf.HalDaemon;
|
||||||
import se.hal.intf.HalWebPage;
|
import se.hal.intf.HalWebPage;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.util.HalAcmeDataStore;
|
import se.hal.util.HalAcmeDataStore;
|
||||||
import se.hal.util.HalOAuth2RegistryStore;
|
import se.hal.util.HalOAuth2RegistryStore;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
|
@ -79,12 +78,12 @@ public class HalExternalWebDaemon implements HalDaemon {
|
||||||
startHttpServer();
|
startHttpServer();
|
||||||
} else {
|
} else {
|
||||||
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external web-server.");
|
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external web-server.");
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessageManager.UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessageManager.UserMessage(
|
||||||
UserMessageManager.MessageLevel.WARNING, "Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external web-server.", UserMessageManager.MessageTTL.DISMISSED));
|
UserMessageManager.MessageLevel.WARNING, "Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external web-server.", UserMessageManager.MessageTTL.DISMISSED));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "Was unable to initiate external web-server.", e);
|
logger.log(Level.SEVERE, "Was unable to initiate external web-server.", e);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessageManager.UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessageManager.UserMessage(
|
||||||
UserMessageManager.MessageLevel.ERROR, "Was unable to initiate external web-server: " + e.getMessage(), UserMessageManager.MessageTTL.DISMISSED));
|
UserMessageManager.MessageLevel.ERROR, "Was unable to initiate external web-server: " + e.getMessage(), UserMessageManager.MessageTTL.DISMISSED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +118,7 @@ public class HalExternalWebDaemon implements HalDaemon {
|
||||||
acmeDataStore.storeCertificate(certificate);
|
acmeDataStore.storeCertificate(certificate);
|
||||||
|
|
||||||
logger.info("SSL certificate successfully generated.");
|
logger.info("SSL certificate successfully generated.");
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessageManager.UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessageManager.UserMessage(
|
||||||
UserMessageManager.MessageLevel.INFO, "SSL certificate successfully generated for external web-server.", UserMessageManager.MessageTTL.DISMISSED));
|
UserMessageManager.MessageLevel.INFO, "SSL certificate successfully generated for external web-server.", UserMessageManager.MessageTTL.DISMISSED));
|
||||||
} else {
|
} else {
|
||||||
logger.warning("No SSL certificate is configured for external web-server, will run server in unsecure mode (not recommended).");
|
logger.warning("No SSL certificate is configured for external web-server, will run server in unsecure mode (not recommended).");
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package se.hal.daemon;
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalDaemon;
|
import se.hal.intf.HalDaemon;
|
||||||
import se.hal.intf.HalSensorConfig.AggregationMethod;
|
import se.hal.intf.HalSensorConfig.AggregationMethod;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.struct.Sensor;
|
import se.hal.struct.Sensor;
|
||||||
import se.hal.util.UTCTimePeriod;
|
import se.hal.util.UTCTimePeriod;
|
||||||
import se.hal.util.UTCTimeUtility;
|
import se.hal.util.UTCTimeUtility;
|
||||||
|
|
@ -119,7 +118,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon, Runnable {
|
||||||
"at <span class=\"timestamp\">"+dbMaxRawTimestamp+"</span>",
|
"at <span class=\"timestamp\">"+dbMaxRawTimestamp+"</span>",
|
||||||
MessageTTL.DISMISSED);
|
MessageTTL.DISMISSED);
|
||||||
alertMap.put(sensor.getId(), alert);
|
alertMap.put(sensor.getId(), alert);
|
||||||
HalAlertManager.getInstance().addAlert(alert);
|
HalContext.getUserMessageManager().add(alert);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Sensor has responded remove alert
|
// Sensor has responded remove alert
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package se.hal.intf;
|
package se.hal.intf;
|
||||||
|
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.struct.User;
|
import se.hal.struct.User;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
|
|
@ -78,7 +77,6 @@ public abstract class HalWebPage implements HttpPage{
|
||||||
main.set("navigation", navigationTemplate);
|
main.set("navigation", navigationTemplate);
|
||||||
main.set("side_navigation", subNavigationTemplate);
|
main.set("side_navigation", subNavigationTemplate);
|
||||||
main.set("content", httpRespond(session, cookie, request));
|
main.set("content", httpRespond(session, cookie, request));
|
||||||
main.set("alerts", HalAlertManager.getInstance().generateAlerts()); // do last so we don't miss any alerts
|
|
||||||
|
|
||||||
out.print(main.compile());
|
out.print(main.compile());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class EventConfigWebPage extends HalWebPage {
|
||||||
|
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
logger.warning("Unknown event id: " + id);
|
logger.warning("Unknown event id: " + id);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unknown event id: " + id, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unknown event id: " + id, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ public class EventConfigWebPage extends HalWebPage {
|
||||||
event.save(db);
|
event.save(db);
|
||||||
EventControllerManager.getInstance().register(event);
|
EventControllerManager.getInstance().register(event);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully created new event: " + event.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully created new event: " + event.getName(), MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ public class EventConfigWebPage extends HalWebPage {
|
||||||
event.getDeviceConfigurator().setValues(request).applyConfiguration();
|
event.getDeviceConfigurator().setValues(request).applyConfiguration();
|
||||||
event.save(db);
|
event.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved event: "+event.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved event: "+event.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -106,7 +106,7 @@ public class EventConfigWebPage extends HalWebPage {
|
||||||
EventControllerManager.getInstance().deregister(event);
|
EventControllerManager.getInstance().deregister(event);
|
||||||
event.delete(db);
|
event.delete(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully removed event: "+event.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully removed event: "+event.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -120,7 +120,7 @@ public class EventConfigWebPage extends HalWebPage {
|
||||||
if (controller instanceof HalScannableController) {
|
if (controller instanceof HalScannableController) {
|
||||||
((HalScannableController) controller).startScan();
|
((HalScannableController) controller).startScan();
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controller.getClass().getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controller.getClass().getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
package se.hal.page;
|
|
||||||
|
|
||||||
import se.hal.HalContext;
|
|
||||||
import zutil.io.file.FileUtil;
|
|
||||||
import zutil.log.LogUtil;
|
|
||||||
import zutil.net.http.HttpHeader;
|
|
||||||
import zutil.net.http.HttpPage;
|
|
||||||
import zutil.net.http.HttpPrintStream;
|
|
||||||
import zutil.parser.Templator;
|
|
||||||
import zutil.ui.UserMessageManager;
|
|
||||||
import zutil.ui.UserMessageManager.UserMessage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class HalAlertManager implements HttpPage {
|
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
|
||||||
private static final String TEMPLATE = HalContext.RESOURCE_WEB_ROOT + "/main_alerts.tmpl";
|
|
||||||
private static final String PAGE_NAME = "alert";
|
|
||||||
private static HalAlertManager instance;
|
|
||||||
|
|
||||||
private UserMessageManager messageManager = new UserMessageManager();
|
|
||||||
|
|
||||||
|
|
||||||
private HalAlertManager() {}
|
|
||||||
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return "/" + PAGE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAlert(UserMessage alert) {
|
|
||||||
messageManager.add(alert);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Templator generateAlerts() {
|
|
||||||
try {
|
|
||||||
List<UserMessage> messages = messageManager.getMessages();
|
|
||||||
for (UserMessage msg : messages) {
|
|
||||||
msg.decreaseTTL();
|
|
||||||
}
|
|
||||||
|
|
||||||
Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
|
|
||||||
tmpl.set("serviceUrl", getUrl());
|
|
||||||
tmpl.set("alerts", messages);
|
|
||||||
return tmpl;
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.log(Level.SEVERE, null, e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void respond(HttpPrintStream out,
|
|
||||||
HttpHeader headers,
|
|
||||||
Map<String, Object> session,
|
|
||||||
Map<String, String> cookie,
|
|
||||||
Map<String, String> request) throws IOException {
|
|
||||||
|
|
||||||
if (request.containsKey("action")) {
|
|
||||||
if (request.get("action").equals("dismiss")) {
|
|
||||||
// parse alert id
|
|
||||||
int id = Integer.parseInt(request.get("id"));
|
|
||||||
// Find alert
|
|
||||||
UserMessage msg = messageManager.get(id);
|
|
||||||
if (msg != null)
|
|
||||||
msg.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void initialize() {
|
|
||||||
instance = new HalAlertManager();
|
|
||||||
}
|
|
||||||
public static HalAlertManager getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -43,10 +43,10 @@ public class PluginConfigWebPage extends HalWebPage {
|
||||||
HalServer.enablePlugin(name,
|
HalServer.enablePlugin(name,
|
||||||
(request.containsKey("enabled") && "on".equals(request.get("enabled"))));
|
(request.containsKey("enabled") && "on".equals(request.get("enabled"))));
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully updated plugin " + name + ", change will take affect after restart.", MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully updated plugin " + name + ", change will take affect after restart.", MessageTTL.ONE_VIEW));
|
||||||
} else {
|
} else {
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Hal-Core cannot be disabled as it is critical component of Hal.", MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Hal-Core cannot be disabled as it is critical component of Hal.", MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -66,14 +66,14 @@ public class PluginConfigWebPage extends HalWebPage {
|
||||||
if (controller instanceof HalScannableController) {
|
if (controller instanceof HalScannableController) {
|
||||||
((HalScannableController) controller).startScan();
|
((HalScannableController) controller).startScan();
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controllerName, MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controllerName, MessageTTL.ONE_VIEW));
|
||||||
} else {
|
} else {
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Controller " + controllerName + " does not support scanning.", MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Controller " + controllerName + " does not support scanning.", MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unable to find controller: " + controllerName, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unable to find controller: " + controllerName, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ public class RoomConfigWebPage extends HalWebPage {
|
||||||
|
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
logger.warning("Unknown room id: " + id);
|
logger.warning("Unknown room id: " + id);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unknown room id: " + id, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unknown room id: " + id, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ public class RoomConfigWebPage extends HalWebPage {
|
||||||
room.setName(request.get("name"));
|
room.setName(request.get("name"));
|
||||||
room.save(db);
|
room.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully updated room: " + room.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully updated room: " + room.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -100,7 +100,7 @@ public class RoomConfigWebPage extends HalWebPage {
|
||||||
logger.info("Removing room(id: " + room.getId() + "): " + room.getName());
|
logger.info("Removing room(id: " + room.getId() + "): " + room.getName());
|
||||||
room.delete(db);
|
room.delete(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully removed room: " + room.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully removed room: " + room.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
|
|
||||||
if (sensor == null) {
|
if (sensor == null) {
|
||||||
logger.warning("Unknown sensor id: " + sensorId);
|
logger.warning("Unknown sensor id: " + sensorId);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unknown sensor id: " + sensorId, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unknown sensor id: " + sensorId, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
logger.warning("Unknown user id: " + userId);
|
logger.warning("Unknown user id: " + userId);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unknown user id: " + userId, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unknown user id: " + userId, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +99,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
sensor.save(db);
|
sensor.save(db);
|
||||||
SensorControllerManager.getInstance().register(sensor);
|
SensorControllerManager.getInstance().register(sensor);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully created new sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully created new sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
sensor.getDeviceConfigurator().setValues(request).applyConfiguration();
|
sensor.getDeviceConfigurator().setValues(request).applyConfiguration();
|
||||||
sensor.save(db);
|
sensor.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -124,7 +124,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
SensorControllerManager.getInstance().deregister(sensor);
|
SensorControllerManager.getInstance().deregister(sensor);
|
||||||
sensor.delete(db);
|
sensor.delete(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully removed sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully removed sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -138,7 +138,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
if (controller instanceof HalScannableController) {
|
if (controller instanceof HalScannableController) {
|
||||||
((HalScannableController) controller).startScan();
|
((HalScannableController) controller).startScan();
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controller.getClass().getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Initiated scanning on controller: " + controller.getClass().getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
user.setExternal(true);
|
user.setExternal(true);
|
||||||
user.save(db);
|
user.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully created new external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully created new external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -167,7 +167,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
user.setPort(Integer.parseInt(request.get("port")));
|
user.setPort(Integer.parseInt(request.get("port")));
|
||||||
user.save(db);
|
user.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -176,7 +176,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
logger.info("Removing external user: " + user.getHostname());
|
logger.info("Removing external user: " + user.getHostname());
|
||||||
user.delete(db);
|
user.delete(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully removed user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully removed user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -191,7 +191,7 @@ public class SensorConfigWebPage extends HalWebPage {
|
||||||
sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
|
sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
|
||||||
sensor.save(db);
|
sensor.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved external sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved external sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public class TriggerWebPage extends HalWebPage {
|
||||||
case "create_trigger":
|
case "create_trigger":
|
||||||
if (flow == null) {
|
if (flow == null) {
|
||||||
logger.warning("Invalid flow id: " + request.get("flow-id"));
|
logger.warning("Invalid flow id: " + request.get("flow-id"));
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Invalid flow id: " + request.get("flow-id"), MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Invalid flow id: " + request.get("flow-id"), MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ public class TriggerWebPage extends HalWebPage {
|
||||||
// Triggers
|
// Triggers
|
||||||
case "create_action":
|
case "create_action":
|
||||||
if (flow == null) {
|
if (flow == null) {
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Invalid flow id", MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Invalid flow id", MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public class UserConfigWebPage extends HalWebPage {
|
||||||
localUser.setAddress(request.get("address"));
|
localUser.setAddress(request.get("address"));
|
||||||
localUser.save(db);
|
localUser.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved profile changes", MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved profile changes", MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
114
hal-core/src/se/hal/page/api/AlertApiEndpoint.java
Normal file
114
hal-core/src/se/hal/page/api/AlertApiEndpoint.java
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
package se.hal.page.api;
|
||||||
|
|
||||||
|
import se.hal.HalContext;
|
||||||
|
import se.hal.intf.HalApiEndpoint;
|
||||||
|
import se.hal.struct.Event;
|
||||||
|
import zutil.ArrayUtil;
|
||||||
|
import zutil.ObjectUtil;
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.parser.DataNode;
|
||||||
|
import zutil.ui.UserMessageManager;
|
||||||
|
import zutil.ui.UserMessageManager.UserMessage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RESTish API for accessing and managing user alert.
|
||||||
|
* For web interface definition see the OpenApi definition hal-core/resources/web/api/doc.html
|
||||||
|
*/
|
||||||
|
public class AlertApiEndpoint extends HalApiEndpoint {
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
|
||||||
|
public AlertApiEndpoint() {
|
||||||
|
super("api/alert");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataNode jsonRespond(
|
||||||
|
Map<String, Object> session,
|
||||||
|
Map<String, String> cookie,
|
||||||
|
Map<String, String> request) throws Exception{
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Filter alerts
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
String[] req_ids = new String[0];
|
||||||
|
if (request.get("id") != null)
|
||||||
|
req_ids = request.get("id").split(",");
|
||||||
|
|
||||||
|
// Filter devices
|
||||||
|
|
||||||
|
List<UserMessage> messages = new ArrayList<>();
|
||||||
|
for (UserMessage message : HalContext.getUserMessageManager().getMessages()) {
|
||||||
|
boolean filter_match = true;
|
||||||
|
|
||||||
|
// id filtering
|
||||||
|
if (!ObjectUtil.isEmpty((Object) req_ids) && !ArrayUtil.contains(req_ids, "" + message.getId())) {
|
||||||
|
filter_match = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the filter
|
||||||
|
if (filter_match) {
|
||||||
|
messages.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(request.get("action"))) {
|
||||||
|
messages.clear(); // Reset the message list
|
||||||
|
} else {
|
||||||
|
switch (request.get("action")) {
|
||||||
|
case "poll":
|
||||||
|
for (UserMessage message : messages) {
|
||||||
|
message.decreaseTTL();
|
||||||
|
}
|
||||||
|
case "peek":
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "dismiss":
|
||||||
|
for (UserMessage message : messages) {
|
||||||
|
message.dismiss();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
messages.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Generate DataNode
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
DataNode root = new DataNode(DataNode.DataType.List);
|
||||||
|
|
||||||
|
for (UserMessage message : messages) {
|
||||||
|
root.add(getUserMessageDataNode(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message the source alert to generate data node for.
|
||||||
|
* @return a DataNode containing relevant information from the given alert. Will return null if the message is null.
|
||||||
|
*/
|
||||||
|
public static DataNode getUserMessageDataNode(UserMessage message) {
|
||||||
|
if (message == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
DataNode node = new DataNode(DataNode.DataType.Map);
|
||||||
|
node.set("id", message.getId());
|
||||||
|
node.set("level", message.getLevel().toString());
|
||||||
|
node.set("ttl", message.getTitle());
|
||||||
|
node.set("title", message.getTitle());
|
||||||
|
node.set("description", message.getDescription());
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,12 +15,8 @@ import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available HTTP Get Request parameters:
|
* RESTish API for accessing and managing Events.
|
||||||
* <pre>
|
* For web interface definition see the OpenApi definition hal-core/resources/web/api/doc.html
|
||||||
* Event filtering parameters:
|
|
||||||
* id: comma separated numeric id for specific events
|
|
||||||
* type: event data type name
|
|
||||||
* </pre>
|
|
||||||
*/
|
*/
|
||||||
public class EventApiEndpoint extends HalApiEndpoint {
|
public class EventApiEndpoint extends HalApiEndpoint {
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
@ -57,7 +53,7 @@ public class EventApiEndpoint extends HalApiEndpoint {
|
||||||
boolean filter_match = true;
|
boolean filter_match = true;
|
||||||
|
|
||||||
// id filtering
|
// id filtering
|
||||||
if (!ObjectUtil.isEmpty(req_ids) && !ArrayUtil.contains(req_ids, "" + event.getId())) {
|
if (!ObjectUtil.isEmpty((Object) req_ids) && !ArrayUtil.contains(req_ids, "" + event.getId())) {
|
||||||
filter_match = false;
|
filter_match = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST service to fetch event device information.
|
* REST service to fetch event device information.
|
||||||
|
* For web interface definition see the OpenApi definition hal-core/resources/web/api/doc.html
|
||||||
*/
|
*/
|
||||||
public class RoomApiEndpoint extends HalApiEndpoint {
|
public class RoomApiEndpoint extends HalApiEndpoint {
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
@ -49,7 +50,7 @@ public class RoomApiEndpoint extends HalApiEndpoint {
|
||||||
boolean filter_match = true;
|
boolean filter_match = true;
|
||||||
|
|
||||||
// id filtering
|
// id filtering
|
||||||
if (!ObjectUtil.isEmpty(req_ids) && !ArrayUtil.contains(req_ids, "" + room.getId())) {
|
if (!ObjectUtil.isEmpty((Object) req_ids) && !ArrayUtil.contains(req_ids, "" + room.getId())) {
|
||||||
filter_match = false;
|
filter_match = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,8 @@ import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available HTTP Get Request parameters:
|
* RESTish API for accessing and managing Sensors.
|
||||||
* <pre>
|
* For web interface definition see the OpenApi definition hal-core/resources/web/api/doc.html
|
||||||
* Sensor filtering parameters:
|
|
||||||
* id: comma separated numeric id for specific sensors
|
|
||||||
* type: sensor data type name
|
|
||||||
*
|
|
||||||
* Data filtering parameters:
|
|
||||||
* aggr: Aggregation periods, needs to be provided to retrieve data. Possible values: minute,hour,day,week
|
|
||||||
* </pre>
|
|
||||||
*/
|
*/
|
||||||
public class SensorApiEndpoint extends HalApiEndpoint {
|
public class SensorApiEndpoint extends HalApiEndpoint {
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
@ -62,7 +55,7 @@ public class SensorApiEndpoint extends HalApiEndpoint {
|
||||||
boolean filter_match = true;
|
boolean filter_match = true;
|
||||||
|
|
||||||
// id filtering
|
// id filtering
|
||||||
if (!ObjectUtil.isEmpty(reqIds) && !ArrayUtil.contains(reqIds, "" + sensor.getId())) {
|
if (!ObjectUtil.isEmpty((Object) reqIds) && !ArrayUtil.contains(reqIds, "" + sensor.getId())) {
|
||||||
filter_match = false;
|
filter_match = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataAggregatorDaemon"},
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataAggregatorDaemon"},
|
||||||
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataCleanupDaemon"},
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataCleanupDaemon"},
|
||||||
|
|
||||||
|
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.AlertApiEndpoint"},
|
||||||
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.EventApiEndpoint"},
|
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.EventApiEndpoint"},
|
||||||
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.MapApiEndpoint"},
|
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.MapApiEndpoint"},
|
||||||
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.RoomApiEndpoint"},
|
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.RoomApiEndpoint"},
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package se.hal.struct;
|
package se.hal.struct;
|
||||||
|
|
||||||
|
import se.hal.page.api.AlertApiEndpoint;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.db.bean.DBBean;
|
import zutil.db.bean.DBBean;
|
||||||
import zutil.db.bean.DBBeanSQLResultHandler;
|
import zutil.db.bean.DBBeanSQLResultHandler;
|
||||||
import zutil.parser.DataNode;
|
import zutil.parser.DataNode;
|
||||||
import zutil.ui.UserMessageManager.UserMessage;
|
import zutil.ui.UserMessageManager.UserMessage;
|
||||||
import zutil.ui.conf.Configurator;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
@ -77,16 +77,21 @@ public class Room extends DBBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataNode getDataNode() {
|
public DataNode getDataNode() {
|
||||||
DataNode deviceNode = new DataNode(DataNode.DataType.Map);
|
DataNode rootNode = new DataNode(DataNode.DataType.Map);
|
||||||
deviceNode.set("id", getId());
|
rootNode.set("id", getId());
|
||||||
deviceNode.set("name", getName());
|
rootNode.set("name", getName());
|
||||||
|
|
||||||
DataNode mapNode = deviceNode.set("map", DataNode.DataType.Map);
|
DataNode mapNode = rootNode.set("map", DataNode.DataType.Map);
|
||||||
mapNode.set("x", getMapX());
|
mapNode.set("x", getMapX());
|
||||||
mapNode.set("y", getMapY());
|
mapNode.set("y", getMapY());
|
||||||
mapNode.set("width", getMapWidth());
|
mapNode.set("width", getMapWidth());
|
||||||
mapNode.set("height", getMapHeight());
|
mapNode.set("height", getMapHeight());
|
||||||
|
|
||||||
return deviceNode;
|
if (roomAlert != null) {
|
||||||
|
DataNode alertNode = AlertApiEndpoint.getUserMessageDataNode(roomAlert);
|
||||||
|
rootNode.set("alert", alertNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,13 @@
|
||||||
|
|
||||||
package se.hal.plugin.nvr.page;
|
package se.hal.plugin.nvr.page;
|
||||||
|
|
||||||
import se.hal.EventControllerManager;
|
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalWebPage;
|
import se.hal.intf.HalWebPage;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.plugin.nvr.CameraControllerManager;
|
import se.hal.plugin.nvr.CameraControllerManager;
|
||||||
import se.hal.plugin.nvr.struct.Camera;
|
import se.hal.plugin.nvr.struct.Camera;
|
||||||
import se.hal.struct.Room;
|
import se.hal.struct.Room;
|
||||||
import se.hal.util.ClassConfigurationFacade;
|
import se.hal.util.ClassConfigurationFacade;
|
||||||
import se.hal.struct.User;
|
import se.hal.struct.User;
|
||||||
import se.hal.util.RoomValueProvider;
|
|
||||||
import zutil.ObjectUtil;
|
import zutil.ObjectUtil;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
|
|
@ -46,6 +43,7 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import static zutil.ui.UserMessageManager.*;
|
import static zutil.ui.UserMessageManager.*;
|
||||||
|
|
||||||
|
|
||||||
public class CameraConfigWebPage extends HalWebPage {
|
public class CameraConfigWebPage extends HalWebPage {
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
private static final String TEMPLATE = HalContext.RESOURCE_WEB_ROOT + "/camera_config.tmpl";
|
private static final String TEMPLATE = HalContext.RESOURCE_WEB_ROOT + "/camera_config.tmpl";
|
||||||
|
|
@ -86,7 +84,7 @@ public class CameraConfigWebPage extends HalWebPage {
|
||||||
|
|
||||||
if (camera == null) {
|
if (camera == null) {
|
||||||
logger.warning("Unknown camera id: " + id);
|
logger.warning("Unknown camera id: " + id);
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.ERROR, "Unknown camera id: " + id, MessageTTL.ONE_VIEW));
|
MessageLevel.ERROR, "Unknown camera id: " + id, MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +101,7 @@ public class CameraConfigWebPage extends HalWebPage {
|
||||||
camera.save(db);
|
camera.save(db);
|
||||||
CameraControllerManager.getInstance().register(camera);
|
CameraControllerManager.getInstance().register(camera);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully created new camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully created new camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -117,7 +115,7 @@ public class CameraConfigWebPage extends HalWebPage {
|
||||||
camera.getDeviceConfigurator().setValues(request).applyConfiguration();
|
camera.getDeviceConfigurator().setValues(request).applyConfiguration();
|
||||||
camera.save(db);
|
camera.save(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully saved camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully saved camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -128,7 +126,7 @@ public class CameraConfigWebPage extends HalWebPage {
|
||||||
CameraControllerManager.getInstance().deregister(camera);
|
CameraControllerManager.getInstance().deregister(camera);
|
||||||
camera.delete(db);
|
camera.delete(db);
|
||||||
|
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(
|
HalContext.getUserMessageManager().add(new UserMessage(
|
||||||
MessageLevel.SUCCESS, "Successfully removed camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
MessageLevel.SUCCESS, "Successfully removed camera: " + camera.getName(), MessageTTL.ONE_VIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ package se.hal.plugin.powerchallenge.daemon;
|
||||||
|
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.HalDaemon;
|
import se.hal.intf.HalDaemon;
|
||||||
import se.hal.page.HalAlertManager;
|
|
||||||
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.PeerDataRspDTO;
|
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.PeerDataRspDTO;
|
||||||
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.SensorDTO;
|
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.SensorDTO;
|
||||||
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.SensorDataDTO;
|
import se.hal.plugin.powerchallenge.daemon.PCDataSynchronizationDaemon.SensorDataDTO;
|
||||||
|
|
@ -157,7 +156,7 @@ public class PCDataSynchronizationClient implements HalDaemon, Runnable {
|
||||||
|
|
||||||
} catch (NoRouteToHostException|UnknownHostException|ConnectException|SocketTimeoutException e) {
|
} catch (NoRouteToHostException|UnknownHostException|ConnectException|SocketTimeoutException e) {
|
||||||
logger.warning("Unable to connect to "+ user.getHostname()+":"+user.getPort() +", "+ e.getMessage());
|
logger.warning("Unable to connect to "+ user.getHostname()+":"+user.getPort() +", "+ e.getMessage());
|
||||||
HalAlertManager.getInstance().addAlert(new UserMessage(MessageLevel.WARNING,
|
HalContext.getUserMessageManager().add(new UserMessage(MessageLevel.WARNING,
|
||||||
"Unable to connect to user with host: "+user.getHostname(), MessageTTL.DISMISSED));
|
"Unable to connect to user with host: "+user.getHostname(), MessageTTL.DISMISSED));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, null, e);
|
logger.log(Level.SEVERE, null, e);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue