diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 8acca0b4c7..f8f0c6040c 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -197,15 +197,15 @@ public class DefaultDeviceStateService implements DeviceStateService { if (lastReportedActivity > 0 && lastReportedActivity > lastSavedActivity) { DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); if (stateData != null) { - DeviceState state = stateData.getState(); - stateData.getState().setLastActivityTime(lastReportedActivity); - stateData.getMetaData().putValue("scope", SERVER_SCOPE); - pushRuleEngineMessage(stateData, ACTIVITY_EVENT); save(deviceId, LAST_ACTIVITY_TIME, lastReportedActivity); deviceLastSavedActivity.put(deviceId, lastReportedActivity); + DeviceState state = stateData.getState(); if (!state.isActive()) { state.setActive(true); save(deviceId, ACTIVITY_STATE, state.isActive()); + state.setLastActivityTime(lastReportedActivity); + stateData.getMetaData().putValue("scope", SERVER_SCOPE); + pushRuleEngineMessage(stateData, ACTIVITY_EVENT); } } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractAlarmNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractAlarmNode.java index b3344105bb..766522d207 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractAlarmNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractAlarmNode.java @@ -41,7 +41,7 @@ public abstract class TbAbstractAlarmNode processAlarm(TbContext ctx, TbMsg msg) { String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg.getMetaData()); - ListenableFuture latest = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType); - return Futures.transformAsync(latest, a -> { - if (a != null && !a.getStatus().isCleared()) { - return clearAlarm(ctx, msg, a); + if (msg.getOriginator().getEntityType().equals(EntityType.ALARM)) { + return clearAlarmFromOriginator(ctx, msg); + } else { + ListenableFuture latest = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType); + return Futures.transformAsync(latest, a -> { + if (a != null && !a.getStatus().isCleared()) { + return clearAlarm(ctx, msg, a); + } + return Futures.immediateFuture(new AlarmResult(false, false, false, null)); + }, ctx.getDbCallbackExecutor()); + } + } + + private ListenableFuture clearAlarmFromOriginator(TbContext ctx, TbMsg msg) { + ListenableFuture alarmByIdAsync = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), new AlarmId(msg.getOriginator().getId())); + return Futures.transformAsync(alarmByIdAsync, alarm -> { + if (alarm != null && !alarm.getStatus().isCleared()) { + long clearTs = System.currentTimeMillis(); + ListenableFuture clearAlarmFuture = ctx.getAlarmService().clearAlarm(ctx.getTenantId(), alarm.getId(), alarm.getDetails(), clearTs); + return Futures.transformAsync(clearAlarmFuture, cleared -> { + if (cleared) { + alarm.setClearTs(clearTs); + AlarmStatus oldStatus = alarm.getStatus(); + AlarmStatus newStatus = oldStatus.isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK; + alarm.setStatus(newStatus); + return Futures.immediateFuture(new AlarmResult(false, false, true, alarm)); + } + return Futures.immediateFuture(new AlarmResult(false, false, false, alarm)); + }, ctx.getDbCallbackExecutor()); } return Futures.immediateFuture(new AlarmResult(false, false, false, null)); }, ctx.getDbCallbackExecutor());