Showing
8 changed files
with
132 additions
and
124 deletions
@@ -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()); |