Showing
5 changed files
with
309 additions
and
180 deletions
1 | 1 | package org.thingsboard.server.controller.yunteng; |
2 | 2 | |
3 | -import com.fasterxml.jackson.databind.node.ObjectNode; | |
3 | +import com.fasterxml.jackson.databind.JsonNode; | |
4 | 4 | import io.swagger.annotations.Api; |
5 | 5 | import io.swagger.annotations.ApiOperation; |
6 | 6 | import io.swagger.annotations.ApiParam; |
... | ... | @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidatio |
26 | 26 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; |
27 | 27 | import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO; |
28 | 28 | import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigReqDTO; |
29 | -import org.thingsboard.server.common.data.yunteng.dto.ConvertJSReqDTO; | |
29 | +import org.thingsboard.server.common.data.yunteng.dto.ConvertReqDTO; | |
30 | 30 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
31 | 31 | import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; |
32 | 32 | import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; |
... | ... | @@ -36,7 +36,6 @@ import org.thingsboard.server.dao.yunteng.service.YtRuleChainService; |
36 | 36 | |
37 | 37 | import java.util.*; |
38 | 38 | import java.util.concurrent.ConcurrentMap; |
39 | -import java.util.concurrent.atomic.AtomicInteger; | |
40 | 39 | |
41 | 40 | import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*; |
42 | 41 | import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.ORDER_TYPE; |
... | ... | @@ -52,8 +51,6 @@ public class YtConvertDataToController extends BaseController { |
52 | 51 | @Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}") |
53 | 52 | private boolean debugPerTenantEnabled; |
54 | 53 | |
55 | - private final String connectionType = "Success"; | |
56 | - | |
57 | 54 | @Autowired(required = false) |
58 | 55 | private ActorSystemContext actorContext; |
59 | 56 | |
... | ... | @@ -158,7 +155,7 @@ public class YtConvertDataToController extends BaseController { |
158 | 155 | @PostMapping("update/js") |
159 | 156 | @ApiOperation("启用或禁用转换脚本") |
160 | 157 | public RuleChainMetaData updateJs( |
161 | - @Validated(UpdateGroup.class) @RequestBody ConvertJSReqDTO convertJSReqDTO) | |
158 | + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertJSReqDTO) | |
162 | 159 | throws ThingsboardException { |
163 | 160 | int status = convertJSReqDTO.getStatus(); |
164 | 161 | if (status == FastIotConstants.StateValue.ENABLE |
... | ... | @@ -178,6 +175,30 @@ public class YtConvertDataToController extends BaseController { |
178 | 175 | return ruleChainMetaData; |
179 | 176 | } |
180 | 177 | |
178 | + @PostMapping("update/scene") | |
179 | + @ApiOperation("启用或禁用场景联动") | |
180 | + public RuleChainMetaData updateScene( | |
181 | + @Validated(UpdateGroup.class) @RequestBody ConvertReqDTO convertReqDTO) | |
182 | + throws ThingsboardException { | |
183 | + //TODO 通过接口获取JsonNode | |
184 | + JsonNode configuration = convertReqDTO.getConfiguration(); | |
185 | + int status = -1; | |
186 | + boolean noValue = configuration == null; | |
187 | + if (noValue && convertReqDTO.getStatus() == FastIotConstants.StateValue.DISABLE) { | |
188 | + status = FastIotConstants.StateValue.DISABLE; | |
189 | + } | |
190 | + if (!noValue) { | |
191 | + status = FastIotConstants.StateValue.ENABLE; | |
192 | + } | |
193 | + List<RuleNode> ruleNodes = new ArrayList<>(); | |
194 | + RuleNode scene = new RuleNode(); | |
195 | + scene.setName("Scene"); | |
196 | + scene.setType("org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode"); | |
197 | + scene.setConfiguration(configuration); | |
198 | + ruleNodes.add(scene); | |
199 | + return saveRuleChain(ruleNodes, status, FastIotConstants.SCENE_REACT); | |
200 | + } | |
201 | + | |
181 | 202 | /** |
182 | 203 | * 保存规则链 |
183 | 204 | * |
... | ... | @@ -196,9 +217,9 @@ public class YtConvertDataToController extends BaseController { |
196 | 217 | ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChain.getId()); |
197 | 218 | // 3. SETUP CONNECTION AND ADD OR DELETE RULE NODE |
198 | 219 | if (status == FastIotConstants.MagicNumber.ZERO) { |
199 | - needSaveRuleNode = deleteRuleNode(nodes, ruleChainMetaData, nodeType); | |
220 | + needSaveRuleNode = convertConfigService.deleteRuleNode(nodes, ruleChainMetaData, nodeType); | |
200 | 221 | } else { |
201 | - addRuleNode(nodes, ruleChainMetaData, nodeType); | |
222 | + convertConfigService.addRuleNode(nodes, ruleChainMetaData, nodeType); | |
202 | 223 | needSaveRuleNode = true; |
203 | 224 | } |
204 | 225 | // 4. SAVE METADATA |
... | ... | @@ -226,174 +247,6 @@ public class YtConvertDataToController extends BaseController { |
226 | 247 | return savedRuleChainMetaData; |
227 | 248 | } |
228 | 249 | |
229 | - private void addRuleNode( | |
230 | - List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType) { | |
231 | - if (nodeType.intValue() == FastIotConstants.CONVERT_DATA.intValue()) { | |
232 | - addConvertConfigRuleNode(nodes, ruleChainMetaData); | |
233 | - } else { | |
234 | - // 1. Get Device Profile nodeIndex | |
235 | - int firstNodeIndex = ruleChainMetaData.getFirstNodeIndex(); | |
236 | - // 2. Add Rule Node | |
237 | - RuleNode ruleNode = nodes.get(0); | |
238 | - int randomNum = new Random().nextInt(50); | |
239 | - int layoutX = 202; | |
240 | - int layoutY = 53; | |
241 | - ObjectNode objectNode = JacksonUtil.newObjectNode(); | |
242 | - objectNode.put("description", ""); | |
243 | - objectNode.put("layoutX", layoutX + randomNum); | |
244 | - objectNode.put("layoutY", layoutY + randomNum); | |
245 | - ruleNode.setAdditionalInfo(objectNode); | |
246 | - ruleChainMetaData.getNodes().add(ruleNode); | |
247 | - int newFirstNodeIndex = ruleChainMetaData.getNodes().size() - 1; | |
248 | - ruleChainMetaData.setFirstNodeIndex(newFirstNodeIndex); | |
249 | - // 3. Add Connection | |
250 | - NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
251 | - nodeConnectionInfo.setFromIndex(newFirstNodeIndex); | |
252 | - nodeConnectionInfo.setType(connectionType); | |
253 | - nodeConnectionInfo.setToIndex(firstNodeIndex); | |
254 | - ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
255 | - } | |
256 | - } | |
257 | - | |
258 | - private void addConvertConfigRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
259 | - // 1. GET SAVE TIMESERIES‘S NODE INDEX | |
260 | - int seriesIndex = 0; | |
261 | - for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
262 | - if (ruleNode.getType().equals("org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode")) { | |
263 | - break; | |
264 | - } | |
265 | - seriesIndex++; | |
266 | - } | |
267 | - // 2. SETUP CONNECTION | |
268 | - // 3. ADD RULE NODE | |
269 | - int finalSeriesIndex = seriesIndex; | |
270 | - int layoutX = 1140; | |
271 | - int layoutY = 170; | |
272 | - nodes.forEach( | |
273 | - ruleNode -> { | |
274 | - int randomNum = new Random().nextInt(50); | |
275 | - NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
276 | - nodeConnectionInfo.setFromIndex(finalSeriesIndex); | |
277 | - nodeConnectionInfo.setType(connectionType); | |
278 | - nodeConnectionInfo.setToIndex(ruleChainMetaData.getNodes().size()); | |
279 | - ObjectNode objectNode = JacksonUtil.newObjectNode(); | |
280 | - objectNode.put("description", ""); | |
281 | - objectNode.put("layoutX", layoutX + randomNum); | |
282 | - objectNode.put("layoutY", layoutY + randomNum); | |
283 | - ruleNode.setAdditionalInfo(objectNode); | |
284 | - ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
285 | - ruleChainMetaData.getNodes().add(ruleNode); | |
286 | - }); | |
287 | - } | |
288 | - /** | |
289 | - * 删除规则节点 | |
290 | - * | |
291 | - * @param nodes 要删除的规则节点 | |
292 | - * @param ruleChainMetaData 规则链元数据 | |
293 | - */ | |
294 | - private boolean deleteRuleNode( | |
295 | - List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType) { | |
296 | - boolean needDelete; | |
297 | - if (nodeType.intValue() == FastIotConstants.CONVERT_DATA.intValue()) { | |
298 | - needDelete = deleteConvertConfig(nodes, ruleChainMetaData); | |
299 | - } else { | |
300 | - needDelete = deleteConvertJS(nodes, ruleChainMetaData); | |
301 | - } | |
302 | - return needDelete; | |
303 | - } | |
304 | - | |
305 | - private boolean deleteConvertConfig(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
306 | - boolean needDelete = true; | |
307 | - // refactoring RuleChainMetaData | |
308 | - AtomicInteger matchNode = new AtomicInteger(0); | |
309 | - nodes.forEach( | |
310 | - deleteRuleNode -> { | |
311 | - int deleteFlag = 0; | |
312 | - List<RuleNode> normalRuleNode = new ArrayList<>(); | |
313 | - List<NodeConnectionInfo> nodeConnectionInfos = ruleChainMetaData.getConnections(); | |
314 | - for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
315 | - if (deleteRuleNode.getName().equals(ruleNode.getName()) | |
316 | - && deleteRuleNode.getType().equals(ruleNode.getType())) { | |
317 | - ruleChainMetaData.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex() - 1); | |
318 | - List<NodeConnectionInfo> normalConnectionInfos = new ArrayList<>(); | |
319 | - for (NodeConnectionInfo nodeConnectionInfo : nodeConnectionInfos) { | |
320 | - int fromIndex = nodeConnectionInfo.getFromIndex(); | |
321 | - int toIndex = nodeConnectionInfo.getToIndex(); | |
322 | - if (fromIndex != deleteFlag && toIndex != deleteFlag) { | |
323 | - nodeConnectionInfo.setFromIndex( | |
324 | - Math.max(fromIndex > deleteFlag ? fromIndex - 1 : fromIndex, 0)); | |
325 | - nodeConnectionInfo.setToIndex( | |
326 | - Math.max(toIndex > deleteFlag ? toIndex - 1 : toIndex, 0)); | |
327 | - normalConnectionInfos.add(nodeConnectionInfo); | |
328 | - } | |
329 | - } | |
330 | - ruleChainMetaData.setConnections(normalConnectionInfos); | |
331 | - matchNode.getAndIncrement(); | |
332 | - } else { | |
333 | - normalRuleNode.add(ruleNode); | |
334 | - } | |
335 | - deleteFlag++; | |
336 | - } | |
337 | - ruleChainMetaData.setNodes(normalRuleNode); | |
338 | - }); | |
339 | - if (matchNode.get() == 0) { | |
340 | - needDelete = false; | |
341 | - } | |
342 | - return needDelete; | |
343 | - } | |
344 | - | |
345 | - private boolean deleteConvertJS(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
346 | - boolean needDelete = false; | |
347 | - // 1. Get firstNodeIndex | |
348 | - int firstNodeIndex = ruleChainMetaData.getFirstNodeIndex(); | |
349 | - // 2. Get Delete Rule Node | |
350 | - RuleNode deleteRuleNode = nodes.get(0); | |
351 | - // 3. RuleChainMetaData Delete Rule Node | |
352 | - int deleteFlag = 0; | |
353 | - for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
354 | - if (ruleNode.getName().equals(deleteRuleNode.getName()) | |
355 | - && ruleNode.getType().equals(deleteRuleNode.getType())) { | |
356 | - needDelete = true; | |
357 | - break; | |
358 | - } | |
359 | - deleteFlag++; | |
360 | - } | |
361 | - if (needDelete) { | |
362 | - ruleChainMetaData.getNodes().remove(deleteFlag); | |
363 | - // 4. Delete Connection | |
364 | - List<NodeConnectionInfo> newConnections = new ArrayList<>(); | |
365 | - ruleChainMetaData | |
366 | - .getConnections() | |
367 | - .forEach( | |
368 | - connectionInfo -> { | |
369 | - int toIndex = connectionInfo.getToIndex(); | |
370 | - int fromIndex = connectionInfo.getFromIndex(); | |
371 | - if (firstNodeIndex != connectionInfo.getToIndex() && fromIndex != firstNodeIndex) { | |
372 | - connectionInfo.setFromIndex( | |
373 | - Math.max(fromIndex > firstNodeIndex ? fromIndex - 1 : fromIndex, 0)); | |
374 | - connectionInfo.setToIndex( | |
375 | - Math.max(toIndex > firstNodeIndex ? toIndex - 1 : toIndex, 0)); | |
376 | - newConnections.add(connectionInfo); | |
377 | - } | |
378 | - }); | |
379 | - | |
380 | - int deviceProfileNodeIndex = 0; | |
381 | - ruleChainMetaData.setConnections(newConnections); | |
382 | - // 5. Set firstNodeIndex | |
383 | - for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
384 | - if (ruleNode.getName().equals("Device Profile Node") | |
385 | - && ruleNode | |
386 | - .getType() | |
387 | - .equals("org.thingsboard.rule.engine.profile.TbDeviceProfileNode")) { | |
388 | - ruleChainMetaData.setFirstNodeIndex(deviceProfileNodeIndex); | |
389 | - break; | |
390 | - } | |
391 | - deviceProfileNodeIndex++; | |
392 | - } | |
393 | - } | |
394 | - return needDelete; | |
395 | - } | |
396 | - | |
397 | 250 | private ResponseEntity<Boolean> delete(DeleteDTO deleteDTO, Integer nodeType) |
398 | 251 | throws ThingsboardException { |
399 | 252 | List<RuleNode> nodes = | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/ConvertReqDTO.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/dto/ConvertJSReqDTO.java
1 | 1 | package org.thingsboard.server.common.data.yunteng.dto; |
2 | 2 | |
3 | +import com.fasterxml.jackson.databind.JsonNode; | |
3 | 4 | import io.swagger.annotations.ApiModelProperty; |
4 | 5 | import lombok.Data; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; |
6 | 7 | |
7 | 8 | import javax.validation.constraints.NotEmpty; |
8 | 9 | import javax.validation.constraints.NotNull; |
9 | -import java.util.List; | |
10 | 10 | |
11 | 11 | @Data |
12 | -public class ConvertJSReqDTO { | |
12 | +public class ConvertReqDTO { | |
13 | 13 | |
14 | - @ApiModelProperty(value = "转换脚本id",required = true) | |
14 | + @ApiModelProperty(value = "id",required = true) | |
15 | 15 | @NotEmpty(message = "id不能为null",groups = UpdateGroup.class) |
16 | 16 | private String id; |
17 | 17 | |
18 | 18 | @ApiModelProperty(value = "状态:0禁用 1启用",required = true) |
19 | 19 | @NotNull(message = "状态不能为空",groups = UpdateGroup.class) |
20 | 20 | private Integer status; |
21 | + | |
22 | + private JsonNode configuration; | |
21 | 23 | } | ... | ... |
... | ... | @@ -2,11 +2,15 @@ package org.thingsboard.server.dao.yunteng.impl; |
2 | 2 | |
3 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
4 | 4 | import com.baomidou.mybatisplus.core.metadata.IPage; |
5 | +import com.fasterxml.jackson.databind.node.ObjectNode; | |
5 | 6 | import lombok.RequiredArgsConstructor; |
6 | 7 | import lombok.extern.slf4j.Slf4j; |
7 | 8 | import org.apache.commons.lang3.StringUtils; |
8 | 9 | import org.springframework.stereotype.Service; |
9 | 10 | import org.springframework.transaction.annotation.Transactional; |
11 | +import org.thingsboard.common.util.JacksonUtil; | |
12 | +import org.thingsboard.server.common.data.rule.NodeConnectionInfo; | |
13 | +import org.thingsboard.server.common.data.rule.RuleChainMetaData; | |
10 | 14 | import org.thingsboard.server.common.data.rule.RuleNode; |
11 | 15 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
12 | 16 | import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException; |
... | ... | @@ -22,6 +26,8 @@ import org.thingsboard.server.dao.yunteng.service.ConvertConfigService; |
22 | 26 | import java.util.ArrayList; |
23 | 27 | import java.util.List; |
24 | 28 | import java.util.Map; |
29 | +import java.util.Random; | |
30 | +import java.util.concurrent.atomic.AtomicInteger; | |
25 | 31 | |
26 | 32 | @Slf4j |
27 | 33 | @Service |
... | ... | @@ -29,6 +35,7 @@ import java.util.Map; |
29 | 35 | public class ConvertConfigServiceImpl |
30 | 36 | extends AbstractBaseService<ConvertConfigMapper, ConvertConfig> |
31 | 37 | implements ConvertConfigService { |
38 | + private final String connectionType = "Success"; | |
32 | 39 | |
33 | 40 | @Override |
34 | 41 | public YtPageData<ConvertConfigDTO> page(String tenantId, Map<String, Object> queryMap) { |
... | ... | @@ -165,4 +172,264 @@ public class ConvertConfigServiceImpl |
165 | 172 | .size() |
166 | 173 | > FastIotConstants.MagicNumber.ZERO; |
167 | 174 | } |
175 | + /** | |
176 | + * 删除规则节点 | |
177 | + * | |
178 | + * @param nodes 要删除的规则节点 | |
179 | + * @param ruleChainMetaData 规则链元数据 | |
180 | + */ | |
181 | + @Override | |
182 | + public boolean deleteRuleNode( | |
183 | + List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType) { | |
184 | + boolean needDelete; | |
185 | + if (nodeType.intValue() == FastIotConstants.CONVERT_DATA.intValue()) { | |
186 | + needDelete = deleteConvertConfig(nodes, ruleChainMetaData); | |
187 | + } else if (nodeType.intValue() == FastIotConstants.JAVA_SCRIPT.intValue()) { | |
188 | + needDelete = deleteConvertJS(nodes, ruleChainMetaData); | |
189 | + } else { | |
190 | + needDelete = deleteScene(nodes.get(0), ruleChainMetaData); | |
191 | + } | |
192 | + return needDelete; | |
193 | + } | |
194 | + | |
195 | + @Override | |
196 | + public void addRuleNode( | |
197 | + List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType) { | |
198 | + if (nodeType.intValue() == FastIotConstants.CONVERT_DATA.intValue()) { | |
199 | + addConvertConfigRuleNode(nodes, ruleChainMetaData); | |
200 | + } else if (nodeType.intValue() == FastIotConstants.JAVA_SCRIPT.intValue()) { | |
201 | + addConvertJSRuleNode(nodes, ruleChainMetaData); | |
202 | + } else { | |
203 | + addSceneRuleNode(nodes.get(0), ruleChainMetaData); | |
204 | + } | |
205 | + } | |
206 | + | |
207 | + private boolean deleteConvertJS(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
208 | + boolean needDelete = false; | |
209 | + // 1. Get firstNodeIndex | |
210 | + int firstNodeIndex = ruleChainMetaData.getFirstNodeIndex(); | |
211 | + // 2. Get Delete Rule Node | |
212 | + RuleNode deleteRuleNode = nodes.get(0); | |
213 | + // 3. RuleChainMetaData Delete Rule Node | |
214 | + int deleteFlag = 0; | |
215 | + for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
216 | + if (ruleNode.getName().equals(deleteRuleNode.getName()) | |
217 | + && ruleNode.getType().equals(deleteRuleNode.getType())) { | |
218 | + needDelete = true; | |
219 | + break; | |
220 | + } | |
221 | + deleteFlag++; | |
222 | + } | |
223 | + if (needDelete) { | |
224 | + ruleChainMetaData.getNodes().remove(deleteFlag); | |
225 | + // 4. Delete Connection | |
226 | + List<NodeConnectionInfo> newConnections = new ArrayList<>(); | |
227 | + ruleChainMetaData | |
228 | + .getConnections() | |
229 | + .forEach( | |
230 | + connectionInfo -> { | |
231 | + int toIndex = connectionInfo.getToIndex(); | |
232 | + int fromIndex = connectionInfo.getFromIndex(); | |
233 | + if (firstNodeIndex != connectionInfo.getToIndex() && fromIndex != firstNodeIndex) { | |
234 | + connectionInfo.setFromIndex( | |
235 | + Math.max(fromIndex > firstNodeIndex ? fromIndex - 1 : fromIndex, 0)); | |
236 | + connectionInfo.setToIndex( | |
237 | + Math.max(toIndex > firstNodeIndex ? toIndex - 1 : toIndex, 0)); | |
238 | + newConnections.add(connectionInfo); | |
239 | + } | |
240 | + }); | |
241 | + | |
242 | + int deviceProfileNodeIndex = 0; | |
243 | + ruleChainMetaData.setConnections(newConnections); | |
244 | + // 5. Set firstNodeIndex | |
245 | + for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
246 | + if (ruleNode.getName().equals("Device Profile Node") | |
247 | + && ruleNode | |
248 | + .getType() | |
249 | + .equals("org.thingsboard.rule.engine.profile.TbDeviceProfileNode")) { | |
250 | + ruleChainMetaData.setFirstNodeIndex(deviceProfileNodeIndex); | |
251 | + break; | |
252 | + } | |
253 | + deviceProfileNodeIndex++; | |
254 | + } | |
255 | + } | |
256 | + return needDelete; | |
257 | + } | |
258 | + | |
259 | + private boolean deleteConvertConfig(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
260 | + boolean needDelete = true; | |
261 | + // refactoring RuleChainMetaData | |
262 | + AtomicInteger matchNode = new AtomicInteger(0); | |
263 | + nodes.forEach( | |
264 | + deleteRuleNode -> { | |
265 | + int deleteFlag = 0; | |
266 | + List<RuleNode> normalRuleNode = new ArrayList<>(); | |
267 | + List<NodeConnectionInfo> nodeConnectionInfos = ruleChainMetaData.getConnections(); | |
268 | + for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
269 | + if (deleteRuleNode.getName().equals(ruleNode.getName()) | |
270 | + && deleteRuleNode.getType().equals(ruleNode.getType())) { | |
271 | + ruleChainMetaData.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex() - 1); | |
272 | + List<NodeConnectionInfo> normalConnectionInfos = new ArrayList<>(); | |
273 | + for (NodeConnectionInfo nodeConnectionInfo : nodeConnectionInfos) { | |
274 | + int fromIndex = nodeConnectionInfo.getFromIndex(); | |
275 | + int toIndex = nodeConnectionInfo.getToIndex(); | |
276 | + if (fromIndex != deleteFlag && toIndex != deleteFlag) { | |
277 | + nodeConnectionInfo.setFromIndex( | |
278 | + Math.max(fromIndex > deleteFlag ? fromIndex - 1 : fromIndex, 0)); | |
279 | + nodeConnectionInfo.setToIndex( | |
280 | + Math.max(toIndex > deleteFlag ? toIndex - 1 : toIndex, 0)); | |
281 | + normalConnectionInfos.add(nodeConnectionInfo); | |
282 | + } | |
283 | + } | |
284 | + ruleChainMetaData.setConnections(normalConnectionInfos); | |
285 | + matchNode.getAndIncrement(); | |
286 | + } else { | |
287 | + normalRuleNode.add(ruleNode); | |
288 | + } | |
289 | + deleteFlag++; | |
290 | + } | |
291 | + ruleChainMetaData.setNodes(normalRuleNode); | |
292 | + }); | |
293 | + if (matchNode.get() == 0) { | |
294 | + needDelete = false; | |
295 | + } | |
296 | + return needDelete; | |
297 | + } | |
298 | + | |
299 | + private boolean deleteScene(RuleNode node, RuleChainMetaData ruleChainMetaData) { | |
300 | + int deleteIndex = 0; | |
301 | + boolean needDelete = false; | |
302 | + for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
303 | + if (ruleNode.getName().equals(node.getName()) && ruleNode.getType().equals(node.getType())) { | |
304 | + needDelete = true; | |
305 | + break; | |
306 | + } | |
307 | + deleteIndex++; | |
308 | + } | |
309 | + if (needDelete) { | |
310 | + // Delete Rule Node | |
311 | + ruleChainMetaData.getNodes().remove(deleteIndex); | |
312 | + List<NodeConnectionInfo> newConnections = new ArrayList<>(); | |
313 | + int finalDeleteIndex = deleteIndex; | |
314 | + // refactor connection | |
315 | + ruleChainMetaData | |
316 | + .getConnections() | |
317 | + .forEach( | |
318 | + nodeConnectionInfo -> { | |
319 | + int fromIndex = nodeConnectionInfo.getFromIndex(); | |
320 | + int toIndex = nodeConnectionInfo.getToIndex(); | |
321 | + if (finalDeleteIndex != nodeConnectionInfo.getToIndex() | |
322 | + && nodeConnectionInfo.getFromIndex() != finalDeleteIndex) { | |
323 | + nodeConnectionInfo.setFromIndex( | |
324 | + Math.max(fromIndex > finalDeleteIndex ? fromIndex - 1 : fromIndex, 0)); | |
325 | + nodeConnectionInfo.setToIndex( | |
326 | + Math.max(toIndex > finalDeleteIndex ? toIndex - 1 : toIndex, 0)); | |
327 | + newConnections.add(nodeConnectionInfo); | |
328 | + } | |
329 | + }); | |
330 | + ruleChainMetaData.setConnections(newConnections); | |
331 | + ruleChainMetaData.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex() - 1); | |
332 | + } | |
333 | + return needDelete; | |
334 | + } | |
335 | + | |
336 | + private void addConvertConfigRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
337 | + // 1. GET SAVE TIMESERIES‘S NODE INDEX | |
338 | + int seriesIndex = 0; | |
339 | + for (RuleNode ruleNode : ruleChainMetaData.getNodes()) { | |
340 | + if (ruleNode.getType().equals("org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode")) { | |
341 | + break; | |
342 | + } | |
343 | + seriesIndex++; | |
344 | + } | |
345 | + // 2. SETUP CONNECTION | |
346 | + // 3. ADD RULE NODE | |
347 | + int finalSeriesIndex = seriesIndex; | |
348 | + int layoutX = 1140; | |
349 | + int layoutY = 170; | |
350 | + nodes.forEach( | |
351 | + ruleNode -> { | |
352 | + NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
353 | + nodeConnectionInfo.setFromIndex(finalSeriesIndex); | |
354 | + nodeConnectionInfo.setType(connectionType); | |
355 | + nodeConnectionInfo.setToIndex(ruleChainMetaData.getNodes().size()); | |
356 | + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY); | |
357 | + ruleNode.setAdditionalInfo(objectNode); | |
358 | + ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
359 | + ruleChainMetaData.getNodes().add(ruleNode); | |
360 | + }); | |
361 | + } | |
362 | + | |
363 | + private void addConvertJSRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData) { | |
364 | + // 1. Get Device Profile nodeIndex | |
365 | + int firstNodeIndex = ruleChainMetaData.getFirstNodeIndex(); | |
366 | + // 2. Add Rule Node | |
367 | + RuleNode ruleNode = nodes.get(0); | |
368 | + int layoutX = 202; | |
369 | + int layoutY = 53; | |
370 | + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY); | |
371 | + ruleNode.setAdditionalInfo(objectNode); | |
372 | + ruleChainMetaData.getNodes().add(ruleNode); | |
373 | + int newFirstNodeIndex = ruleChainMetaData.getNodes().size() - 1; | |
374 | + ruleChainMetaData.setFirstNodeIndex(newFirstNodeIndex); | |
375 | + // 3. Add Connection | |
376 | + NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
377 | + nodeConnectionInfo.setFromIndex(newFirstNodeIndex); | |
378 | + nodeConnectionInfo.setType(connectionType); | |
379 | + nodeConnectionInfo.setToIndex(firstNodeIndex); | |
380 | + ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
381 | + } | |
382 | + | |
383 | + private void addSceneRuleNode(RuleNode ruleNode, RuleChainMetaData ruleChainMetaData) { | |
384 | + boolean existScene = false; | |
385 | + // check scene exist | |
386 | + for (RuleNode node : ruleChainMetaData.getNodes()) { | |
387 | + if (ruleNode.getName().equals(node.getName()) && ruleNode.getType().equals(node.getType())) { | |
388 | + node.setConfiguration(ruleNode.getConfiguration()); | |
389 | + existScene = true; | |
390 | + break; | |
391 | + } | |
392 | + } | |
393 | + if (!existScene) { | |
394 | + // get Save Timeseries Save Client Attributes | |
395 | + AtomicInteger ruleNodeIndex = new AtomicInteger(); | |
396 | + int layoutX = 1128; | |
397 | + int layoutY = 132; | |
398 | + ObjectNode objectNode = setAdditionalInfo(layoutX, layoutY); | |
399 | + ruleNode.setAdditionalInfo(objectNode); | |
400 | + ruleChainMetaData.getNodes().add(ruleNode); | |
401 | + ruleChainMetaData | |
402 | + .getNodes() | |
403 | + .forEach( | |
404 | + node -> { | |
405 | + if (node.getType() | |
406 | + .equals("org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode") | |
407 | + || node.getType() | |
408 | + .equals("org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode")) { | |
409 | + NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
410 | + nodeConnectionInfo.setFromIndex(ruleNodeIndex.get()); | |
411 | + nodeConnectionInfo.setToIndex(ruleChainMetaData.getNodes().size() - 1); | |
412 | + nodeConnectionInfo.setType(connectionType); | |
413 | + ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
414 | + } | |
415 | + if (node.getType().equals("org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode")) { | |
416 | + NodeConnectionInfo nodeConnectionInfo = new NodeConnectionInfo(); | |
417 | + nodeConnectionInfo.setFromIndex(ruleChainMetaData.getNodes().size() - 1); | |
418 | + nodeConnectionInfo.setToIndex(ruleNodeIndex.get()); | |
419 | + nodeConnectionInfo.setType("RPC Request"); | |
420 | + ruleChainMetaData.getConnections().add(nodeConnectionInfo); | |
421 | + } | |
422 | + ruleNodeIndex.getAndIncrement(); | |
423 | + }); | |
424 | + } | |
425 | + } | |
426 | + | |
427 | + private ObjectNode setAdditionalInfo(int layoutX, int layoutY) { | |
428 | + int randomNum = new Random().nextInt(50); | |
429 | + ObjectNode objectNode = JacksonUtil.newObjectNode(); | |
430 | + objectNode.put("description", ""); | |
431 | + objectNode.put("layoutX", layoutX + randomNum); | |
432 | + objectNode.put("layoutY", layoutY + randomNum); | |
433 | + return objectNode; | |
434 | + } | |
168 | 435 | } | ... | ... |
1 | 1 | package org.thingsboard.server.dao.yunteng.service; |
2 | 2 | |
3 | +import org.thingsboard.server.common.data.rule.RuleChainMetaData; | |
3 | 4 | import org.thingsboard.server.common.data.rule.RuleNode; |
4 | 5 | import org.thingsboard.server.common.data.yunteng.dto.ConvertConfigDTO; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
... | ... | @@ -54,4 +55,9 @@ public interface ConvertConfigService extends BaseService<ConvertConfig> { |
54 | 55 | * @return true已启用 false未启用 |
55 | 56 | */ |
56 | 57 | boolean checkConvertJSStatusEnable(String tenantId); |
58 | + | |
59 | + boolean deleteRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType); | |
60 | + | |
61 | + void addRuleNode(List<RuleNode> nodes, RuleChainMetaData ruleChainMetaData, Integer nodeType); | |
62 | + | |
57 | 63 | } | ... | ... |
... | ... | @@ -25,7 +25,8 @@ public class TbSceneReactNodeConfig implements NodeConfiguration<TbSceneReactNod |
25 | 25 | @Override |
26 | 26 | public TbSceneReactNodeConfig defaultConfiguration() { |
27 | 27 | TbSceneReactNodeConfig config = new TbSceneReactNodeConfig(); |
28 | - config.setScenes(new HashMap<>()); | |
28 | + Map<String, List<String>> sceneMap = new HashMap<>(); | |
29 | + config.setScenes(sceneMap); | |
29 | 30 | return config; |
30 | 31 | } |
31 | 32 | } | ... | ... |