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