Commit a80b79e0979f661abe6e2eef117b3b691d7b5eb2

Authored by xp.Huang
2 parents 73ee851d edb11b95

Merge branch '20220319' into 'master'

refactor: 场景联动新增关联关系

See merge request huang/thingsboard3.3.2!69
... ... @@ -23,6 +23,6 @@ public class ActionAlarmDTO extends TenantDTO {
23 23 private AlarmSeverity alarmLevel;
24 24
25 25
26   - private AlarmRule clearRule;
  26 + private TriggerDTO clearRule;
27 27
28 28 }
... ...
... ... @@ -3,22 +3,20 @@ package org.thingsboard.server.common.data.yunteng.dto;
3 3 import io.swagger.annotations.ApiModelProperty;
4 4 import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6   -import org.thingsboard.server.common.data.device.profile.AlarmCondition;
7 6 import org.thingsboard.server.common.data.device.profile.AlarmRule;
8   -import org.thingsboard.server.common.data.device.profile.AlarmSchedule;
9 7 import org.thingsboard.server.common.data.yunteng.enums.ScopeEnum;
10 8 import org.thingsboard.server.common.data.yunteng.enums.TriggerTypeEnum;
11 9
12 10 import java.util.List;
13 11
14 12 /**
15   - * @Description 场景联动触发器数据传输表
  13 + * @Description 场景联动触发器数据传输表
16 14 * @Author cxy
17 15 * @Date 2021/11/24 17:32
18 16 */
19 17 @Data
20 18 @EqualsAndHashCode(callSuper = true)
21   -public class TriggerDTO extends TenantDTO{
  19 +public class TriggerDTO extends TenantDTO {
22 20
23 21 @ApiModelProperty(value = "触发器类型")
24 22 private TriggerTypeEnum triggerType;
... ... @@ -31,7 +29,6 @@ public class TriggerDTO extends TenantDTO{
31 29 private AlarmRule triggerCondition;
32 30
33 31
34   -
35 32 @ApiModelProperty(value = "场景联动id")
36 33 private String sceneLinkageId;
37 34
... ...
... ... @@ -31,8 +31,7 @@ import java.util.stream.Collectors;
31 31 */
32 32 @Service
33 33 @RequiredArgsConstructor
34   -public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMapper, SceneLinkage>
35   - implements SceneLinkageService {
  34 +public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMapper, SceneLinkage> implements SceneLinkageService {
36 35
37 36 private final SceneLinkageMapper sceneLinkageMapper;
38 37 private final DeviceMapper deviceMapper;
... ... @@ -43,7 +42,6 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
43 42 private final TriggerService triggerService;
44 43 private final DoConditionService doConditionService;
45 44 private final DoActionService doActionService;
46   - private final UserMapper userMapper;
47 45
48 46 /**
49 47 * 增加场景联动,触发器可以多个,执行条件可以多个,执行动作可以多个
... ... @@ -89,29 +87,15 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
89 87 @Override
90 88 @Transactional
91 89 public void deleteSceneLinkage(Set<String> ids, String tenantId, String currentUserId) {
92   - LambdaQueryWrapper<SceneLinkage> Wrapper =
93   - new QueryWrapper<SceneLinkage>()
94   - .lambda()
95   - .eq(SceneLinkage::getTenantId, tenantId)
96   - .eq(SceneLinkage::getCreator, currentUserId)
97   - .in(SceneLinkage::getId, ids);
  90 + LambdaQueryWrapper<SceneLinkage> Wrapper = new QueryWrapper<SceneLinkage>().lambda().eq(SceneLinkage::getTenantId, tenantId).eq(SceneLinkage::getCreator, currentUserId).in(SceneLinkage::getId, ids);
98 91 int result = sceneLinkageMapper.delete(Wrapper);
99 92 if (result != ids.size()) {
100 93 throw new YtDataValidationException("存在非当前用户创建的场景联动");
101 94 }
102 95 // 删除场景,一并删除数据库触发器,执行条件,执行动作的数据
103   - triggerMapper.delete(
104   - new LambdaQueryWrapper<Trigger>()
105   - .eq(Trigger::getTenantId, tenantId)
106   - .in(Trigger::getSceneLinkageId, ids));
107   - doConditionMapper.delete(
108   - new LambdaQueryWrapper<DoCondition>()
109   - .eq(DoCondition::getTenantId, tenantId)
110   - .in(DoCondition::getSceneLinkageId, ids));
111   - doActionMapper.delete(
112   - new LambdaQueryWrapper<DoAction>()
113   - .eq(DoAction::getTenantId, tenantId)
114   - .in(DoAction::getSceneLinkageId, ids));
  96 + triggerMapper.delete(new LambdaQueryWrapper<Trigger>().eq(Trigger::getTenantId, tenantId).in(Trigger::getSceneLinkageId, ids));
  97 + doConditionMapper.delete(new LambdaQueryWrapper<DoCondition>().eq(DoCondition::getTenantId, tenantId).in(DoCondition::getSceneLinkageId, ids));
  98 + doActionMapper.delete(new LambdaQueryWrapper<DoAction>().eq(DoAction::getTenantId, tenantId).in(DoAction::getSceneLinkageId, ids));
115 99 }
116 100
117 101 /**
... ... @@ -180,22 +164,16 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
180 164 }
181 165
182 166 // 先删除触发器
183   - triggerMapper.delete(
184   - new QueryWrapper<Trigger>()
185   - .lambda()
186   - .eq(StringUtils.isNoneBlank(sceneLinkage.getId()), Trigger::getSceneLinkageId, sceneLinkage.getId()));
  167 + triggerMapper.delete(new QueryWrapper<Trigger>().lambda().eq(StringUtils.isNoneBlank(sceneLinkage.getId()), Trigger::getSceneLinkageId, sceneLinkage.getId()));
187 168
188 169
189 170 // 如果获取的触发器不为空,进行添加操作
190   - if(triggerDTOS != null && !triggerDTOS.isEmpty()){
191   - List<Trigger> triggers =
192   - triggerDTOS.stream()
193   - .map(triggerDTO -> {
194   - triggerDTO.setTenantId(sceneLinkage.getTenantId());
195   - triggerDTO.setSceneLinkageId(sceneLinkage.getId());
196   - return triggerDTO.getEntity(Trigger.class);
197   - })
198   - .collect(Collectors.toList());
  171 + if (triggerDTOS != null && !triggerDTOS.isEmpty()) {
  172 + List<Trigger> triggers = triggerDTOS.stream().map(triggerDTO -> {
  173 + triggerDTO.setTenantId(sceneLinkage.getTenantId());
  174 + triggerDTO.setSceneLinkageId(sceneLinkage.getId());
  175 + return triggerDTO.getEntity(Trigger.class);
  176 + }).collect(Collectors.toList());
199 177 triggerService.insertBatch(triggers, 1000);
200 178 }
201 179 }
... ... @@ -228,26 +206,20 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
228 206 }
229 207 }
230 208
231   - doActionMapper.delete(
232   - new QueryWrapper<DoAction>()
233   - .lambda()
234   - .eq(StringUtils.isNoneBlank(sceneLinkageDTO.getId()), DoAction::getSceneLinkageId, sceneLinkageDTO.getId()));
  209 + doActionMapper.delete(new QueryWrapper<DoAction>().lambda().eq(StringUtils.isNoneBlank(sceneLinkageDTO.getId()), DoAction::getSceneLinkageId, sceneLinkageDTO.getId()));
235 210
236 211 if (actionDTOS != null && !actionDTOS.isEmpty()) {
237   - List<DoAction> collectA =
238   - actionDTOS.stream()
239   - .map(doActionDTO -> {
240   - doActionDTO.setTenantId(sceneLinkageDTO.getTenantId());
241   - doActionDTO.setSceneLinkageId(sceneLinkageDTO.getId());
242   - if (ActionTypeEnum.DEVICE_OUT.equals(doActionDTO.getOutTarget())) {
243   - ObjectNode doContext = JacksonUtil.newObjectNode();
244   - doContext.put("method", "methodThingskit");
245   - doContext.put("params", doActionDTO.getDoContext());
246   - doActionDTO.setDoContext(doContext);
247   - }
248   - return doActionDTO.getEntity(DoAction.class);
249   - })
250   - .collect(Collectors.toList());
  212 + List<DoAction> collectA = actionDTOS.stream().map(doActionDTO -> {
  213 + doActionDTO.setTenantId(sceneLinkageDTO.getTenantId());
  214 + doActionDTO.setSceneLinkageId(sceneLinkageDTO.getId());
  215 + if (ActionTypeEnum.DEVICE_OUT.equals(doActionDTO.getOutTarget())) {
  216 + ObjectNode doContext = JacksonUtil.newObjectNode();
  217 + doContext.put("method", "methodThingskit");
  218 + doContext.put("params", doActionDTO.getDoContext());
  219 + doActionDTO.setDoContext(doContext);
  220 + }
  221 + return doActionDTO.getEntity(DoAction.class);
  222 + }).collect(Collectors.toList());
251 223 doActionService.insertBatch(collectA, 1000);
252 224
253 225 }
... ... @@ -283,24 +255,17 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
283 255 }
284 256 }
285 257
286   - doConditionMapper.delete(
287   - new QueryWrapper<DoCondition>()
288   - .lambda()
289   - .eq(StringUtils.isNoneBlank(sceneLinkageDTO.getId()), DoCondition::getSceneLinkageId, sceneLinkageDTO.getId()));
  258 + doConditionMapper.delete(new QueryWrapper<DoCondition>().lambda().eq(StringUtils.isNoneBlank(sceneLinkageDTO.getId()), DoCondition::getSceneLinkageId, sceneLinkageDTO.getId()));
290 259
291 260
292 261 // 4.批量新增执行条件
293 262 if (conditionDTOS != null && !conditionDTOS.isEmpty()) {
294   - List<DoCondition> collectC =
295   - conditionDTOS.stream()
296   - .map(doConditionDTO -> {
297   -
298   - doConditionDTO.setTenantId(sceneLinkageDTO.getTenantId());
299   - doConditionDTO.setSceneLinkageId(sceneLinkageDTO.getId());
300   - return doConditionDTO.getEntity(DoCondition.class);
301   - }
302   - )
303   - .collect(Collectors.toList());
  263 + List<DoCondition> collectC = conditionDTOS.stream().map(doConditionDTO -> {
  264 +
  265 + doConditionDTO.setTenantId(sceneLinkageDTO.getTenantId());
  266 + doConditionDTO.setSceneLinkageId(sceneLinkageDTO.getId());
  267 + return doConditionDTO.getEntity(DoCondition.class);
  268 + }).collect(Collectors.toList());
304 269 doConditionService.insertBatch(collectC, 1000);
305 270
306 271 }
... ... @@ -334,14 +299,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
334 299 */
335 300 @Override
336 301 public List<SceneLinkageDTO> findSceneLinkage(SceneLinkageDTO sceneLinkageDTO, String tenantId) {
337   - List<SceneLinkage> scenelinkageList =
338   - baseMapper.selectList(
339   - new QueryWrapper<SceneLinkage>()
340   - .lambda()
341   - .eq(SceneLinkage::getTenantId, tenantId)
342   - .like(SceneLinkage::getName, sceneLinkageDTO.getName())
343   - .like(SceneLinkage::getOrganizationId, sceneLinkageDTO.getOrganizationId())
344   - .like(SceneLinkage::getStatus, sceneLinkageDTO.getStatus()));
  302 + List<SceneLinkage> scenelinkageList = baseMapper.selectList(new QueryWrapper<SceneLinkage>().lambda().eq(SceneLinkage::getTenantId, tenantId).like(SceneLinkage::getName, sceneLinkageDTO.getName()).like(SceneLinkage::getOrganizationId, sceneLinkageDTO.getOrganizationId()).like(SceneLinkage::getStatus, sceneLinkageDTO.getStatus()));
345 303 return ReflectUtils.sourceToTarget(scenelinkageList, SceneLinkageDTO.class);
346 304 }
347 305
... ... @@ -354,17 +312,10 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
354 312 @Override
355 313 @Transactional(rollbackFor = Exception.class)
356 314 public void updateSceneStatus(String sceneLinkageId, int status, String tenantId) {
357   - Optional.ofNullable(
358   - baseMapper.selectOne(
359   - new QueryWrapper<SceneLinkage>()
360   - .lambda()
361   - .eq(SceneLinkage::getId, sceneLinkageId)
362   - .eq(SceneLinkage::getTenantId, tenantId)))
363   - .ifPresent(
364   - sceneLinkage -> {
365   - sceneLinkage.setStatus(status);
366   - baseMapper.updateById(sceneLinkage);
367   - });
  315 + Optional.ofNullable(baseMapper.selectOne(new QueryWrapper<SceneLinkage>().lambda().eq(SceneLinkage::getId, sceneLinkageId).eq(SceneLinkage::getTenantId, tenantId))).ifPresent(sceneLinkage -> {
  316 + sceneLinkage.setStatus(status);
  317 + baseMapper.updateById(sceneLinkage);
  318 + });
368 319 }
369 320
370 321 /**
... ... @@ -374,32 +325,23 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
374 325 * @return 设备集合
375 326 */
376 327 @Override
377   - public List<DeviceDTO> findDeviceList(
378   - String organizationId, String tenantId, String customerId) {
  328 + public List<DeviceDTO> findDeviceList(String organizationId, String tenantId, String customerId) {
379 329 List<String> organizationFilter = new ArrayList<>();
380 330 organizationFilter.add(organizationId);
381 331 // 查询该组织的所有子类
382   - List<String> orgIds =
383   - organizationMapper.findOrganizationTreeList(tenantId, organizationFilter).stream()
384   - .map(organization -> organization.getId())
385   - .collect(Collectors.toList());
  332 + List<String> orgIds = organizationMapper.findOrganizationTreeList(tenantId, organizationFilter).stream().map(organization -> organization.getId()).collect(Collectors.toList());
386 333 // 拿到当前组织ids所包含的设备集合
387 334 if (orgIds.isEmpty()) {
388 335 throw new YtDataValidationException(ErrorMessage.ORGANIZATION_NOT_EXTIED.getMessage());
389 336 }
390   - List<YtDevice> orgDevices =
391   - deviceMapper.selectList(
392   - new QueryWrapper<YtDevice>().lambda().in(YtDevice::getOrganizationId, orgIds));
  337 + List<YtDevice> orgDevices = deviceMapper.selectList(new QueryWrapper<YtDevice>().lambda().in(YtDevice::getOrganizationId, orgIds));
393 338
394 339
395 340 List<String> customerDevices = deviceMapper.findDeviceIdsByCustomerId(customerId);
396 341 if (customerDevices == null || customerDevices.isEmpty()) {
397 342 return null;
398 343 }
399   - List<DeviceDTO> result = orgDevices.stream()
400   - .filter(f -> customerDevices.contains(f.getTbDeviceId()))
401   - .map(device -> device.getDTO(DeviceDTO.class))
402   - .collect(Collectors.toList());
  344 + List<DeviceDTO> result = orgDevices.stream().filter(f -> customerDevices.contains(f.getTbDeviceId())).map(device -> device.getDTO(DeviceDTO.class)).collect(Collectors.toList());
403 345
404 346
405 347 return result;
... ... @@ -416,29 +358,26 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
416 358 */
417 359 @Override
418 360 public JsonNode getRuleNodeConfig(String currentSceneId, String tenantId, String customerId, Integer state) {
419   - String ruleTyp = "org.thingsboard.rule.engine.filter.TbSceneReactNode";
420   - List<SceneLinkage> runningScenes = baseMapper.selectList(
421   - new QueryWrapper<SceneLinkage>()
422   - .lambda()
423   - .eq(SceneLinkage::getTenantId, tenantId)
424   - .eq(SceneLinkage::getStatus, FastIotConstants.StateValue.ENABLE)
425   - );
  361 + List<SceneLinkage> runningScenes = baseMapper.selectList(new QueryWrapper<SceneLinkage>().lambda().eq(SceneLinkage::getTenantId, tenantId).eq(SceneLinkage::getStatus, FastIotConstants.StateValue.ENABLE));
426 362 Set<String> enableIds = new HashSet<>();
427 363 Map<String, String> sceneInform = new HashMap<>();
428 364 for (SceneLinkage item : runningScenes) {
429 365 enableIds.add(item.getId());
430   - sceneInform.put(item.getId(),item.getName());
  366 + sceneInform.put(item.getId(), item.getName());
431 367 }
432   - enableIds.add(currentSceneId);
  368 + SceneLinkage self = baseMapper.selectById(currentSceneId);
433 369 if (state == FastIotConstants.StateValue.DISABLE) {
434 370 enableIds.remove(currentSceneId);
  371 + sceneInform.remove(currentSceneId);
  372 + } else {
  373 + enableIds.add(currentSceneId);
  374 + sceneInform.put(currentSceneId, self.getName());
435 375 }
436 376
437 377 if (enableIds.size() <= 0) {
438 378 return null;
439 379 }
440 380
441   - SceneLinkage self = baseMapper.selectById(currentSceneId);
442 381 List<DeviceDTO> organizationDevices = findDeviceList(self.getOrganizationId(), tenantId, customerId);
443 382 List<String> allDevices = new ArrayList<>();
444 383 for (DeviceDTO item : organizationDevices) {
... ... @@ -448,40 +387,34 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
448 387
449 388 Map<String, List<String>> matchedDevices = new HashMap<>();
450 389
451   - List<Trigger> triggers = triggerMapper.selectList(
452   - new QueryWrapper<Trigger>()
453   - .lambda()
454   - .eq(Trigger::getTenantId, tenantId)
455   - .eq(Trigger::getTriggerType, TriggerTypeEnum.DEVICE_TRIGGER)
456   - .in(Trigger::getSceneLinkageId, enableIds)
457   - );
  390 + List<Trigger> triggers = triggerMapper.selectList(new QueryWrapper<Trigger>().lambda().eq(Trigger::getTenantId, tenantId).eq(Trigger::getTriggerType, TriggerTypeEnum.DEVICE_TRIGGER).in(Trigger::getSceneLinkageId, enableIds));
458 391
459 392
460   - triggers.forEach(trigger ->{
  393 + triggers.forEach(trigger -> {
461 394 String scenId = trigger.getSceneLinkageId();
462 395 List<String> devices = trigger.getEntityId();
463   - if(ScopeEnum.ALL.equals(trigger)){
  396 + if (ScopeEnum.ALL.equals(trigger.getEntityType()) && currentSceneId.equals(scenId)) {
464 397 trigger.setEntityId(allDevices);
465 398 triggerMapper.updateById(trigger);
466 399 devices = allDevices;
467 400 }
468   - deviceSceneMap(matchedDevices,devices , scenId);
  401 + deviceSceneMap(matchedDevices, devices, scenId);
469 402 });
470 403
471   - List<DoCondition> conditions = doConditionMapper.selectList(new QueryWrapper<DoCondition>().lambda()
472   - .eq(DoCondition::getSceneLinkageId, currentSceneId)
473   - .eq(DoCondition::getEntityType,ScopeEnum.ALL));
  404 + List<DoCondition> conditions = doConditionMapper.selectList(new QueryWrapper<DoCondition>().lambda().eq(DoCondition::getSceneLinkageId, currentSceneId).eq(DoCondition::getEntityType, ScopeEnum.ALL));
474 405 conditions.forEach(item -> {
475   - item.setEntityId(allDevices);
476   - doConditionMapper.updateById(item);
  406 + if (currentSceneId.equals(item.getSceneLinkageId())) {
  407 + item.setEntityId(allDevices);
  408 + doConditionMapper.updateById(item);
  409 + }
477 410 });
478 411
479   - List<DoAction> actions = doActionMapper.selectList(new QueryWrapper<DoAction>().lambda()
480   - .eq(DoAction::getSceneLinkageId, currentSceneId)
481   - .eq(DoAction::getEntityType,ScopeEnum.ALL));
  412 + List<DoAction> actions = doActionMapper.selectList(new QueryWrapper<DoAction>().lambda().eq(DoAction::getSceneLinkageId, currentSceneId).eq(DoAction::getEntityType, ScopeEnum.ALL));
482 413 actions.forEach(item -> {
483   - item.setDeviceId(allDevices);
484   - doActionMapper.updateById(item);
  414 + if (currentSceneId.equals(item.getSceneLinkageId())) {
  415 + item.setDeviceId(allDevices);
  416 + doActionMapper.updateById(item);
  417 + }
485 418 });
486 419
487 420 if (matchedDevices.isEmpty()) {
... ... @@ -493,8 +426,6 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
493 426 engineConfig.put("names", sceneInform);
494 427
495 428
496   -
497   -
498 429 return JacksonUtil.convertValue(engineConfig, JsonNode.class);
499 430 }
500 431
... ... @@ -521,8 +452,7 @@ public class SceneLinkageServiceImpl extends AbstractBaseService<SceneLinkageMap
521 452
522 453 private List<String> getQueryOrganizationIds(String tenantId, List<String> organizationIds) {
523 454 // 查询该组织的所有子类
524   - List<OrganizationDTO> organizationDTOS =
525   - organizationMapper.findOrganizationTreeList(tenantId, organizationIds);
  455 + List<OrganizationDTO> organizationDTOS = organizationMapper.findOrganizationTreeList(tenantId, organizationIds);
526 456 // 遍历组织id
527 457 List<String> queryOrganizationIds = new ArrayList<>();
528 458 organizationDTOS.forEach(item -> queryOrganizationIds.add(item.getId()));
... ...
... ... @@ -5,25 +5,18 @@ package org.thingsboard.rule.engine.yunteng.scene;
5 5
6 6 import com.fasterxml.jackson.databind.JsonNode;
7 7 import com.fasterxml.jackson.databind.node.ObjectNode;
8   -import com.google.common.util.concurrent.ListenableFuture;
9 8 import lombok.extern.slf4j.Slf4j;
10   -import org.apache.commons.lang3.StringUtils;
11 9 import org.jetbrains.annotations.NotNull;
12   -import org.thingsboard.common.util.DonAsynchron;
13   -import org.thingsboard.rule.engine.action.TbAlarmResult;
14 10 import org.thingsboard.rule.engine.api.TbContext;
15 11 import org.thingsboard.server.common.data.DataConstants;
16 12 import org.thingsboard.server.common.data.alarm.Alarm;
17 13 import org.thingsboard.server.common.data.alarm.AlarmStatus;
18   -import org.thingsboard.server.common.data.device.profile.AlarmCondition;
19 14 import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter;
20 15 import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey;
21 16 import org.thingsboard.server.common.data.device.profile.AlarmRule;
22 17 import org.thingsboard.server.common.data.id.DeviceId;
23   -import org.thingsboard.server.common.data.rule.RuleNodeState;
24 18 import org.thingsboard.server.common.data.yunteng.dto.ActionAlarmDTO;
25 19 import org.thingsboard.server.common.data.yunteng.dto.AlarmInfoDTO;
26   -import org.thingsboard.server.common.data.yunteng.dto.DoActionDTO;
27 20 import org.thingsboard.server.common.data.yunteng.dto.TriggerDTO;
28 21 import org.thingsboard.server.common.data.yunteng.enums.ActionTypeEnum;
29 22 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
... ... @@ -31,13 +24,14 @@ import org.thingsboard.server.common.data.yunteng.utils.SpringBeanUtils;
31 24 import org.thingsboard.server.common.msg.TbMsg;
32 25 import org.thingsboard.server.common.msg.TbMsgMetaData;
33 26 import org.thingsboard.server.common.msg.queue.ServiceQueue;
34   -import org.thingsboard.server.dao.alarm.AlarmOperationResult;
35 27 import org.thingsboard.server.dao.yunteng.entities.DoAction;
36 28 import org.thingsboard.server.dao.yunteng.entities.DoCondition;
37 29 import org.thingsboard.server.dao.yunteng.service.*;
38 30
39   -import java.net.InetAddress;
40   -import java.util.*;
  31 +import java.util.HashSet;
  32 +import java.util.List;
  33 +import java.util.Set;
  34 +import java.util.UUID;
41 35 import java.util.concurrent.ConcurrentHashMap;
42 36 import java.util.concurrent.ExecutionException;
43 37
... ... @@ -68,7 +62,7 @@ class ReactState {
68 62 * 键:设备ID为键
69 63 * 值:设备最新告警信息
70 64 */
71   - private ConcurrentHashMap<String, Alarm> currentAlarms;
  65 + private ConcurrentHashMap<String, Alarm> currentAlarms = new ConcurrentHashMap<>();
72 66
73 67 /**
74 68 * 场景联动的执行条件状态
... ... @@ -92,7 +86,6 @@ class ReactState {
92 86 private YtDeviceService ytDeviceService;
93 87
94 88
95   -
96 89 ReactState(String reactId, TbContext ctx, TbSceneReactNodeConfig config) {
97 90 this.reactId = reactId;
98 91 this.reactName = config.getNames().get(reactId);
... ... @@ -102,9 +95,9 @@ class ReactState {
102 95 this.conditions = conditionService.getConditions(reactId);
103 96 DoActionService actionService = SpringBeanUtils.getBean(DoActionService.class);
104 97 this.actions = actionService.getActions(reactId);
105   - for(DoAction action: actions){
  98 + for (DoAction action : actions) {
106 99 /**动作中只有1个告警通知*/
107   - if(ActionTypeEnum.MSG_NOTIFY.equals(action.getOutTarget())){
  100 + if (ActionTypeEnum.MSG_NOTIFY.equals(action.getOutTarget())) {
108 101 this.alarmAction = action;
109 102 break;
110 103 }
... ... @@ -132,10 +125,10 @@ class ReactState {
132 125 matched = triggerState.process(ctx, msg);
133 126 if (matched) {
134 127 detail.append(triggerState.getAlarmDetails());
135   - if(this.alarmAction != null){
136   - noticeMsg(ctx, msg, alarmAction,deviceId,triggerState.getAlarmDetails(),triggerState.getLatestValues().getTs());
  128 + if (this.alarmAction != null) {
  129 + noticeMsg(ctx, msg, alarmAction, deviceId, triggerState.getAlarmDetails(), triggerState.getLatestValues().getTs());
137 130 }
138   - }else if(currentAlarms.containsKey(deviceId) && this.alarmAction != null){
  131 + } else if (currentAlarms.containsKey(deviceId) && this.alarmAction != null) {
139 132 //清除设备告警
140 133 clearAlarm(ctx, msg, deviceId);
141 134 }
... ... @@ -169,10 +162,10 @@ class ReactState {
169 162
170 163 if (matched) {
171 164 for (DoAction item : actions) {
172   - if(ActionTypeEnum.MSG_NOTIFY.equals(item.getOutTarget())){
  165 + if (ActionTypeEnum.MSG_NOTIFY.equals(item.getOutTarget())) {
173 166 continue;
174 167 }
175   - pushMsg(ctx, msg, item,detail.toString());
  168 + pushMsg(ctx, msg, item, detail.toString());
176 169 }
177 170 } else {
178 171 ctx.tellSuccess(msg);
... ... @@ -201,9 +194,9 @@ class ReactState {
201 194 return triggerState.get(deviceId);
202 195 }
203 196 if (alarmAction.getDeviceId().contains(deviceId)) {
204   - ActionAlarmDTO alarm = JacksonUtil.convertValue(alarmAction.getDoContext(),ActionAlarmDTO.class);
205   - if(alarm != null && alarm.getClearRule()!=null){
206   - TriggerState state = createTriggerState(deviceId, alarm.getClearRule());
  197 + ActionAlarmDTO alarm = JacksonUtil.convertValue(alarmAction.getDoContext(), ActionAlarmDTO.class);
  198 + if (alarm != null && alarm.getClearRule() != null) {
  199 + TriggerState state = createTriggerState(deviceId, alarm.getClearRule().getTriggerCondition());
207 200 triggerState.put(deviceId, state);
208 201 return state;
209 202 }
... ... @@ -230,12 +223,12 @@ class ReactState {
230 223 for (AlarmConditionFilter filter : rule.getCondition().getCondition()) {
231 224 filterKeys.add(filter.getKey());
232 225 }
233   - TriggerState state = new TriggerState(deviceId, rule, filterKeys, rule.getAlarmDetails(),null);
  226 + TriggerState state = new TriggerState(deviceId, rule, filterKeys, rule.getAlarmDetails(), null);
234 227
235 228 return state;
236 229 }
237 230
238   - private void pushMsg(TbContext ctx, TbMsg msg, DoAction action,String detail) {
  231 + private void pushMsg(TbContext ctx, TbMsg msg, DoAction action, String detail) {
239 232 TbMsgMetaData metaData = //lastMsgMetaData != null ? lastMsgMetaData.copy() :
240 233 new TbMsgMetaData();
241 234 String relationType = "";
... ... @@ -282,10 +275,10 @@ class ReactState {
282 275 * @param msg
283 276 * @param action
284 277 */
285   - private void noticeMsg(TbContext ctx, TbMsg msg, DoAction action,String deviceId,String detailStr,long startTs) {
  278 + private void noticeMsg(TbContext ctx, TbMsg msg, DoAction action, String deviceId, String detailStr, long startTs) {
286 279
287 280 DeviceId entityId = new DeviceId(UUID.fromString(deviceId));
288   - ActionAlarmDTO actionAlarm = JacksonUtil.convertValue(action.getDoContext(),ActionAlarmDTO.class);
  281 + ActionAlarmDTO actionAlarm = JacksonUtil.convertValue(action.getDoContext(), ActionAlarmDTO.class);
289 282
290 283
291 284 Alarm currentAlarm = new Alarm();
... ... @@ -298,8 +291,8 @@ class ReactState {
298 291 currentAlarm.setStartTs(startTs);
299 292 currentAlarm.setEndTs(currentAlarm.getStartTs());
300 293 ObjectNode detailData = JacksonUtil.newObjectNode();
301   - detailData.put("msg",detailStr);
302   - detailData.put("data",JacksonUtil.toJsonNode(msg.getData()));
  294 + detailData.put("msg", detailStr);
  295 + detailData.put("data", JacksonUtil.toJsonNode(msg.getData()));
303 296 currentAlarm.setDetails(detailData);
304 297 currentAlarm.setOriginator(entityId);
305 298 currentAlarm.setTenantId(ctx.getTenantId());
... ... @@ -307,9 +300,8 @@ class ReactState {
307 300
308 301 currentAlarm = ctx.getAlarmService().createOrUpdateAlarm(currentAlarm);
309 302 ytDeviceService.freshAlarmStatus(entityId, 1);
310   - currentAlarms.put(deviceId,currentAlarm);
311   -
312   -
  303 + currentAlarms.put(deviceId, currentAlarm);
  304 + alarmMsg(ctx, msg, currentAlarm, "Alarm Cleared");
313 305
314 306 AlarmInfoDTO formData = new AlarmInfoDTO();
315 307 formData.setDeviceName(msg.getMetaData().getData().get("deviceName"));
... ... @@ -322,18 +314,28 @@ class ReactState {
322 314 formData.setDeviceId(deviceId);
323 315 formData.setTenantId(currentAlarm.getTenantId().getId().toString());
324 316 formData.setSeverity(actionAlarm.getAlarmLevel().name());
325   - noticeService.alert(action.getAlarmProfileId(),formData);
  317 + noticeService.alert(action.getAlarmProfileId(), formData);
326 318 }
327 319
328   - private void clearAlarm(TbContext ctx, TbMsg msg,String deviceId) throws ExecutionException, InterruptedException {
329   - TriggerState clearStete = getOrCreateClearState(deviceId);
330   - if(clearStete.process(ctx, msg)){
  320 + private void clearAlarm(TbContext ctx, TbMsg msg, String deviceId) throws ExecutionException, InterruptedException {
  321 + TriggerState clearState = getOrCreateClearState(deviceId);
  322 + if (clearState.process(ctx, msg)) {
331 323 ctx.getAlarmService().clearAlarmForResult(ctx.getTenantId(), currentAlarms.get(deviceId).getId(), null, System.currentTimeMillis());
332 324 ytDeviceService.freshAlarmStatus(new DeviceId(UUID.fromString(deviceId)), 0);
  325 + alarmMsg(ctx, msg, currentAlarms.get(deviceId), "Alarm Cleared");
333 326 currentAlarms.remove(deviceId);
334 327 }
335 328 }
336 329
  330 + private void alarmMsg(TbContext ctx, TbMsg msg,Alarm alarm,String releationType) {
  331 + String lastMsgQueueName = msg.getQueueName();
  332 + TbMsgMetaData metaData = msg.getMetaData();
  333 + String data = JacksonUtil.valueToTree(alarm).toString();
  334 + TbMsg newMsg = ctx.newMsg(lastMsgQueueName != null ? lastMsgQueueName : ServiceQueue.MAIN, "ALARM",
  335 + alarm.getOriginator(), msg != null ? msg.getCustomerId() : null, metaData, data);
  336 + ctx.enqueueForTellNext(newMsg, releationType);
  337 + }
  338 +
337 339
338 340 private void reactMsg(TbContext ctx, TbMsg msg, DoAction action) {
339 341 //TODO: 场景联动关联消息通知
... ...
... ... @@ -42,7 +42,7 @@ import java.util.concurrent.ExecutionException;
42 42 type = ComponentType.FILTER,
43 43 name = "scene react",
44 44 configClazz = TbCheckAlarmStatusNodeConfig.class,
45   - relationTypes = {"Message", "RPC Request"},
  45 + relationTypes = {"Message","Alarm Created", "Alarm Updated", "RPC Request"},
46 46 nodeDescription = "基于业务场景,实现设备的交互控制。",
47 47 nodeDetails = "基于业务场景,实现设备的交互控制。",
48 48 uiResources = {"static/rulenode/rulenode-core-config.js"},
... ...