Commit 1afb808cafe7133503efc58d1ae1847c069e5a9c

Authored by 云中非
1 parent 13530c95

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

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