diff --git a/hal-core/resources/web/css/hal.css b/hal-core/resources/web/css/hal.css index 297886f4..0d5a35e6 100644 --- a/hal-core/resources/web/css/hal.css +++ b/hal-core/resources/web/css/hal.css @@ -146,3 +146,37 @@ body { transform: rotate(359deg); } } + +/* + * Animations + */ + +.pulse-border { + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0% { + stroke-width: 3; + opacity: 1; + } + + 10% { + stroke-width: 5; + opacity: 0.2; + } + 15% { + stroke-width: 5; + opacity: 0.2; + } + + 50% { + stroke-width: 3; + opacity: 1; + } + + 100% { + stroke-width: 3; + opacity: 1; + } +} \ No newline at end of file diff --git a/hal-core/resources/web/js/hal_map.js b/hal-core/resources/web/js/hal_map.js index 49e704a1..d05f22a4 100644 --- a/hal-core/resources/web/js/hal_map.js +++ b/hal-core/resources/web/js/hal_map.js @@ -155,11 +155,7 @@ function drawMap() { group.text(room.name).move(5, 5).fill('#999'); var rect = group.rect(room.map.width, room.map.height); - rect.fill('none').stroke({ - color: '#000', - opacity: 0.6, - width: 3 - }); + setAlertStyle(rect, (room.alert == null ? null : room.alert.level)); rect.addClass("resizable"); group.addClass("room") @@ -275,3 +271,36 @@ function saveDevice(element, type, id) { data: data }); } + +// ---------------------------------------------- +// Colors +// ---------------------------------------------- + +function setAlertStyle(target, level=null) { + target.addClass("pulse-border"); + target.fill('none'); + + switch(level) { + case "ERROR": + target.stroke({opacity: 1, color: '#f00'}); + break; + case "WARNING": + target.stroke({opacity: 1, color: '#ffa500'}); + break; + case "SUCCESS": + target.stroke({opacity: 1, color: '#90EE90'}); + break; + case "INFO": + target.stroke({opacity: 1, color: '#87CEFA'}); + break; + + default: + target.removeClass("pulse-border"); + target.stroke({ + color: '#000', + opacity: 0.6, + width: 3 + });; + break; + } +} \ No newline at end of file diff --git a/hal-core/src/se/hal/action/AlertAction.java b/hal-core/src/se/hal/action/AlertAction.java index 577e62cc..4074846f 100644 --- a/hal-core/src/se/hal/action/AlertAction.java +++ b/hal-core/src/se/hal/action/AlertAction.java @@ -33,6 +33,6 @@ public class AlertAction implements HalAction { public String toString(){ - return "Send Alert: " + severity + ": " + title; + return "Generate Alert: " + severity + ": " + title; } } diff --git a/hal-core/src/se/hal/action/DismissRoomAlertAction.java b/hal-core/src/se/hal/action/DismissRoomAlertAction.java new file mode 100644 index 00000000..fd52b061 --- /dev/null +++ b/hal-core/src/se/hal/action/DismissRoomAlertAction.java @@ -0,0 +1,42 @@ +package se.hal.action; + +import se.hal.HalContext; +import se.hal.intf.HalAction; +import se.hal.struct.Room; +import se.hal.util.RoomValueProvider; +import zutil.log.LogUtil; +import zutil.ui.UserMessageManager.MessageTTL; +import zutil.ui.conf.Configurator; + +import java.util.logging.Logger; + +import static zutil.ui.UserMessageManager.MessageLevel; +import static zutil.ui.UserMessageManager.UserMessage; + +/** + * Action that will alert users with a message + */ +public class DismissRoomAlertAction implements HalAction { + private static final Logger logger = LogUtil.getLogger(); + + @Configurator.Configurable(value = "Target Room", valueProvider = RoomValueProvider.class) + private Room room; + + + @Override + public void execute() { + if (room != null) { + room.clearRoomAlert(); + } else { + HalContext.getUserMessageManager().add(new UserMessage(MessageLevel.WARNING, "Room not defined for dismissing alert.", MessageTTL.ONE_VIEW)); + } + } + + + public String toString(){ + if (room != null) { + return "Dismiss alert for room: " + room.getName(); + } + return "No room defined."; + } +} diff --git a/hal-core/src/se/hal/action/RoomAlertAction.java b/hal-core/src/se/hal/action/RoomAlertAction.java new file mode 100644 index 00000000..f47f3ba7 --- /dev/null +++ b/hal-core/src/se/hal/action/RoomAlertAction.java @@ -0,0 +1,45 @@ +package se.hal.action; + +import se.hal.HalContext; +import se.hal.intf.HalAction; +import se.hal.struct.Room; +import se.hal.util.ConfigSensorValueProvider; +import se.hal.util.RoomValueProvider; +import zutil.db.DBConnection; +import zutil.log.LogUtil; +import zutil.ui.UserMessageManager.MessageTTL; +import zutil.ui.conf.Configurator; + +import java.util.logging.Logger; + +import static zutil.ui.UserMessageManager.MessageLevel; +import static zutil.ui.UserMessageManager.UserMessage; + +/** + * Action that will alert users with a message + */ +public class RoomAlertAction implements HalAction { + private static final Logger logger = LogUtil.getLogger(); + + @Configurator.Configurable(value = "Target Room", valueProvider = RoomValueProvider.class) + private Room room; + @Configurator.Configurable("Alert Severity") + private MessageLevel severity = MessageLevel.INFO; + @Configurator.Configurable("Alert Title") + private String title = ""; + + + @Override + public void execute() { + if (room != null) { + room.setRoomAlert(new UserMessage(severity, title, MessageTTL.DISMISSED)); + } else { + HalContext.getUserMessageManager().add(new UserMessage(MessageLevel.WARNING, "Room not defined for room alert.", MessageTTL.ONE_VIEW)); + } + } + + + public String toString(){ + return "Generate Room Alert: " + severity + ": " + title; + } +} diff --git a/hal-core/src/se/hal/plugin.json b/hal-core/src/se/hal/plugin.json index 9b89f5dd..91a89ae0 100644 --- a/hal-core/src/se/hal/plugin.json +++ b/hal-core/src/se/hal/plugin.json @@ -36,6 +36,8 @@ {"se.hal.intf.HalTrigger": "se.hal.trigger.TimerTrigger"}, {"se.hal.intf.HalAction": "se.hal.action.AlertAction"}, + {"se.hal.intf.HalAction": "se.hal.action.DismissRoomAlertAction"}, + {"se.hal.intf.HalAction": "se.hal.action.RoomAlertAction"}, {"se.hal.intf.HalAction": "se.hal.action.SendEventAction"} ] }