Commit 4ac26bc66428380d5b19e2e1d67b944ea1dc7afb
1 parent
291634c1
TbGetTelemetryCertainTimeRangeNode
Showing
2 changed files
with
146 additions
and
0 deletions
1 | +package org.thingsboard.rule.engine.metadata; | ||
2 | + | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
7 | +import com.google.common.util.concurrent.ListenableFuture; | ||
8 | +import lombok.extern.slf4j.Slf4j; | ||
9 | +import org.thingsboard.rule.engine.api.*; | ||
10 | +import org.thingsboard.rule.engine.api.util.DonAsynchron; | ||
11 | +import org.thingsboard.rule.engine.api.util.TbNodeUtils; | ||
12 | +import org.thingsboard.server.common.data.kv.BaseTsKvQuery; | ||
13 | +import org.thingsboard.server.common.data.kv.TsKvEntry; | ||
14 | +import org.thingsboard.server.common.data.kv.TsKvQuery; | ||
15 | +import org.thingsboard.server.common.data.plugin.ComponentType; | ||
16 | +import org.thingsboard.server.common.msg.TbMsg; | ||
17 | + | ||
18 | +import java.util.ArrayList; | ||
19 | +import java.util.List; | ||
20 | +import java.util.concurrent.ExecutionException; | ||
21 | +import java.util.concurrent.TimeUnit; | ||
22 | + | ||
23 | +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; | ||
24 | +import static org.thingsboard.server.common.data.kv.Aggregation.NONE; | ||
25 | + | ||
26 | +/** | ||
27 | + * Created by mshvayka on 04.09.18. | ||
28 | + */ | ||
29 | +@Slf4j | ||
30 | +@RuleNode(type = ComponentType.ENRICHMENT, | ||
31 | + name = "huy", | ||
32 | + configClazz = TbGetTelemetryCertainTimeRangeNodeConfiguration.class, | ||
33 | + nodeDescription = "", | ||
34 | + nodeDetails = "", | ||
35 | + uiResources = "", //{"static/rulenode/rulenode-core-config.js"}, | ||
36 | + configDirective = "") | ||
37 | +public class TbGetTelemetryCertainTimeRangeNode implements TbNode { | ||
38 | + | ||
39 | + private TbGetTelemetryCertainTimeRangeNodeConfiguration config; | ||
40 | + private List<String> tsKeyNames; | ||
41 | + private long startTsOffset; | ||
42 | + private long endTsOffset; | ||
43 | + private int limit; | ||
44 | + private ObjectMapper mapper; | ||
45 | + | ||
46 | + @Override | ||
47 | + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { | ||
48 | + this.config = TbNodeUtils.convert(configuration, TbGetTelemetryCertainTimeRangeNodeConfiguration.class); | ||
49 | + tsKeyNames = config.getLatestTsKeyNames(); | ||
50 | + startTsOffset = TimeUnit.valueOf(config.getStartIntervalTimeUnit()).toMillis(config.getStartInterval()); | ||
51 | + endTsOffset = TimeUnit.valueOf(config.getEndIntervalTimeUnit()).toMillis(config.getEndInterval()); | ||
52 | + limit = config.getFetchMode().equals(TbGetTelemetryCertainTimeRangeNodeConfiguration.FETCH_MODE_ALL) | ||
53 | + ? TbGetTelemetryCertainTimeRangeNodeConfiguration.MAX_FETCH_SIZE : 1; | ||
54 | + mapper = new ObjectMapper(); | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException { | ||
59 | + ObjectNode resultNode = mapper.createObjectNode(); | ||
60 | + List<TsKvQuery> queries = new ArrayList<>(); | ||
61 | + long ts = System.currentTimeMillis(); | ||
62 | + long startTs = ts - startTsOffset; | ||
63 | + long endTs = ts - endTsOffset; | ||
64 | + if (tsKeyNames.isEmpty()) { | ||
65 | + ctx.tellFailure(msg, new Exception("Telemetry not found")); | ||
66 | + } else { | ||
67 | + for (String key : tsKeyNames) { | ||
68 | + //TODO: handle direction; | ||
69 | + queries.add(new BaseTsKvQuery(key, startTs, endTs, 1, limit, NONE)); | ||
70 | + if (limit == TbGetTelemetryCertainTimeRangeNodeConfiguration.MAX_FETCH_SIZE) { | ||
71 | + resultNode.set(key, mapper.createArrayNode()); | ||
72 | + } else { | ||
73 | + resultNode.putObject(key); | ||
74 | + } | ||
75 | + } | ||
76 | + try { | ||
77 | + ListenableFuture<List<TsKvEntry>> list = ctx.getTimeseriesService().findAll(msg.getOriginator(), queries); | ||
78 | + DonAsynchron.withCallback(list, data -> { | ||
79 | + for (TsKvEntry tsKvEntry : data) { | ||
80 | + JsonNode node = resultNode.get(tsKvEntry.getKey()); | ||
81 | + if (node.isArray()) { | ||
82 | + ArrayNode arrayNode = (ArrayNode) node; | ||
83 | + arrayNode.add(mapper.createObjectNode().put(String.valueOf(tsKvEntry.getTs()), tsKvEntry.getValueAsString())); | ||
84 | + } else { | ||
85 | + ObjectNode object = mapper.createObjectNode().put(String.valueOf(tsKvEntry.getTs()), tsKvEntry.getValueAsString()); | ||
86 | + resultNode.set(tsKvEntry.getKey(), object); | ||
87 | + } | ||
88 | + } | ||
89 | + for (String key : tsKeyNames) { | ||
90 | + msg.getMetaData().putValue(key, resultNode.get(key).toString()); | ||
91 | + } | ||
92 | + TbMsg newMsg = ctx.newMsg(msg.getType(), msg.getOriginator(), msg.getMetaData(), msg.getData()); | ||
93 | + ctx.tellNext(newMsg, SUCCESS); | ||
94 | + }, error -> ctx.tellFailure(msg, error)); | ||
95 | + } catch (Exception e) { | ||
96 | + ctx.tellFailure(msg, e); | ||
97 | + } | ||
98 | + } | ||
99 | + } | ||
100 | + | ||
101 | + @Override | ||
102 | + public void destroy() { | ||
103 | + | ||
104 | + } | ||
105 | +} |
1 | +package org.thingsboard.rule.engine.metadata; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | +import org.thingsboard.rule.engine.api.NodeConfiguration; | ||
5 | + | ||
6 | +import java.util.Collections; | ||
7 | +import java.util.List; | ||
8 | +import java.util.concurrent.TimeUnit; | ||
9 | + | ||
10 | +/** | ||
11 | + * Created by mshvayka on 04.09.18. | ||
12 | + */ | ||
13 | +@Data | ||
14 | +public class TbGetTelemetryCertainTimeRangeNodeConfiguration implements NodeConfiguration<TbGetTelemetryCertainTimeRangeNodeConfiguration> { | ||
15 | + | ||
16 | + public static final String FETCH_MODE_FIRST = "FIRST"; | ||
17 | + public static final String FETCH_MODE_LAST = "LAST"; | ||
18 | + public static final String FETCH_MODE_ALL = "ALL"; | ||
19 | + public static final int MAX_FETCH_SIZE = 1000; | ||
20 | + | ||
21 | + private int startInterval; | ||
22 | + private int endInterval; | ||
23 | + private String startIntervalTimeUnit; | ||
24 | + private String endIntervalTimeUnit; | ||
25 | + private String fetchMode; //FIRST, LAST, LATEST | ||
26 | + | ||
27 | + private List<String> latestTsKeyNames; | ||
28 | + | ||
29 | + | ||
30 | + | ||
31 | + @Override | ||
32 | + public TbGetTelemetryCertainTimeRangeNodeConfiguration defaultConfiguration() { | ||
33 | + TbGetTelemetryCertainTimeRangeNodeConfiguration configuration = new TbGetTelemetryCertainTimeRangeNodeConfiguration(); | ||
34 | + configuration.setLatestTsKeyNames(Collections.emptyList()); | ||
35 | + configuration.setStartIntervalTimeUnit(TimeUnit.MINUTES.name()); | ||
36 | + configuration.setStartInterval(1); | ||
37 | + configuration.setEndIntervalTimeUnit(TimeUnit.MINUTES.name()); | ||
38 | + configuration.setEndInterval(2); | ||
39 | + return configuration; | ||
40 | + } | ||
41 | +} |