Commit a71d5b7ee4627e843ad0c8687c69b037468c8e93
Merge branch '20220317' into 'master'
refactor: 动作之设备输出 See merge request huang/thingsboard3.3.2!66
Showing
17 changed files
with
424 additions
and
395 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 | ... | ... |
... | ... | @@ -47,221 +47,220 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. |
47 | 47 | @RequestMapping("api/yt/convert") |
48 | 48 | @Api(tags = {"数据流转控制器"}) |
49 | 49 | public class YtConvertDataToController extends BaseController { |
50 | - private final YtRuleChainService ytRuleChainService; | |
50 | + private final YtRuleChainService ytRuleChainService; | |
51 | 51 | |
52 | - @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}") | |
53 | - private boolean debugPerTenantEnabled; | |
52 | + @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}") | |
53 | + private boolean debugPerTenantEnabled; | |
54 | 54 | |
55 | - @Autowired(required = false) | |
56 | - private ActorSystemContext actorContext; | |
55 | + @Autowired(required = false) | |
56 | + private ActorSystemContext actorContext; | |
57 | 57 | |
58 | - private final ConvertConfigService convertConfigService; | |
59 | - private final SceneLinkageService sceneLinkageService; | |
58 | + private final ConvertConfigService convertConfigService; | |
59 | + private final SceneLinkageService sceneLinkageService; | |
60 | 60 | |
61 | - @GetMapping(params = {PAGE_SIZE, PAGE}) | |
62 | - @ApiOperation("分页查询") | |
63 | - public YtPageData<ConvertConfigDTO> pageMessageConfig( | |
64 | - @RequestParam(PAGE_SIZE) int pageSize, | |
65 | - @RequestParam(PAGE) int page, | |
66 | - @ApiParam(value = "0:转换脚本 1:数据流转") @RequestParam(value = "nodeType") Integer nodeType, | |
67 | - @RequestParam(value = "name", required = false) String name, | |
68 | - @RequestParam(value = "status", required = false) Integer status, | |
69 | - @RequestParam(value = ORDER_FILED, required = false) String orderBy, | |
70 | - @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) | |
71 | - throws ThingsboardException { | |
61 | + @GetMapping(params = {PAGE_SIZE, PAGE}) | |
62 | + @ApiOperation("分页查询") | |
63 | + public YtPageData<ConvertConfigDTO> pageMessageConfig( | |
64 | + @RequestParam(PAGE_SIZE) int pageSize, | |
65 | + @RequestParam(PAGE) int page, | |
66 | + @ApiParam(value = "0:转换脚本 1:数据流转") @RequestParam(value = "nodeType") Integer nodeType, | |
67 | + @RequestParam(value = "name", required = false) String name, | |
68 | + @RequestParam(value = "status", required = false) Integer status, | |
69 | + @RequestParam(value = ORDER_FILED, required = false) String orderBy, | |
70 | + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) | |
71 | + throws ThingsboardException { | |
72 | 72 | |
73 | - HashMap<String, Object> queryMap = new HashMap<>(); | |
74 | - queryMap.put(PAGE_SIZE, pageSize); | |
75 | - queryMap.put(PAGE, page); | |
76 | - queryMap.put(ORDER_FILED, orderBy); | |
77 | - queryMap.put("nodeType", nodeType); | |
78 | - queryMap.put("name", name); | |
79 | - queryMap.put("status", status); | |
80 | - if (orderType != null) { | |
81 | - queryMap.put(ORDER_TYPE, orderType.name()); | |
73 | + HashMap<String, Object> queryMap = new HashMap<>(); | |
74 | + queryMap.put(PAGE_SIZE, pageSize); | |
75 | + queryMap.put(PAGE, page); | |
76 | + queryMap.put(ORDER_FILED, orderBy); | |
77 | + queryMap.put("nodeType", nodeType); | |
78 | + queryMap.put("name", name); | |
79 | + queryMap.put("status", status); | |
80 | + if (orderType != null) { | |
81 | + queryMap.put(ORDER_TYPE, orderType.name()); | |
82 | + } | |
83 | + return convertConfigService.page(getCurrentUser().getCurrentTenantId(), queryMap); | |
82 | 84 | } |
83 | - return convertConfigService.page(getCurrentUser().getCurrentTenantId(), queryMap); | |
84 | - } | |
85 | - | |
86 | - @PostMapping("config") | |
87 | - @ApiOperation("添加或修改转换配置") | |
88 | - public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertData( | |
89 | - @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException { | |
90 | - convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | |
91 | - convertConfigDTO.setNodeType(FastIotConstants.CONVERT_DATA); | |
92 | - return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO)); | |
93 | - } | |
94 | 85 | |
95 | - @PostMapping("js") | |
96 | - @ApiOperation("添加或修改转换脚本") | |
97 | - public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertJS( | |
98 | - @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException { | |
99 | - convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | |
100 | - convertConfigDTO.setNodeType(FastIotConstants.JAVA_SCRIPT); | |
101 | - return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO)); | |
102 | - } | |
103 | - | |
104 | - @PostMapping("/check/config") | |
105 | - @ApiOperation("检查配置名称是否存在") | |
106 | - public ResponseEntity<Boolean> checkConvertConfig(@RequestBody Map<String, String> checkParam) | |
107 | - throws ThingsboardException { | |
108 | - String type = checkParam.get("type"); | |
109 | - String name = checkParam.get("name"); | |
110 | - if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) { | |
111 | - throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
86 | + @PostMapping("config") | |
87 | + @ApiOperation("添加或修改转换配置") | |
88 | + public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertData( | |
89 | + @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException { | |
90 | + convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | |
91 | + convertConfigDTO.setNodeType(FastIotConstants.CONVERT_DATA); | |
92 | + return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO)); | |
112 | 93 | } |
113 | - return ResponseEntity.ok( | |
114 | - convertConfigService.checkConvertConfigNameExist( | |
115 | - null, name, type, getCurrentUser().getCurrentTenantId())); | |
116 | - } | |
117 | 94 | |
118 | - @DeleteMapping("config") | |
119 | - @ApiOperation("删除转换配置") | |
120 | - public ResponseEntity<Boolean> deleteConfig( | |
121 | - @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException { | |
122 | - return delete(deleteDTO, FastIotConstants.CONVERT_DATA); | |
123 | - } | |
95 | + @PostMapping("js") | |
96 | + @ApiOperation("添加或修改转换脚本") | |
97 | + public ResponseEntity<ConvertConfigDTO> createOrUpdateConvertJS( | |
98 | + @Validated @RequestBody ConvertConfigDTO convertConfigDTO) throws ThingsboardException { | |
99 | + convertConfigDTO.setTenantId(getCurrentUser().getCurrentTenantId()); | |
100 | + convertConfigDTO.setNodeType(FastIotConstants.JAVA_SCRIPT); | |
101 | + return ResponseEntity.ok(convertConfigService.createOrUpdate(convertConfigDTO)); | |
102 | + } | |
124 | 103 | |
125 | - @DeleteMapping("js") | |
126 | - @ApiOperation("删除转换脚本") | |
127 | - public ResponseEntity<Boolean> deleteJS( | |
128 | - @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException { | |
129 | - return delete(deleteDTO, FastIotConstants.JAVA_SCRIPT); | |
130 | - } | |
104 | + @PostMapping("/check/config") | |
105 | + @ApiOperation("检查配置名称是否存在") | |
106 | + public ResponseEntity<Boolean> checkConvertConfig(@RequestBody Map<String, String> checkParam) | |
107 | + throws ThingsboardException { | |
108 | + String type = checkParam.get("type"); | |
109 | + String name = checkParam.get("name"); | |
110 | + if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) { | |
111 | + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
112 | + } | |
113 | + return ResponseEntity.ok( | |
114 | + convertConfigService.checkConvertConfigNameExist( | |
115 | + null, name, type, getCurrentUser().getCurrentTenantId())); | |
116 | + } | |
131 | 117 | |
132 | - @PostMapping("update/config") | |
133 | - @ApiOperation("启用或禁用配置") | |
134 | - public RuleChainMetaData updateConfig( | |
135 | - @Validated(UpdateGroup.class) @RequestBody ConvertConfigReqDTO convertConfigReqDTO) | |
136 | - throws ThingsboardException { | |
137 | - if (convertConfigService.checkConvertConfigStatusExist( | |
138 | - convertConfigReqDTO.getConvertIds(), | |
139 | - convertConfigReqDTO.getStatus(), | |
140 | - getCurrentUser().getCurrentTenantId())) { | |
141 | - throw new YtDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage()); | |
118 | + @DeleteMapping("config") | |
119 | + @ApiOperation("删除转换配置") | |
120 | + public ResponseEntity<Boolean> deleteConfig( | |
121 | + @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException { | |
122 | + return delete(deleteDTO, FastIotConstants.CONVERT_DATA); | |
142 | 123 | } |
143 | - List<String> ids = convertConfigReqDTO.getConvertIds(); | |
144 | - int status = convertConfigReqDTO.getStatus(); | |
145 | - List<RuleNode> nodes = | |
146 | - convertConfigService.getRuleNodesByConvertConfigIds( | |
147 | - ids, null, FastIotConstants.CONVERT_DATA); | |
148 | - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); | |
149 | - if (null != nodes && nodes.size() > 0) { | |
150 | - ruleChainMetaData = saveRuleChain(nodes, status, FastIotConstants.CONVERT_DATA); | |
124 | + | |
125 | + @DeleteMapping("js") | |
126 | + @ApiOperation("删除转换脚本") | |
127 | + public ResponseEntity<Boolean> deleteJS( | |
128 | + @Validated(DeleteGroup.class) @RequestBody DeleteDTO deleteDTO) throws ThingsboardException { | |
129 | + return delete(deleteDTO, FastIotConstants.JAVA_SCRIPT); | |
151 | 130 | } |
152 | - convertConfigService.updateConvertStatusByIds( | |
153 | - ids, status, getCurrentUser().getCurrentTenantId()); | |
154 | - return ruleChainMetaData; | |
155 | - } | |
156 | 131 | |
157 | - @PostMapping("update/js") | |
158 | - @ApiOperation("启用或禁用转换脚本") | |
159 | - public RuleChainMetaData updateJs( | |
160 | - @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertJSReqDTO) | |
161 | - throws ThingsboardException { | |
162 | - int status = convertJSReqDTO.getStatus(); | |
163 | - if (status == FastIotConstants.StateValue.ENABLE | |
164 | - && convertConfigService.checkConvertJSStatusEnable(getCurrentUser().getCurrentTenantId())) { | |
165 | - throw new YtDataValidationException(ErrorMessage.CONVERT_JS_IS_ALONE.getMessage()); | |
132 | + @PostMapping("update/config") | |
133 | + @ApiOperation("启用或禁用配置") | |
134 | + public RuleChainMetaData updateConfig( | |
135 | + @Validated(UpdateGroup.class) @RequestBody ConvertConfigReqDTO convertConfigReqDTO) | |
136 | + throws ThingsboardException { | |
137 | + if (convertConfigService.checkConvertConfigStatusExist( | |
138 | + convertConfigReqDTO.getConvertIds(), | |
139 | + convertConfigReqDTO.getStatus(), | |
140 | + getCurrentUser().getCurrentTenantId())) { | |
141 | + throw new YtDataValidationException(ErrorMessage.DATA_ALREADY_EXISTS.getMessage()); | |
142 | + } | |
143 | + List<String> ids = convertConfigReqDTO.getConvertIds(); | |
144 | + int status = convertConfigReqDTO.getStatus(); | |
145 | + List<RuleNode> nodes = | |
146 | + convertConfigService.getRuleNodesByConvertConfigIds( | |
147 | + ids, null, FastIotConstants.CONVERT_DATA); | |
148 | + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); | |
149 | + if (null != nodes && nodes.size() > 0) { | |
150 | + ruleChainMetaData = saveRuleChain(nodes, status, FastIotConstants.CONVERT_DATA); | |
151 | + } | |
152 | + convertConfigService.updateConvertStatusByIds( | |
153 | + ids, status, getCurrentUser().getCurrentTenantId()); | |
154 | + return ruleChainMetaData; | |
166 | 155 | } |
167 | - List<String> ids = new ArrayList<>(); | |
168 | - ids.add(convertJSReqDTO.getId()); | |
169 | - List<RuleNode> nodes = | |
170 | - convertConfigService.getRuleNodesByConvertConfigIds( | |
171 | - ids, null, FastIotConstants.JAVA_SCRIPT); | |
172 | 156 | |
173 | - RuleChainMetaData ruleChainMetaData = | |
174 | - saveRuleChain(nodes, status, FastIotConstants.JAVA_SCRIPT); | |
175 | - convertConfigService.updateConvertStatusByIds( | |
176 | - ids, status, getCurrentUser().getCurrentTenantId()); | |
177 | - return ruleChainMetaData; | |
178 | - } | |
157 | + @PostMapping("update/js") | |
158 | + @ApiOperation("启用或禁用转换脚本") | |
159 | + public RuleChainMetaData updateJs( | |
160 | + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertJSReqDTO) | |
161 | + throws ThingsboardException { | |
162 | + int status = convertJSReqDTO.getStatus(); | |
163 | + if (status == FastIotConstants.StateValue.ENABLE | |
164 | + && convertConfigService.checkConvertJSStatusEnable(getCurrentUser().getCurrentTenantId())) { | |
165 | + throw new YtDataValidationException(ErrorMessage.CONVERT_JS_IS_ALONE.getMessage()); | |
166 | + } | |
167 | + List<String> ids = new ArrayList<>(); | |
168 | + ids.add(convertJSReqDTO.getId()); | |
169 | + List<RuleNode> nodes = | |
170 | + convertConfigService.getRuleNodesByConvertConfigIds( | |
171 | + ids, null, FastIotConstants.JAVA_SCRIPT); | |
179 | 172 | |
180 | - @PostMapping("update/scene") | |
181 | - @ApiOperation("启用或禁用场景联动") | |
182 | - public RuleChainMetaData updateScene( | |
183 | - @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertReqDTO) | |
184 | - throws ThingsboardException { | |
185 | - //TODO 通过接口获取JsonNode | |
186 | - int status = -1; | |
187 | - String sceneId = convertReqDTO.getId(); | |
188 | - String currentTenant = getCurrentUser().getCurrentTenantId(); | |
189 | - Integer sceneStatus = convertReqDTO.getStatus(); | |
190 | - JsonNode configuration = sceneLinkageService.getRuleNodeConfig(sceneId,currentTenant,getCurrentUser().getCustomerId().getId().toString(),sceneStatus); | |
191 | - boolean noValue = configuration == null; | |
192 | - if (noValue && convertReqDTO.getStatus() == FastIotConstants.StateValue.DISABLE) { | |
193 | - status = FastIotConstants.StateValue.DISABLE; | |
173 | + RuleChainMetaData ruleChainMetaData = | |
174 | + saveRuleChain(nodes, status, FastIotConstants.JAVA_SCRIPT); | |
175 | + convertConfigService.updateConvertStatusByIds( | |
176 | + ids, status, getCurrentUser().getCurrentTenantId()); | |
177 | + return ruleChainMetaData; | |
194 | 178 | } |
195 | - if (!noValue) { | |
196 | - status = FastIotConstants.StateValue.ENABLE; | |
197 | - } | |
198 | - List<RuleNode> ruleNodes = new ArrayList<>(); | |
199 | - RuleNode scene = new RuleNode(); | |
200 | - scene.setName("Scene"); | |
201 | - scene.setType("org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode"); | |
202 | - scene.setConfiguration(configuration); | |
203 | - ruleNodes.add(scene); | |
204 | - RuleChainMetaData result = saveRuleChain(ruleNodes, status, FastIotConstants.SCENE_REACT); | |
205 | - sceneLinkageService.updateSceneStatus(sceneId,sceneStatus,currentTenant); | |
206 | - return result; | |
207 | - } | |
208 | 179 | |
209 | - /** | |
210 | - * 保存规则链 | |
211 | - * | |
212 | - * @param nodes 规则节点 | |
213 | - * @param status 0禁用 1启用 | |
214 | - * @return 规则节点数据 | |
215 | - */ | |
216 | - private RuleChainMetaData saveRuleChain(List<RuleNode> nodes, Integer status, Integer nodeType) | |
217 | - throws ThingsboardException { | |
218 | - boolean needSaveRuleNode; | |
219 | - TenantId tenantId = getTenantId(); | |
220 | - // 1. GET DEFAULT RULE CHAIN | |
221 | - RuleChain ruleChain = ytRuleChainService.getRootTenantRuleChain(getTenantId()); | |
222 | - // 2. GET RULE CHAIN METADATA | |
223 | - RuleChainMetaData ruleChainMetaData = | |
224 | - ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChain.getId()); | |
225 | - // 3. SETUP CONNECTION AND ADD OR DELETE RULE NODE | |
226 | - if (status == FastIotConstants.MagicNumber.ZERO) { | |
227 | - needSaveRuleNode = convertConfigService.deleteRuleNode(nodes, ruleChainMetaData, nodeType); | |
228 | - } else { | |
229 | - convertConfigService.addRuleNode(nodes, ruleChainMetaData, nodeType); | |
230 | - needSaveRuleNode = true; | |
180 | + @PostMapping("update/scene") | |
181 | + @ApiOperation("启用或禁用场景联动") | |
182 | + public RuleChainMetaData updateScene( | |
183 | + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertReqDTO) | |
184 | + throws ThingsboardException { | |
185 | + int status = -1; | |
186 | + String sceneId = convertReqDTO.getId(); | |
187 | + String currentTenant = getCurrentUser().getCurrentTenantId(); | |
188 | + Integer sceneStatus = convertReqDTO.getStatus(); | |
189 | + JsonNode configuration = sceneLinkageService.getRuleNodeConfig(sceneId, currentTenant, getCurrentUser().getCustomerId().getId().toString(), sceneStatus); | |
190 | + boolean noValue = configuration == null; | |
191 | + if (noValue && convertReqDTO.getStatus() == FastIotConstants.StateValue.DISABLE) { | |
192 | + status = FastIotConstants.StateValue.DISABLE; | |
193 | + } | |
194 | + if (!noValue) { | |
195 | + status = FastIotConstants.StateValue.ENABLE; | |
196 | + } | |
197 | + List<RuleNode> ruleNodes = new ArrayList<>(); | |
198 | + RuleNode scene = new RuleNode(); | |
199 | + scene.setName("Scene"); | |
200 | + scene.setType("org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode"); | |
201 | + scene.setConfiguration(configuration); | |
202 | + ruleNodes.add(scene); | |
203 | + RuleChainMetaData result = saveRuleChain(ruleNodes, status, FastIotConstants.SCENE_REACT); | |
204 | + sceneLinkageService.updateSceneStatus(sceneId, sceneStatus, currentTenant); | |
205 | + return result; | |
231 | 206 | } |
232 | - // 4. SAVE METADATA | |
233 | - RuleChainMetaData savedRuleChainMetaData = null; | |
234 | - if (needSaveRuleNode) { | |
235 | - if (debugPerTenantEnabled) { | |
236 | - ConcurrentMap<TenantId, DebugTbRateLimits> debugPerTenantLimits = | |
237 | - actorContext.getDebugPerTenantLimits(); | |
238 | - DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null); | |
239 | - if (debugTbRateLimits != null) { | |
240 | - debugPerTenantLimits.remove(tenantId, debugTbRateLimits); | |
207 | + | |
208 | + /** | |
209 | + * 保存规则链 | |
210 | + * | |
211 | + * @param nodes 规则节点 | |
212 | + * @param status 0禁用 1启用 | |
213 | + * @return 规则节点数据 | |
214 | + */ | |
215 | + private RuleChainMetaData saveRuleChain(List<RuleNode> nodes, Integer status, Integer nodeType) | |
216 | + throws ThingsboardException { | |
217 | + boolean needSaveRuleNode; | |
218 | + TenantId tenantId = getTenantId(); | |
219 | + // 1. GET DEFAULT RULE CHAIN | |
220 | + RuleChain ruleChain = ytRuleChainService.getRootTenantRuleChain(getTenantId()); | |
221 | + // 2. GET RULE CHAIN METADATA | |
222 | + RuleChainMetaData ruleChainMetaData = | |
223 | + ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChain.getId()); | |
224 | + // 3. SETUP CONNECTION AND ADD OR DELETE RULE NODE | |
225 | + if (status == FastIotConstants.MagicNumber.ZERO) { | |
226 | + needSaveRuleNode = convertConfigService.deleteRuleNode(nodes, ruleChainMetaData, nodeType); | |
227 | + } else { | |
228 | + convertConfigService.addRuleNode(nodes, ruleChainMetaData, nodeType); | |
229 | + needSaveRuleNode = true; | |
241 | 230 | } |
242 | - } | |
243 | - checkNotNull( | |
244 | - ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData) ? true : null); | |
245 | - savedRuleChainMetaData = | |
246 | - checkNotNull( | |
247 | - ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); | |
231 | + // 4. SAVE METADATA | |
232 | + RuleChainMetaData savedRuleChainMetaData = null; | |
233 | + if (needSaveRuleNode) { | |
234 | + if (debugPerTenantEnabled) { | |
235 | + ConcurrentMap<TenantId, DebugTbRateLimits> debugPerTenantLimits = | |
236 | + actorContext.getDebugPerTenantLimits(); | |
237 | + DebugTbRateLimits debugTbRateLimits = debugPerTenantLimits.getOrDefault(tenantId, null); | |
238 | + if (debugTbRateLimits != null) { | |
239 | + debugPerTenantLimits.remove(tenantId, debugTbRateLimits); | |
240 | + } | |
241 | + } | |
242 | + checkNotNull( | |
243 | + ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData) ? true : null); | |
244 | + savedRuleChainMetaData = | |
245 | + checkNotNull( | |
246 | + ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); | |
248 | 247 | |
249 | - if (RuleChainType.CORE.equals(ruleChain.getType())) { | |
250 | - tbClusterService.broadcastEntityStateChangeEvent( | |
251 | - ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); | |
252 | - } | |
248 | + if (RuleChainType.CORE.equals(ruleChain.getType())) { | |
249 | + tbClusterService.broadcastEntityStateChangeEvent( | |
250 | + ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); | |
251 | + } | |
252 | + } | |
253 | + return savedRuleChainMetaData; | |
253 | 254 | } |
254 | - return savedRuleChainMetaData; | |
255 | - } | |
256 | 255 | |
257 | - private ResponseEntity<Boolean> delete(DeleteDTO deleteDTO, Integer nodeType) | |
258 | - throws ThingsboardException { | |
259 | - List<RuleNode> nodes = | |
260 | - convertConfigService.getRuleNodesByConvertConfigIds( | |
261 | - new ArrayList<>(deleteDTO.getIds()), FastIotConstants.StateValue.ENABLE, nodeType); | |
262 | - if (nodes != null && nodes.size() > FastIotConstants.MagicNumber.ZERO) { | |
263 | - saveRuleChain(nodes, 0, nodeType); | |
256 | + private ResponseEntity<Boolean> delete(DeleteDTO deleteDTO, Integer nodeType) | |
257 | + throws ThingsboardException { | |
258 | + List<RuleNode> nodes = | |
259 | + convertConfigService.getRuleNodesByConvertConfigIds( | |
260 | + new ArrayList<>(deleteDTO.getIds()), FastIotConstants.StateValue.ENABLE, nodeType); | |
261 | + if (nodes != null && nodes.size() > FastIotConstants.MagicNumber.ZERO) { | |
262 | + saveRuleChain(nodes, 0, nodeType); | |
263 | + } | |
264 | + return ResponseEntity.ok(convertConfigService.deleteConvertConfig(deleteDTO, nodeType)); | |
264 | 265 | } |
265 | - return ResponseEntity.ok(convertConfigService.deleteConvertConfig(deleteDTO, nodeType)); | |
266 | - } | |
267 | 266 | } | ... | ... |
... | ... | @@ -72,14 +72,14 @@ public interface FastIotConstants { |
72 | 72 | } |
73 | 73 | |
74 | 74 | interface ReceiverType { |
75 | - String PERSONAL = "3"; | |
76 | - String DEPARTMENT = "2"; | |
77 | - String ORGANIZATION = "1"; | |
78 | - String ALL = "0"; | |
75 | + int PERSONAL = 3; | |
76 | + int DEPARTMENT = 2; | |
77 | + int ORGANIZATION = 1; | |
78 | + int ALL = 0; | |
79 | 79 | } |
80 | 80 | |
81 | 81 | interface DraftStatus { |
82 | - String PUBLISHED = "1"; | |
83 | - String DRAFT = "0"; | |
82 | + int PUBLISHED = 1; | |
83 | + int DRAFT = 0; | |
84 | 84 | } |
85 | 85 | } | ... | ... |
... | ... | @@ -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 | } | ... | ... |
... | ... | @@ -31,13 +31,13 @@ public class SysNoticeDTO extends TenantDTO { |
31 | 31 | private String content; |
32 | 32 | |
33 | 33 | @ApiModelProperty(value = "接收者(字典值receiver_type) 0:全部 1:组织 2:部门 3:个人",required = true) |
34 | - private String receiverType; | |
34 | + private Integer receiverType; | |
35 | 35 | |
36 | 36 | @ApiModelProperty(value = "根据receiverType不同变化,0:传null,1:组织id,2:部门id,3:用户id",required = true) |
37 | 37 | private String pointId; |
38 | 38 | |
39 | 39 | @ApiModelProperty(value = "发送状态(字典值draft_status) 0:草稿 1:已发布") |
40 | - private String status; | |
40 | + private Integer status; | |
41 | 41 | |
42 | 42 | @ApiModelProperty(value = "发送者") |
43 | 43 | private String senderName; | ... | ... |
... | ... | @@ -27,9 +27,9 @@ public class SysNotice extends TenantBaseEntity { |
27 | 27 | /** 内容 */ |
28 | 28 | private String content; |
29 | 29 | /** 接收者(字典值receiver_type) 0:全部 1:组织 2:部门 3:个人 */ |
30 | - private String receiverType; | |
30 | + private int receiverType; | |
31 | 31 | /** 发送状态(字典值draft_status) 0:草稿 1:已发布 */ |
32 | - private String status; | |
32 | + private int status; | |
33 | 33 | /** 发送者 */ |
34 | 34 | private String senderName; |
35 | 35 | /** 发送时间 */ | ... | ... |
... | ... | @@ -73,7 +73,7 @@ public class SysNoticeUserServiceImpl |
73 | 73 | |
74 | 74 | @Override |
75 | 75 | public void saveSysNoticeUser( |
76 | - List<String> userIds, String tenantId, String noticeId, String status) { | |
76 | + List<String> userIds, String tenantId, String noticeId, Integer status) { | |
77 | 77 | List<User> userList = userMapper |
78 | 78 | .selectList( |
79 | 79 | new LambdaQueryWrapper<User>().in(User::getId, userIds)) |
... | ... | @@ -108,8 +108,8 @@ public class SysNoticeUserServiceImpl |
108 | 108 | } |
109 | 109 | |
110 | 110 | @Override |
111 | - public boolean updateSysNoticeUsersStatusByNoticeId(String id, String status) { | |
112 | - if (StringUtils.isAllEmpty(id) || StringUtils.isAllEmpty(status)) { | |
111 | + public boolean updateSysNoticeUsersStatusByNoticeId(String id, Integer status) { | |
112 | + if (StringUtils.isAllEmpty(id) || status == null) { | |
113 | 113 | throw new YtDataValidationException(ErrorMessage.INTERNAL_ERROR.name()); |
114 | 114 | } |
115 | 115 | return baseMapper.updateSysNoticeUsersStatusByNoticeId(id, status); | ... | ... |
... | ... | @@ -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); | ... | ... |
... | ... | @@ -30,7 +30,7 @@ public interface SysNoticeUserMapper extends BaseMapper<SysNoticeUser> { |
30 | 30 | */ |
31 | 31 | SysNoticeUserDTO get(@Param("id") String id, @Param("tenantId") String tenantId); |
32 | 32 | |
33 | - boolean updateSysNoticeUsersStatusByNoticeId(@Param("noticeId")String noticeId, @Param("status")String status); | |
33 | + boolean updateSysNoticeUsersStatusByNoticeId(@Param("noticeId")String noticeId, @Param("status")Integer status); | |
34 | 34 | |
35 | 35 | |
36 | 36 | } | ... | ... |
... | ... | @@ -21,11 +21,11 @@ public interface SysNoticeUserService extends BaseService<SysNoticeUser>{ |
21 | 21 | |
22 | 22 | SysNoticeUserDTO get(String id,String tenantId); |
23 | 23 | |
24 | - void saveSysNoticeUser (List<String> userIds, String tenantId,String noticeId,String status); | |
24 | + void saveSysNoticeUser (List<String> userIds, String tenantId,String noticeId,Integer status); | |
25 | 25 | |
26 | 26 | List<String> getSysNoticeUserIdsByNoticeId(String noticeId); |
27 | 27 | |
28 | - boolean updateSysNoticeUsersStatusByNoticeId(String noticeId, String status); | |
28 | + boolean updateSysNoticeUsersStatusByNoticeId(String noticeId, Integer status); | |
29 | 29 | |
30 | 30 | boolean deleteNoticUserByNoticeId(List<String> noticeId); |
31 | 31 | } | ... | ... |
... | ... | @@ -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 | } | ... | ... |
... | ... | @@ -32,15 +32,15 @@ |
32 | 32 | sn.id id, |
33 | 33 | sn.type AS type, |
34 | 34 | sn.title title, |
35 | - sn.content AS content, | |
36 | - ( | |
37 | - <include refid="dict"/> | |
38 | - AND sd.dict_code = 'receiver_type' AND sdi.item_value = sn.receiver_type | |
39 | - ) receiver_type, | |
40 | - ( | |
41 | - <include refid="dict"/> | |
42 | - AND sd.dict_code = 'draft_status' AND sdi.item_value = sn.status | |
43 | - ) status, | |
35 | + sn.content AS content,sn.receiver_type,sn.status, | |
36 | +<!-- (--> | |
37 | +<!-- <include refid="dict"/>--> | |
38 | +<!-- AND sd.dict_code = 'receiver_type' AND sdi.item_value = sn.receiver_type--> | |
39 | +<!-- ) receiver_type,--> | |
40 | +<!-- (--> | |
41 | +<!-- <include refid="dict"/>--> | |
42 | +<!-- AND sd.dict_code = 'draft_status' AND sdi.item_value = sn.status--> | |
43 | +<!-- ) status,--> | |
44 | 44 | sn.sender_name sender_name, |
45 | 45 | sn.sender_date sender_date, |
46 | 46 | sn.creator creator, | ... | ... |
... | ... | @@ -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; |
... | ... | @@ -33,121 +38,122 @@ import java.util.concurrent.ExecutionException; |
33 | 38 | @Slf4j |
34 | 39 | class ReactState { |
35 | 40 | |
36 | - /**场景联动主键*/ | |
41 | + /** | |
42 | + * 场景联动主键 | |
43 | + */ | |
37 | 44 | String reactId; |
38 | 45 | |
39 | - /**场景联动的触发器状态 | |
46 | + /** | |
47 | + * 场景联动的触发器状态 | |
40 | 48 | * 键:设备主键 |
41 | 49 | * 值:设备指标参与的触发器 |
42 | 50 | */ |
43 | - private ConcurrentHashMap<String, TriggerState > triggerState = new ConcurrentHashMap<>(); | |
51 | + private ConcurrentHashMap<String, TriggerState> triggerState = new ConcurrentHashMap<>(); | |
44 | 52 | |
45 | 53 | private ConcurrentHashMap<String, TriggerState> clearState = new ConcurrentHashMap<>(); |
46 | 54 | |
47 | - /**场景联动的执行条件状态 | |
55 | + /** | |
56 | + * 场景联动的执行条件状态 | |
48 | 57 | * 键:设备主键 |
49 | 58 | * 值:设备指标参与的触发器 |
50 | 59 | */ |
51 | 60 | private ConcurrentHashMap<String, TriggerState> conditionState = new ConcurrentHashMap<>(); |
52 | 61 | |
53 | 62 | |
54 | - | |
55 | - | |
56 | - | |
57 | 63 | private final List<TriggerDTO> triggers; |
58 | - /**【场景联动的执行条件】懒加载*/ | |
64 | + /** | |
65 | + * 【场景联动的执行条件】懒加载 | |
66 | + */ | |
59 | 67 | private final List<DoCondition> conditions; |
60 | - /**【场景联动的执行集合】懒加载*/ | |
68 | + /** | |
69 | + * 【场景联动的执行集合】懒加载 | |
70 | + */ | |
61 | 71 | private final List<DoAction> actions; |
62 | - | |
63 | - | |
64 | - | |
72 | + private final YtNoticeService noticeService; | |
65 | 73 | |
66 | 74 | |
67 | 75 | private RuleNodeState state; |
68 | 76 | |
69 | 77 | |
70 | - ReactState(String reactId,TbContext ctx, TbSceneReactNodeConfig config) { | |
78 | + ReactState(String reactId, TbContext ctx, TbSceneReactNodeConfig config) { | |
71 | 79 | this.reactId = reactId; |
72 | 80 | TriggerService triggerService = SpringBeanUtils.getBean(TriggerService.class); |
73 | 81 | this.triggers = triggerService.getTrigger(reactId); |
74 | 82 | DoConditionService conditionService = SpringBeanUtils.getBean(DoConditionService.class); |
75 | 83 | this.conditions = conditionService.getConditions(reactId); |
76 | 84 | DoActionService actionService = SpringBeanUtils.getBean(DoActionService.class); |
77 | - this.actions =actionService.getActions(reactId); | |
85 | + this.actions = actionService.getActions(reactId); | |
86 | + this.noticeService = SpringBeanUtils.getBean(YtNoticeService.class); | |
78 | 87 | |
79 | 88 | } |
80 | 89 | |
81 | 90 | |
82 | - | |
83 | - public void process(TbContext ctx, TbMsg msg,String deviceId) throws ExecutionException, InterruptedException { | |
84 | - | |
85 | - | |
91 | + public void process(TbContext ctx, TbMsg msg, String deviceId) throws ExecutionException, InterruptedException { | |
86 | 92 | |
87 | 93 | |
88 | - if( actions == null){ | |
94 | + StringBuilder detail = new StringBuilder(); | |
95 | + if (actions == null) { | |
89 | 96 | ctx.tellSuccess(msg); |
90 | 97 | } |
91 | 98 | |
92 | 99 | boolean matched; |
93 | - if(triggers == null || triggers.isEmpty()){ | |
100 | + if (triggers == null || triggers.isEmpty()) { | |
94 | 101 | matched = true; |
95 | - }else{ | |
102 | + } else { | |
96 | 103 | matched = false; |
97 | - for(TriggerDTO trigger: triggers){ | |
98 | - TriggerState triggerState = getOrCreateTriggerState(trigger,deviceId); | |
99 | - matched = triggerState.process(ctx,msg); | |
100 | - if(matched){ | |
104 | + for (TriggerDTO trigger : triggers) { | |
105 | + TriggerState triggerState = getOrCreateTriggerState(trigger, deviceId); | |
106 | + matched = triggerState.process(ctx, msg); | |
107 | + if (matched) { | |
108 | + detail.append(triggerState.getAlarmDetails()); | |
101 | 109 | break; |
102 | 110 | } |
103 | 111 | } |
104 | 112 | } |
105 | 113 | |
106 | 114 | |
107 | - if(matched && conditions.size() >0 ){ | |
115 | + if (matched && conditions.size() > 0) { | |
108 | 116 | matched = false; |
109 | - for(DoCondition item:conditions){ | |
117 | + for (DoCondition item : conditions) { | |
110 | 118 | List<String> entityIds = item.getEntityId(); |
111 | - if(entityIds == null || entityIds.isEmpty()){ | |
119 | + if (entityIds == null || entityIds.isEmpty()) { | |
112 | 120 | matched = true; |
113 | 121 | break; |
114 | 122 | } |
115 | - for(String id:entityIds){ | |
116 | - TriggerState conditionState = getOrCreateConditionState(item.getId(),id,item.getTriggerCondition()); | |
117 | - if( conditionState == null | |
118 | - || conditionState.process(ctx,msg)){ | |
123 | + for (String id : entityIds) { | |
124 | + TriggerState conditionState = getOrCreateConditionState(item.getId(), id, item.getTriggerCondition()); | |
125 | + if (conditionState == null | |
126 | + || conditionState.process(ctx, msg)) { | |
127 | + detail.append(";"); | |
128 | + detail.append(conditionState.getAlarmDetails()); | |
119 | 129 | matched = true; |
120 | 130 | break; |
121 | 131 | } |
122 | 132 | } |
123 | - if(matched){ | |
133 | + if (matched) { | |
124 | 134 | break; |
125 | 135 | } |
126 | 136 | } |
127 | 137 | } |
128 | 138 | |
129 | - if(matched){ | |
130 | - for(DoAction item: actions){ | |
131 | - pushMsg(ctx, msg, item); | |
139 | + if (matched) { | |
140 | + for (DoAction item : actions) { | |
141 | + pushMsg(ctx, msg, item,detail.toString()); | |
132 | 142 | } |
133 | - }else{ | |
143 | + } else { | |
134 | 144 | ctx.tellSuccess(msg); |
135 | 145 | } |
136 | 146 | |
137 | 147 | } |
138 | 148 | |
139 | 149 | |
140 | - | |
141 | - | |
142 | - | |
143 | - | |
144 | - protected TriggerState getOrCreateTriggerState(TriggerDTO trigger,String deviceId) { | |
150 | + protected TriggerState getOrCreateTriggerState(TriggerDTO trigger, String deviceId) { | |
145 | 151 | String triggerId = trigger.getId(); |
146 | - String cacheKey =triggerId+deviceId; | |
147 | - if(triggerState.containsKey(cacheKey)){ | |
152 | + String cacheKey = triggerId + deviceId; | |
153 | + if (triggerState.containsKey(cacheKey)) { | |
148 | 154 | return triggerState.get(cacheKey); |
149 | 155 | } |
150 | - if(trigger.getEntityId().contains(deviceId)){ | |
156 | + if (trigger.getEntityId().contains(deviceId)) { | |
151 | 157 | TriggerState state = createTriggerState(deviceId, trigger.getTriggerCondition()); |
152 | 158 | triggerState.put(cacheKey, state); |
153 | 159 | return state; |
... | ... | @@ -157,13 +163,13 @@ class ReactState { |
157 | 163 | } |
158 | 164 | |
159 | 165 | protected TriggerState getOrCreateConditionState(String conditionId, String deviceId, AlarmRule condition) { |
160 | - String cacheKey =conditionId+deviceId; | |
161 | - if(conditionState.containsKey(cacheKey)){ | |
166 | + String cacheKey = conditionId + deviceId; | |
167 | + if (conditionState.containsKey(cacheKey)) { | |
162 | 168 | return conditionState.get(cacheKey); |
163 | - }else{ | |
169 | + } else { | |
164 | 170 | TriggerState state = createTriggerState(deviceId, condition); |
165 | 171 | conditionState.put(cacheKey, state); |
166 | - return state; | |
172 | + return state; | |
167 | 173 | } |
168 | 174 | |
169 | 175 | } |
... | ... | @@ -171,51 +177,97 @@ class ReactState { |
171 | 177 | @NotNull |
172 | 178 | private TriggerState createTriggerState(String deviceId, AlarmRule rule) { |
173 | 179 | Set<AlarmConditionFilterKey> filterKeys = new HashSet<>(); |
174 | - for(AlarmConditionFilter filter :rule.getCondition().getCondition()){ | |
180 | + for (AlarmConditionFilter filter : rule.getCondition().getCondition()) { | |
175 | 181 | filterKeys.add(filter.getKey()); |
176 | 182 | } |
177 | - TriggerState state = new TriggerState(deviceId,rule, filterKeys,null); | |
183 | + TriggerState state = new TriggerState(deviceId, rule, filterKeys, rule.getAlarmDetails(),null); | |
178 | 184 | |
179 | - return state; | |
185 | + return state; | |
180 | 186 | } |
181 | 187 | |
182 | - private void pushMsg(TbContext ctx, TbMsg msg, DoAction action) { | |
188 | + private void pushMsg(TbContext ctx, TbMsg msg, DoAction action,String detail) { | |
183 | 189 | TbMsgMetaData metaData = //lastMsgMetaData != null ? lastMsgMetaData.copy() : |
184 | 190 | new TbMsgMetaData(); |
185 | 191 | String relationType = ""; |
186 | 192 | TbMsg newMsg = null; |
187 | - switch(action.getOutTarget()){ | |
193 | + switch (action.getOutTarget()) { | |
188 | 194 | case DEVICE_OUT: |
189 | - relationType = "RPC Request"; | |
190 | - newMsg = rpcMsg(ctx,msg,action.getDoContext()); | |
195 | + rpcMsg(ctx, msg, action.getDeviceId(), action.getDoContext()); | |
191 | 196 | break; |
192 | 197 | case SCENE_ACT: |
193 | - //TODO: 场景联动关联场景联动 | |
194 | - relationType = "Alarm Updated"; | |
198 | + reactMsg(ctx, msg, action); | |
195 | 199 | break; |
196 | 200 | case MSG_NOTIFY: |
197 | - relationType = "Message"; | |
201 | + noticeMsg(ctx, msg, action,detail); | |
198 | 202 | break; |
199 | 203 | default: |
200 | 204 | ctx.tellSuccess(msg); |
201 | 205 | break; |
202 | 206 | } |
207 | + } | |
203 | 208 | |
204 | - if(newMsg != null){ | |
205 | - ctx.tellNext(newMsg, relationType); | |
209 | + /** | |
210 | + * 设备输出 | |
211 | + * | |
212 | + * @param ctx | |
213 | + * @param msg | |
214 | + * @param devices | |
215 | + * @param context | |
216 | + */ | |
217 | + private void rpcMsg(TbContext ctx, TbMsg msg, List<String> devices, JsonNode context) { | |
218 | + String lastMsgQueueName = msg.getQueueName(); | |
219 | + TbMsgMetaData metaData = msg.getMetaData(); | |
220 | + for (String id : devices) { | |
221 | + TbMsg newMsg = ctx.newMsg(lastMsgQueueName != null ? lastMsgQueueName : ServiceQueue.MAIN | |
222 | + , msg.getType() | |
223 | + , msg.getOriginator() | |
224 | + , msg != null ? msg.getCustomerId() : null | |
225 | + , metaData | |
226 | + , JacksonUtil.toString(context)); | |
227 | + ctx.tellNext(newMsg, "RPC Request"); | |
206 | 228 | } |
207 | 229 | } |
208 | 230 | |
209 | - private TbMsg rpcMsg(TbContext ctx, TbMsg msg, JsonNode context){ | |
231 | + /** | |
232 | + * 告警通知 | |
233 | + * | |
234 | + * @param ctx | |
235 | + * @param msg | |
236 | + * @param action | |
237 | + */ | |
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: 场景联动关联消息通知 | |
210 | 262 | String lastMsgQueueName = msg.getQueueName(); |
211 | 263 | TbMsgMetaData metaData = msg.getMetaData(); |
212 | - metaData.putValue(DataConstants.IS_CLEARED_ALARM, Boolean.TRUE.toString()); | |
264 | + metaData.putValue(DataConstants.IS_CLEARED_ALARM, Boolean.TRUE.toString()); | |
213 | 265 | TbMsg newMsg = ctx.newMsg(lastMsgQueueName != null ? lastMsgQueueName : ServiceQueue.MAIN |
214 | 266 | , msg.getType() |
215 | 267 | , msg.getOriginator() |
216 | 268 | , msg != null ? msg.getCustomerId() : null |
217 | 269 | , metaData |
218 | - , JacksonUtil.toString(context)); | |
219 | - return newMsg; | |
270 | + , JacksonUtil.toString(action.getDoContext())); | |
271 | + ctx.tellNext(newMsg, "Message"); | |
220 | 272 | } |
221 | 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()); | ... | ... |