Commit 1afb808cafe7133503efc58d1ae1847c069e5a9c

Authored by 云中非
1 parent 13530c95

refactor: 场景联动触发告警通知

... ... @@ -28,17 +28,18 @@ import java.net.InetAddress;
28 28 @RequiredArgsConstructor
29 29 @Slf4j
30 30 @Api(tags = {"告警通知"})
  31 +@Deprecated
31 32 public class YtAlarmNoticeController {
32 33
33 34 private final YtNoticeService service;
34 35
35   - @PostMapping("/alert")
  36 + @PostMapping("/alert/{alarmProfileId}")
36 37 public void alertNotice(@RequestParam(value = "token", required = true) String token,
37   - @RequestBody AlarmInfoDTO alarmInfo) {
  38 + @PathVariable("alarmProfileId") String alarmProfileId, @RequestBody AlarmInfoDTO alarmInfo) {
38 39 Assert.notNull(token, "token cannot be null");
39 40 Assert.notNull(alarmInfo, "alarm info cannot be null");
40 41 if (parseTokenClaims(token, alarmInfo)) {
41   - service.alert(alarmInfo);
  42 + service.alert(alarmProfileId, alarmInfo);
42 43 }
43 44 }
44 45
... ...
... ... @@ -12,19 +12,14 @@ import org.thingsboard.server.common.data.yunteng.enums.ScopeEnum;
12 12 import java.util.List;
13 13
14 14 /**
15   - * @Description 场景联动动作告警通知
  15 + * @Description 场景联动动作告警通知
16 16 * @Author cxy
17 17 * @Date 2021/11/24 17:32
18 18 */
19 19 @Data
20   -public class ActionAlarmDTO extends TenantDTO{
  20 +public class ActionAlarmDTO extends TenantDTO {
21 21
22 22
23   - private List<ActionTypeEnum> noticeType;
24   -
25   - /**告警联系人*/
26   - private List<String> noticeUser;
27   -
28 23 private AlarmSeverity alarmLevel;
29 24
30 25
... ...
... ... @@ -6,37 +6,38 @@ import lombok.EqualsAndHashCode;
6 6
7 7 import javax.validation.constraints.NotEmpty;
8 8
9   -/** @Description @Author cxy @Date 2021/11/16 17:49 */
  9 +/**
  10 + * @Description @Author cxy @Date 2021/11/16 17:49
  11 + */
10 12 @Data
11 13 @EqualsAndHashCode(callSuper = true)
12 14 public class AlarmInfoDTO extends TenantDTO {
13   - @ApiModelProperty(value = "告警时间")
14   - private long createTs;
  15 + @ApiModelProperty(value = "告警时间")
  16 + private long createTs;
15 17
16   - @ApiModelProperty(value = "告警类型")
17   - private String type;
  18 + @ApiModelProperty(value = "告警名称")
  19 + private String type;
18 20
19   - @ApiModelProperty(value = "告警详情")
20   - private String details;
  21 + @ApiModelProperty(value = "告警详情")
  22 + private String details;
21 23
22 24
23   - @ApiModelProperty(value = "告警开始时间")
24   - private long startTs;
  25 + @ApiModelProperty(value = "告警开始时间")
  26 + private long startTs;
25 27
26   - @ApiModelProperty(value = "告警结束时间")
27   - private long endTs;
  28 + @ApiModelProperty(value = "告警结束时间")
  29 + private long endTs;
28 30
29   - @ApiModelProperty(value = "告警状态")
30   - private String status;
  31 + @ApiModelProperty(value = "告警状态")
  32 + private String status;
31 33
32   - @ApiModelProperty(value = "告警程度")
33   - private String severity;
  34 + @ApiModelProperty(value = "告警程度")
  35 + private String severity;
34 36
35 37
36   -
37   - @ApiModelProperty(value = "告警设备名称")
38   - private String deviceName;
39   - @ApiModelProperty(value = "告警设备ID")
40   - @NotEmpty(message = "设备ID不能为空")
41   - private String deviceId;
  38 + @ApiModelProperty(value = "告警设备名称")
  39 + private String deviceName;
  40 + @ApiModelProperty(value = "告警设备ID")
  41 + @NotEmpty(message = "设备ID不能为空")
  42 + private String deviceId;
42 43 }
... ...
... ... @@ -13,13 +13,10 @@ import org.thingsboard.server.common.data.yunteng.enums.MsgTemplatePurposeEnum;
13 13 import org.thingsboard.server.common.data.yunteng.utils.YtDateTimeUtils;
14 14 import org.thingsboard.server.dao.yunteng.entities.*;
15 15 import org.thingsboard.server.dao.yunteng.mapper.*;
16   -import org.thingsboard.server.dao.yunteng.service.YtNoticeService;
17 16 import org.thingsboard.server.dao.yunteng.service.YtMailService;
  17 +import org.thingsboard.server.dao.yunteng.service.YtNoticeService;
18 18 import org.thingsboard.server.dao.yunteng.service.YtSmsService;
19 19
20   -import java.time.LocalDateTime;
21   -import java.time.OffsetDateTime;
22   -import java.time.format.DateTimeFormatter;
23 20 import java.util.*;
24 21 import java.util.stream.Collectors;
25 22
... ... @@ -47,7 +44,7 @@ public class YtNoticeServiceImpl implements YtNoticeService {
47 44 private final YtMailService mailService;
48 45
49 46 @Override
50   - public void alert(AlarmInfoDTO alarmInfo) {
  47 + public void alert(String profileId, AlarmInfoDTO alarmInfo) {
51 48
52 49 /**
53 50 * 1、查找设备和设备所属组织
... ... @@ -68,11 +65,8 @@ public class YtNoticeServiceImpl implements YtNoticeService {
68 65 .eq(Organization::getId, device.getOrganizationId());
69 66 Organization organization = organizationMapper.selectOne(organizationQueryWrapper);
70 67
71   - QueryWrapper<AlarmProfile> alarmProfileQueryWrapper = new QueryWrapper<AlarmProfile>();
72   - //TODO junlianglee 修改通知
73   -// alarmProfileQueryWrapper.lambda()
74   -// .eq(AlarmProfile::getDeviceProfileId, device.getProfileId());
75   - AlarmProfile alarmProfile = alarmProfileMapper.selectOne(alarmProfileQueryWrapper);
  68 +
  69 + AlarmProfile alarmProfile = alarmProfileMapper.selectById(profileId);
76 70
77 71
78 72 if (alarmProfile == null || alarmProfile.getAlarmContactId().isEmpty() || alarmProfile.getMessageMode().isEmpty()) {
... ... @@ -80,7 +74,7 @@ public class YtNoticeServiceImpl implements YtNoticeService {
80 74 }
81 75 String messageCode = alarmProfile.getMessageMode();
82 76 List<AlarmContact> alarmContactList = alarmContactMapper.selectBatchIds(Arrays.stream(alarmProfile.getAlarmContactId().split(",")).distinct().collect(Collectors.toList()));
83   - noticeAll(messageCode, alarmContactList, alarmInfo, organization,alarmProfile.getTenantId());
  77 + noticeAll(messageCode, alarmContactList, alarmInfo, organization, alarmProfile.getTenantId());
84 78
85 79
86 80 }
... ... @@ -93,7 +87,7 @@ public class YtNoticeServiceImpl implements YtNoticeService {
93 87 * @param alarmInfo 通知内容
94 88 * @param organization 设备所属组织
95 89 */
96   - private void noticeAll(String messageCode, List<AlarmContact> alarmContactList, AlarmInfoDTO alarmInfo, Organization organization,String tenantId) {
  90 + private void noticeAll(String messageCode, List<AlarmContact> alarmContactList, AlarmInfoDTO alarmInfo, Organization organization, String tenantId) {
97 91 Optional.ofNullable(alarmContactList).ifPresent(contacts -> {
98 92
99 93 /**可用的告警通知模板*/
... ... @@ -113,35 +107,36 @@ public class YtNoticeServiceImpl implements YtNoticeService {
113 107
114 108 if (messageCode.contains(MessageTypeEnum.PHONE_MESSAGE.name())
115 109 && templatesMap.containsKey(MessageTypeEnum.PHONE_MESSAGE.name())) {
116   - sms4Alarm(alarmInfo,templatesMap.get(MessageTypeEnum.PHONE_MESSAGE.name()),organization,contacts);
  110 + sms4Alarm(alarmInfo, templatesMap.get(MessageTypeEnum.PHONE_MESSAGE.name()), organization, contacts);
117 111 }
118 112
119 113 if (messageCode.contains(MessageTypeEnum.EMAIL_MESSAGE.name())
120 114 && templatesMap.containsKey(MessageTypeEnum.EMAIL_MESSAGE.name())) {
121   - email4Alarm(alarmInfo,templatesMap.get(MessageTypeEnum.EMAIL_MESSAGE.name()),organization,contacts);
  115 + email4Alarm(alarmInfo, templatesMap.get(MessageTypeEnum.EMAIL_MESSAGE.name()), organization, contacts);
122 116 }
123 117
124 118
125 119 if (messageCode.contains(MessageTypeEnum.DING_TALK_MESSAGE.name())
126 120 && templatesMap.containsKey(MessageTypeEnum.DING_TALK_MESSAGE.name())) {
127   - dingTalk4Alarm(alarmInfo,templatesMap.get(MessageTypeEnum.DING_TALK_MESSAGE.name()),organization,contacts);
  121 + dingTalk4Alarm(alarmInfo, templatesMap.get(MessageTypeEnum.DING_TALK_MESSAGE.name()), organization, contacts);
128 122 }
129 123
130 124 if (messageCode.contains(MessageTypeEnum.WECHAT_MESSAGE.name())
131 125 && templatesMap.containsKey(MessageTypeEnum.WECHAT_MESSAGE.name())) {
132   - weChat4Alarm(alarmInfo,templatesMap.get(MessageTypeEnum.WECHAT_MESSAGE.name()),organization,contacts);
  126 + weChat4Alarm(alarmInfo, templatesMap.get(MessageTypeEnum.WECHAT_MESSAGE.name()), organization, contacts);
133 127 }
134 128 });
135 129 }
136 130
137 131 /**
138 132 * 短信通知设备告警信息
139   - * @param alarmInfo 告警信息
140   - * @param templateId 告警模板主键
141   - * @param organization 设备所属组织
142   - * @param contacts 设备告警联系人
  133 + *
  134 + * @param alarmInfo 告警信息
  135 + * @param templateId 告警模板主键
  136 + * @param organization 设备所属组织
  137 + * @param contacts 设备告警联系人
143 138 */
144   - private void sms4Alarm(AlarmInfoDTO alarmInfo,String templateId, Organization organization,List<AlarmContact> contacts){
  139 + private void sms4Alarm(AlarmInfoDTO alarmInfo, String templateId, Organization organization, List<AlarmContact> contacts) {
145 140 SmsReqDTO info = new SmsReqDTO();
146 141 info.setId(templateId);
147 142 info.setTemplatePurpose(MsgTemplatePurposeEnum.FOR_ALARM_NOTICE.name());
... ... @@ -163,12 +158,13 @@ public class YtNoticeServiceImpl implements YtNoticeService {
163 158
164 159 /**
165 160 * 邮件通知设备告警信息
166   - * @param alarmInfo 告警信息
167   - * @param templateId 告警模板主键
168   - * @param organization 设备所属组织
169   - * @param contacts 设备告警联系人
  161 + *
  162 + * @param alarmInfo 告警信息
  163 + * @param templateId 告警模板主键
  164 + * @param organization 设备所属组织
  165 + * @param contacts 设备告警联系人
170 166 */
171   - private void email4Alarm(AlarmInfoDTO alarmInfo,String templateId, Organization organization,List<AlarmContact> contacts){
  167 + private void email4Alarm(AlarmInfoDTO alarmInfo, String templateId, Organization organization, List<AlarmContact> contacts) {
172 168 List<String> emailReceivers = new ArrayList<>();
173 169 contacts.stream().parallel().forEach(item -> {
174 170 if (!item.getEmail().isEmpty()) {
... ... @@ -178,12 +174,12 @@ public class YtNoticeServiceImpl implements YtNoticeService {
178 174 if (!emailReceivers.isEmpty()) {
179 175 EmailReqDTO info = new EmailReqDTO();
180 176 info.setTo(emailReceivers.toArray(new String[emailReceivers.size()]));
181   - info.setSubject(String.format("【%s】告警通知",alarmInfo.getDeviceName()));
182   - String body =String.format("%s位于【%s】的设备【%s】触发【%s】级的【%s】,请尽快处理!"
183   - ,YtDateTimeUtils.formate(alarmInfo.getCreateTs())
  177 + info.setSubject(String.format("【%s】告警通知", alarmInfo.getDeviceName()));
  178 + String body = String.format("%s位于【%s】的设备【%s】触发【%s】级的【%s】,请尽快处理!"
  179 + , YtDateTimeUtils.formate(alarmInfo.getCreateTs())
184 180 , organization != null ? organization.getName() : ""
185   - ,alarmInfo.getDeviceName()
186   - ,alarmInfo.getSeverity()
  181 + , alarmInfo.getDeviceName()
  182 + , alarmInfo.getSeverity()
187 183 , alarmInfo.getType());
188 184 info.setBody(body);
189 185 info.setEmailFormatEnum(EmailFormatEnum.TEXT.name());
... ... @@ -196,12 +192,13 @@ public class YtNoticeServiceImpl implements YtNoticeService {
196 192
197 193 /**
198 194 * 钉钉通知设备告警信息
199   - * @param alarmInfo 告警信息
200   - * @param templateId 告警模板主键
201   - * @param organization 设备所属组织
202   - * @param contacts 设备告警联系人
  195 + *
  196 + * @param alarmInfo 告警信息
  197 + * @param templateId 告警模板主键
  198 + * @param organization 设备所属组织
  199 + * @param contacts 设备告警联系人
203 200 */
204   - private void dingTalk4Alarm(AlarmInfoDTO alarmInfo,String templateId, Organization organization,List<AlarmContact> contacts){
  201 + private void dingTalk4Alarm(AlarmInfoDTO alarmInfo, String templateId, Organization organization, List<AlarmContact> contacts) {
205 202 // TODO 推送钉钉消息
206 203 SmsReqDTO info = new SmsReqDTO();
207 204 info.setId(templateId);
... ... @@ -224,12 +221,13 @@ public class YtNoticeServiceImpl implements YtNoticeService {
224 221
225 222 /**
226 223 * 微信通知设备告警信息
227   - * @param alarmInfo 告警信息
228   - * @param templateId 告警模板主键
229   - * @param organization 设备所属组织
230   - * @param contacts 设备告警联系人
  224 + *
  225 + * @param alarmInfo 告警信息
  226 + * @param templateId 告警模板主键
  227 + * @param organization 设备所属组织
  228 + * @param contacts 设备告警联系人
231 229 */
232   - private void weChat4Alarm(AlarmInfoDTO alarmInfo,String templateId, Organization organization,List<AlarmContact> contacts){
  230 + private void weChat4Alarm(AlarmInfoDTO alarmInfo, String templateId, Organization organization, List<AlarmContact> contacts) {
233 231 // TODO 推送微信通知
234 232 SmsReqDTO info = new SmsReqDTO();
235 233 info.setId(templateId);
... ...
... ... @@ -18,8 +18,9 @@ public interface YtNoticeService {
18 18 * 设备告警通知负责人
19 19 * * @param alarmInfo
20 20 *
  21 + * @param profileId 告警配置主键
21 22 * @param alarmInfo 告警数据
22 23 */
23   - void alert(AlarmInfoDTO alarmInfo);
  24 + void alert(String profileId, AlarmInfoDTO alarmInfo);
24 25
25 26 }
... ...
... ... @@ -33,15 +33,9 @@ import java.net.InetAddress;
33 33 import static org.thingsboard.common.util.DonAsynchron.withCallback;
34 34
35 35 @Slf4j
36   -@RuleNode(
37   - type = ComponentType.EXTERNAL,
38   - name = "alarm notice",
39   - configClazz = AlarmNoticeNodeConfiguration.class,
40   - nodeDescription = "while device alarm, notice some people.",
41   - nodeDetails = "notice method include sms,email and so on.",
  36 +@RuleNode(type = ComponentType.EXTERNAL, name = "alarm notice", configClazz = AlarmNoticeNodeConfiguration.class, nodeDescription = "while device alarm, notice some people.", nodeDetails = "notice method include sms,email and so on.",
42 37 // configDirective = "tbActionNodeSendSmsConfig",
43   - icon = "sms"
44   -)
  38 + icon = "sms")
45 39 public class AlarmNoticeNode implements TbNode {
46 40
47 41 private AlarmNoticeNodeConfiguration config;
... ... @@ -64,11 +58,11 @@ public class AlarmNoticeNode implements TbNode {
64 58 public void onMsg(TbContext ctx, TbMsg msg) {
65 59 try {
66 60 withCallback(ctx.getSmsExecutor().executeAsync(() -> {
67   - posetApi(ctx, msg);
68   - return null;
69   - }),
70   - ok -> {ctx.tellSuccess(msg);},
71   - fail -> ctx.tellFailure(msg, fail));
  61 + posetApi(ctx, msg);
  62 + return null;
  63 + }), ok -> {
  64 + ctx.tellSuccess(msg);
  65 + }, fail -> ctx.tellFailure(msg, fail));
72 66 } catch (Exception ex) {
73 67 ctx.tellFailure(msg, ex);
74 68 }
... ... @@ -96,7 +90,7 @@ public class AlarmNoticeNode implements TbNode {
96 90 formData.setTenantId(tenantId);
97 91 formData.setSeverity(severity);
98 92
99   - service.alert(formData);
  93 + service.alert(null, formData);
100 94 }
101 95
102 96 @Override
... ...
... ... @@ -9,11 +9,14 @@ import org.apache.commons.lang3.StringUtils;
9 9 import org.jetbrains.annotations.NotNull;
10 10 import org.thingsboard.rule.engine.api.TbContext;
11 11 import org.thingsboard.server.common.data.DataConstants;
  12 +import org.thingsboard.server.common.data.alarm.Alarm;
12 13 import org.thingsboard.server.common.data.device.profile.AlarmCondition;
13 14 import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter;
14 15 import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey;
15 16 import org.thingsboard.server.common.data.device.profile.AlarmRule;
16 17 import org.thingsboard.server.common.data.rule.RuleNodeState;
  18 +import org.thingsboard.server.common.data.yunteng.dto.ActionAlarmDTO;
  19 +import org.thingsboard.server.common.data.yunteng.dto.AlarmInfoDTO;
17 20 import org.thingsboard.server.common.data.yunteng.dto.TriggerDTO;
18 21 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
19 22 import org.thingsboard.server.common.data.yunteng.utils.SpringBeanUtils;
... ... @@ -25,7 +28,9 @@ import org.thingsboard.server.dao.yunteng.entities.DoCondition;
25 28 import org.thingsboard.server.dao.yunteng.service.DoActionService;
26 29 import org.thingsboard.server.dao.yunteng.service.DoConditionService;
27 30 import org.thingsboard.server.dao.yunteng.service.TriggerService;
  31 +import org.thingsboard.server.dao.yunteng.service.YtNoticeService;
28 32
  33 +import java.net.InetAddress;
29 34 import java.util.*;
30 35 import java.util.concurrent.ConcurrentHashMap;
31 36 import java.util.concurrent.ExecutionException;
... ... @@ -64,6 +69,7 @@ class ReactState {
64 69 * 【场景联动的执行集合】懒加载
65 70 */
66 71 private final List<DoAction> actions;
  72 + private final YtNoticeService noticeService;
67 73
68 74
69 75 private RuleNodeState state;
... ... @@ -77,6 +83,7 @@ class ReactState {
77 83 this.conditions = conditionService.getConditions(reactId);
78 84 DoActionService actionService = SpringBeanUtils.getBean(DoActionService.class);
79 85 this.actions = actionService.getActions(reactId);
  86 + this.noticeService = SpringBeanUtils.getBean(YtNoticeService.class);
80 87
81 88 }
82 89
... ... @@ -84,6 +91,7 @@ class ReactState {
84 91 public void process(TbContext ctx, TbMsg msg, String deviceId) throws ExecutionException, InterruptedException {
85 92
86 93
  94 + StringBuilder detail = new StringBuilder();
87 95 if (actions == null) {
88 96 ctx.tellSuccess(msg);
89 97 }
... ... @@ -97,6 +105,7 @@ class ReactState {
97 105 TriggerState triggerState = getOrCreateTriggerState(trigger, deviceId);
98 106 matched = triggerState.process(ctx, msg);
99 107 if (matched) {
  108 + detail.append(triggerState.getAlarmDetails());
100 109 break;
101 110 }
102 111 }
... ... @@ -115,6 +124,8 @@ class ReactState {
115 124 TriggerState conditionState = getOrCreateConditionState(item.getId(), id, item.getTriggerCondition());
116 125 if (conditionState == null
117 126 || conditionState.process(ctx, msg)) {
  127 + detail.append(";");
  128 + detail.append(conditionState.getAlarmDetails());
118 129 matched = true;
119 130 break;
120 131 }
... ... @@ -127,7 +138,7 @@ class ReactState {
127 138
128 139 if (matched) {
129 140 for (DoAction item : actions) {
130   - pushMsg(ctx, msg, item);
  141 + pushMsg(ctx, msg, item,detail.toString());
131 142 }
132 143 } else {
133 144 ctx.tellSuccess(msg);
... ... @@ -169,12 +180,12 @@ class ReactState {
169 180 for (AlarmConditionFilter filter : rule.getCondition().getCondition()) {
170 181 filterKeys.add(filter.getKey());
171 182 }
172   - TriggerState state = new TriggerState(deviceId, rule, filterKeys, null);
  183 + TriggerState state = new TriggerState(deviceId, rule, filterKeys, rule.getAlarmDetails(),null);
173 184
174 185 return state;
175 186 }
176 187
177   - private void pushMsg(TbContext ctx, TbMsg msg, DoAction action) {
  188 + private void pushMsg(TbContext ctx, TbMsg msg, DoAction action,String detail) {
178 189 TbMsgMetaData metaData = //lastMsgMetaData != null ? lastMsgMetaData.copy() :
179 190 new TbMsgMetaData();
180 191 String relationType = "";
... ... @@ -184,19 +195,15 @@ class ReactState {
184 195 rpcMsg(ctx, msg, action.getDeviceId(), action.getDoContext());
185 196 break;
186 197 case SCENE_ACT:
187   - //TODO: 场景联动关联消息通知
  198 + reactMsg(ctx, msg, action);
188 199 break;
189 200 case MSG_NOTIFY:
190   - noticeMsg(ctx, msg, action.getDoContext());
  201 + noticeMsg(ctx, msg, action,detail);
191 202 break;
192 203 default:
193 204 ctx.tellSuccess(msg);
194 205 break;
195 206 }
196   -
197   - if (newMsg != null) {
198   - ctx.tellNext(newMsg, relationType);
199   - }
200 207 }
201 208
202 209 /**
... ... @@ -226,9 +233,32 @@ class ReactState {
226 233 *
227 234 * @param ctx
228 235 * @param msg
229   - * @param context
  236 + * @param action
230 237 */
231   - private void noticeMsg(TbContext ctx, TbMsg msg, JsonNode context) {
  238 + private void noticeMsg(TbContext ctx, TbMsg msg, DoAction action,String detail) {
  239 + Alarm alarm = JacksonUtil.convertValue(msg.getData(), Alarm.class);
  240 + String tenantId = alarm.getTenantId().getId().toString();
  241 + String deviceId = alarm.getOriginator().getId().toString();
  242 + String severity = alarm.getSeverity().name();
  243 + ActionAlarmDTO actionAlarm = JacksonUtil.convertValue(action.getDoContext(),ActionAlarmDTO.class);
  244 +
  245 +
  246 + AlarmInfoDTO formData = new AlarmInfoDTO();
  247 + formData.setDeviceName(msg.getMetaData().getData().get("deviceName"));
  248 + formData.setDetails(detail);
  249 + formData.setType(alarm.getType());
  250 + formData.setCreateTs(alarm.getCreatedTime());
  251 + formData.setStartTs(alarm.getStartTs());
  252 + formData.setEndTs(alarm.getEndTs());
  253 + formData.setStatus(alarm.getStatus().name());
  254 + formData.setDeviceId(deviceId);
  255 + formData.setTenantId(tenantId);
  256 + formData.setSeverity(actionAlarm.getAlarmLevel().name());
  257 + noticeService.alert(action.getAlarmProfileId(),formData);
  258 + }
  259 +
  260 + private void reactMsg(TbContext ctx, TbMsg msg, DoAction action) {
  261 + //TODO: 场景联动关联消息通知
232 262 String lastMsgQueueName = msg.getQueueName();
233 263 TbMsgMetaData metaData = msg.getMetaData();
234 264 metaData.putValue(DataConstants.IS_CLEARED_ALARM, Boolean.TRUE.toString());
... ... @@ -237,7 +267,7 @@ class ReactState {
237 267 , msg.getOriginator()
238 268 , msg != null ? msg.getCustomerId() : null
239 269 , metaData
240   - , JacksonUtil.toString(context));
  270 + , JacksonUtil.toString(action.getDoContext()));
241 271 ctx.tellNext(newMsg, "Message");
242 272 }
243 273 }
... ...
... ... @@ -72,13 +72,15 @@ class TriggerState {
72 72 private DataSnapshot latestValues;
73 73
74 74 private final Set<AlarmConditionFilterKey> entityKeys;
  75 + private final String alarmDetails;
75 76
76   - TriggerState( String originator, AlarmRule rule,Set<AlarmConditionFilterKey> filterKeys,DynamicPredicateValueCtx dynamicPredicateValueCtx) {
  77 + TriggerState(String originator, AlarmRule rule, Set<AlarmConditionFilterKey> filterKeys, String alarmDetails, DynamicPredicateValueCtx dynamicPredicateValueCtx) {
77 78
78 79 this.originator = originator;
79 80 this.dynamicPredicateValueCtx = dynamicPredicateValueCtx;
80   - ruleState = new TriggerRuleState(rule.getCondition(), filterKeys, new PersistedAlarmRuleState(),rule.getSchedule());
  81 + ruleState = new TriggerRuleState(rule.getCondition(), filterKeys, new PersistedAlarmRuleState(), rule.getSchedule());
81 82 this.entityKeys = filterKeys;
  83 + this.alarmDetails = alarmDetails;
82 84 }
83 85
84 86
... ... @@ -88,10 +90,10 @@ class TriggerState {
88 90 }
89 91 lastMsgMetaData = msg.getMetaData();
90 92 SnapshotUpdate update = null;
91   - if(msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())){
92   - update = processTelemetry(ctx,msg);
93   - }else{
94   - update = processAttributes(ctx,msg);
  93 + if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) {
  94 + update = processTelemetry(ctx, msg);
  95 + } else {
  96 + update = processAttributes(ctx, msg);
95 97 }
96 98
97 99 if (update != null && update.hasUpdate()) {
... ... @@ -101,7 +103,6 @@ class TriggerState {
101 103 }
102 104
103 105
104   -
105 106 public boolean process(TbContext ctx, long ts) throws ExecutionException, InterruptedException {
106 107 return createOrClearAlarms(ctx, null, ts, null, (alarmState, tsParam) -> alarmState.eval(tsParam, latestValues));
107 108 }
... ... @@ -142,8 +143,6 @@ class TriggerState {
142 143 }
143 144
144 145
145   -
146   -
147 146 protected void setAlarmConditionMetadata(TriggerRuleState ruleState, TbMsgMetaData metaData) {
148 147 if (ruleState.getSpec().getType() == AlarmConditionSpecType.REPEATING) {
149 148 metaData.putValue(DataConstants.ALARM_CONDITION_REPEATS, String.valueOf(ruleState.getState().getEventCount()));
... ... @@ -154,9 +153,6 @@ class TriggerState {
154 153 }
155 154
156 155
157   -
158   -
159   -
160 156 public void processAckAlarm(Alarm alarm) {
161 157 if (currentAlarm != null && currentAlarm.getId().equals(alarm.getId())) {
162 158 currentAlarm.setStatus(alarm.getStatus());
... ... @@ -165,16 +161,6 @@ class TriggerState {
165 161 }
166 162
167 163
168   -
169   -
170   -
171   -
172   -
173   -
174   -
175   -
176   -
177   -
178 164 protected SnapshotUpdate processAttributes(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException {
179 165 Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(msg.getData()));
180 166 if (!attributes.isEmpty()) {
... ... @@ -188,14 +174,13 @@ class TriggerState {
188 174 for (Map.Entry<Long, List<KvEntry>> entry : tsKvMap.entrySet()) {
189 175 Long ts = entry.getKey();
190 176 List<KvEntry> data = entry.getValue();
191   - return merge( ts, data);
  177 + return merge(ts, data);
192 178 }
193 179
194 180 return null;
195 181 }
196 182
197 183
198   -
199 184 private DataSnapshot fetchLatestValues(TbContext ctx, String originator) throws ExecutionException, InterruptedException {
200 185 DataSnapshot result = new DataSnapshot(entityKeys);
201 186 addEntityKeysToSnapshot(ctx, originator, result);
... ... @@ -254,6 +239,7 @@ class TriggerState {
254 239 addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), new DeviceId(UUID.fromString(originator)), DataConstants.SERVER_SCOPE, attributeKeys).get());
255 240 }
256 241 }
  242 +
257 243 private void addToSnapshot(DataSnapshot snapshot, List<AttributeKvEntry> data) {
258 244 for (AttributeKvEntry entry : data) {
259 245 if (entry.getValue() != null) {
... ... @@ -262,6 +248,7 @@ class TriggerState {
262 248 }
263 249 }
264 250 }
  251 +
265 252 public static EntityKeyValue toEntityValue(KvEntry entry) {
266 253 switch (entry.getDataType()) {
267 254 case STRING:
... ... @@ -278,7 +265,8 @@ class TriggerState {
278 265 throw new RuntimeException("Can't parse entry: " + entry.getDataType());
279 266 }
280 267 }
281   - private SnapshotUpdate merge( Long newTs, List<KvEntry> data) {
  268 +
  269 + private SnapshotUpdate merge(Long newTs, List<KvEntry> data) {
282 270 Set<AlarmConditionFilterKey> keys = new HashSet<>();
283 271 for (KvEntry entry : data) {
284 272 AlarmConditionFilterKey entityKey = new AlarmConditionFilterKey(AlarmConditionKeyType.TIME_SERIES, entry.getKey());
... ...