...
|
...
|
@@ -4,31 +4,19 @@ |
4
|
4
|
package org.thingsboard.rule.engine.yunteng.scene;
|
5
|
5
|
|
6
|
6
|
import com.fasterxml.jackson.databind.JsonNode;
|
7
|
|
-import com.google.gson.JsonParser;
|
8
|
7
|
import lombok.extern.slf4j.Slf4j;
|
9
|
8
|
import org.thingsboard.common.util.JacksonUtil;
|
10
|
9
|
import org.thingsboard.rule.engine.action.TbAlarmResult;
|
11
|
10
|
import org.thingsboard.rule.engine.api.TbContext;
|
12
|
|
-import org.thingsboard.rule.engine.profile.*;
|
13
|
|
-import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState;
|
14
|
|
-import org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode;
|
15
|
|
-import org.thingsboard.rule.engine.yunteng.utils.TriggerRuleState;
|
16
|
11
|
import org.thingsboard.server.common.data.DataConstants;
|
17
|
|
-import org.thingsboard.server.common.data.device.profile.*;
|
18
|
|
-import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededException;
|
19
|
|
-import org.thingsboard.server.common.data.id.EntityId;
|
20
|
|
-import org.thingsboard.server.common.data.id.TenantId;
|
21
|
|
-import org.thingsboard.server.common.data.kv.AttributeKvEntry;
|
22
|
|
-import org.thingsboard.server.common.data.kv.KvEntry;
|
23
|
|
-import org.thingsboard.server.common.data.query.EntityKeyType;
|
|
12
|
+import org.thingsboard.server.common.data.device.profile.AlarmCondition;
|
|
13
|
+import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter;
|
|
14
|
+import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey;
|
24
|
15
|
import org.thingsboard.server.common.data.rule.RuleNodeState;
|
25
|
16
|
import org.thingsboard.server.common.data.yunteng.dto.TriggerDTO;
|
26
|
17
|
import org.thingsboard.server.common.data.yunteng.utils.SpringBeanUtils;
|
27
|
18
|
import org.thingsboard.server.common.msg.TbMsg;
|
28
|
19
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
29
|
|
-import org.thingsboard.server.common.msg.queue.ServiceQueue;
|
30
|
|
-import org.thingsboard.server.common.msg.session.SessionMsgType;
|
31
|
|
-import org.thingsboard.server.common.transport.adaptor.JsonConverter;
|
32
|
20
|
import org.thingsboard.server.dao.yunteng.entities.DoAction;
|
33
|
21
|
import org.thingsboard.server.dao.yunteng.entities.DoCondition;
|
34
|
22
|
import org.thingsboard.server.dao.yunteng.service.DoActionService;
|
...
|
...
|
@@ -36,6 +24,7 @@ import org.thingsboard.server.dao.yunteng.service.DoConditionService; |
36
|
24
|
import org.thingsboard.server.dao.yunteng.service.TriggerService;
|
37
|
25
|
|
38
|
26
|
import java.util.*;
|
|
27
|
+import java.util.concurrent.ConcurrentHashMap;
|
39
|
28
|
import java.util.concurrent.ExecutionException;
|
40
|
29
|
|
41
|
30
|
@Slf4j
|
...
|
...
|
@@ -48,7 +37,7 @@ class ReactState { |
48
|
37
|
* 键:设备主键
|
49
|
38
|
* 值:设备指标参与的触发器
|
50
|
39
|
*/
|
51
|
|
- private Map<String, TriggerState> triggerState;
|
|
40
|
+ private ConcurrentHashMap<String, TriggerState> triggerState = new ConcurrentHashMap<>();
|
52
|
41
|
|
53
|
42
|
|
54
|
43
|
|
...
|
...
|
@@ -78,21 +67,17 @@ class ReactState { |
78
|
67
|
|
79
|
68
|
|
80
|
69
|
public void process(TbContext ctx, TbMsg msg,String deviceId) throws ExecutionException, InterruptedException {
|
81
|
|
- TriggerState triggerRuleState = getOrCreateTriggerState(deviceId);
|
|
70
|
+ TriggerState triggerState = getOrCreateTriggerState(deviceId);
|
82
|
71
|
boolean matched = false;
|
83
|
|
- if(triggerRuleState != null && actions != null){
|
84
|
|
- if(msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())){
|
85
|
|
- matched = processTelemetry(ctx,msg,triggerRuleState);
|
86
|
|
- }else{
|
87
|
|
- matched = processAttributes(ctx,msg,triggerRuleState);
|
88
|
|
- }
|
|
72
|
+ if(triggerState != null && actions != null){
|
|
73
|
+ matched = triggerState.process(ctx,msg);
|
89
|
74
|
}
|
90
|
75
|
|
91
|
76
|
if(matched){
|
92
|
77
|
// TODO 执行条件
|
93
|
78
|
}
|
94
|
79
|
|
95
|
|
- if(true){
|
|
80
|
+ if(matched){
|
96
|
81
|
// TODO 输出动作
|
97
|
82
|
for(DoAction item: actions){
|
98
|
83
|
// pushMsg();
|
...
|
...
|
@@ -103,69 +88,26 @@ class ReactState { |
103
|
88
|
|
104
|
89
|
|
105
|
90
|
|
106
|
|
- private boolean processAttributes(TbContext ctx, TbMsg msg,TriggerState triggerRuleState) throws ExecutionException, InterruptedException {
|
107
|
|
- boolean stateChanged = false;
|
108
|
|
- Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(msg.getData()));
|
109
|
|
- if (!attributes.isEmpty()) {
|
110
|
|
- SnapshotUpdate update = triggerRuleState.merge(attributes);
|
111
|
|
- stateChanged |= triggerRuleState.process(ctx, msg, update);
|
112
|
|
-
|
113
|
|
- }
|
114
|
|
- return stateChanged;
|
115
|
|
- }
|
116
|
|
-
|
117
|
|
- protected boolean processTelemetry(TbContext ctx, TbMsg msg,TriggerState triggerRuleState) throws ExecutionException, InterruptedException {
|
118
|
|
- boolean stateChanged = false;
|
119
|
|
- Map<Long, List<KvEntry>> tsKvMap = JsonConverter.convertToSortedTelemetry(new JsonParser().parse(msg.getData()), TbMsgTimeseriesNode.getTs(msg));
|
120
|
|
- for (Map.Entry<Long, List<KvEntry>> entry : tsKvMap.entrySet()) {
|
121
|
|
- Long ts = entry.getKey();
|
122
|
|
- List<KvEntry> data = entry.getValue();
|
123
|
|
- SnapshotUpdate update = triggerRuleState.merge( ts, data);
|
124
|
|
- if (update.hasUpdate()) {
|
125
|
|
- stateChanged |= triggerRuleState.process(ctx, msg, update);
|
126
|
|
- }
|
127
|
|
- }
|
128
|
|
-
|
129
|
|
- return stateChanged;
|
130
|
|
- }
|
131
|
|
-
|
132
|
|
-
|
133
|
|
-
|
134
|
|
- private static EntityKeyType getKeyTypeFromScope(String scope) {
|
135
|
|
- switch (scope) {
|
136
|
|
- case DataConstants.CLIENT_SCOPE:
|
137
|
|
- return EntityKeyType.CLIENT_ATTRIBUTE;
|
138
|
|
- case DataConstants.SHARED_SCOPE:
|
139
|
|
- return EntityKeyType.SHARED_ATTRIBUTE;
|
140
|
|
- case DataConstants.SERVER_SCOPE:
|
141
|
|
- return EntityKeyType.SERVER_ATTRIBUTE;
|
142
|
|
- }
|
143
|
|
- return EntityKeyType.ATTRIBUTE;
|
144
|
|
- }
|
145
|
|
-
|
146
|
|
-
|
147
|
|
-
|
148
|
91
|
|
149
|
92
|
|
150
|
93
|
|
151
|
94
|
protected TriggerState getOrCreateTriggerState(String deviceId) {
|
152
|
|
- TriggerState triggerRuleState = triggerState.computeIfAbsent(deviceId
|
153
|
|
- ,a -> {
|
154
|
|
- TriggerService triggerService = SpringBeanUtils.getBean(TriggerService.class);
|
155
|
|
- TriggerDTO trigger =triggerService.getTrigger(reactId,deviceId);
|
156
|
|
- if(trigger == null){
|
157
|
|
- return null;
|
158
|
|
- }
|
159
|
|
- AlarmCondition condition = trigger.getTriggerCondition();
|
160
|
|
- Set<AlarmConditionFilterKey> filterKeys = new HashSet<>();
|
161
|
|
- for(AlarmConditionFilter filter :condition.getCondition()){
|
162
|
|
- filterKeys.add(filter.getKey());
|
163
|
|
- }
|
164
|
|
- TriggerState state = new TriggerState(deviceId,condition, filterKeys,null);
|
165
|
|
- triggerState.put(a, state);
|
166
|
|
- return state;
|
167
|
|
- });
|
168
|
|
- return triggerRuleState;
|
|
95
|
+ if(triggerState.containsKey(deviceId)){
|
|
96
|
+ return triggerState.get(deviceId);
|
|
97
|
+ }
|
|
98
|
+ TriggerService triggerService = SpringBeanUtils.getBean(TriggerService.class);
|
|
99
|
+ TriggerDTO trigger =triggerService.getTrigger(reactId,deviceId);
|
|
100
|
+ if(trigger != null){
|
|
101
|
+ AlarmCondition condition = trigger.getTriggerCondition();
|
|
102
|
+ Set<AlarmConditionFilterKey> filterKeys = new HashSet<>();
|
|
103
|
+ for(AlarmConditionFilter filter :condition.getCondition()){
|
|
104
|
+ filterKeys.add(filter.getKey());
|
|
105
|
+ }
|
|
106
|
+ TriggerState state = new TriggerState(deviceId,condition, filterKeys,null);
|
|
107
|
+ triggerState.put(deviceId, state);
|
|
108
|
+ return state;
|
|
109
|
+ }
|
|
110
|
+ return null;
|
169
|
111
|
}
|
170
|
112
|
|
171
|
113
|
private void pushMsg(TbContext ctx, TbMsg msg, TbAlarmResult alarmResult,DoAction action) {
|
...
|
...
|
|