Commit b7718b91d4bffd0901a2ce94dfd02174b135ee1e
Merge branch 'develop/3.2' of github.com:thingsboard/thingsboard into develop/3.2
Showing
6 changed files
with
78 additions
and
41 deletions
@@ -243,6 +243,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -243,6 +243,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | + | ||
247 | + | ||
246 | private <T> TransportServiceCallback<Void> getPubAckCallback(final ChannelHandlerContext ctx, final int msgId, final T msg) { | 248 | private <T> TransportServiceCallback<Void> getPubAckCallback(final ChannelHandlerContext ctx, final int msgId, final T msg) { |
247 | return new TransportServiceCallback<Void>() { | 249 | return new TransportServiceCallback<Void>() { |
248 | @Override | 250 | @Override |
@@ -34,7 +34,7 @@ public class JacksonUtil { | @@ -34,7 +34,7 @@ public class JacksonUtil { | ||
34 | return fromValue != null ? OBJECT_MAPPER.convertValue(fromValue, toValueType) : null; | 34 | return fromValue != null ? OBJECT_MAPPER.convertValue(fromValue, toValueType) : null; |
35 | } catch (IllegalArgumentException e) { | 35 | } catch (IllegalArgumentException e) { |
36 | throw new IllegalArgumentException("The given object value: " | 36 | throw new IllegalArgumentException("The given object value: " |
37 | - + fromValue + " cannot be converted to " + toValueType); | 37 | + + fromValue + " cannot be converted to " + toValueType, e); |
38 | } | 38 | } |
39 | } | 39 | } |
40 | 40 | ||
@@ -43,7 +43,7 @@ public class JacksonUtil { | @@ -43,7 +43,7 @@ public class JacksonUtil { | ||
43 | return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null; | 43 | return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null; |
44 | } catch (IOException e) { | 44 | } catch (IOException e) { |
45 | throw new IllegalArgumentException("The given string value: " | 45 | throw new IllegalArgumentException("The given string value: " |
46 | - + string + " cannot be transformed to Json object"); | 46 | + + string + " cannot be transformed to Json object", e); |
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
@@ -52,7 +52,7 @@ public class JacksonUtil { | @@ -52,7 +52,7 @@ public class JacksonUtil { | ||
52 | return value != null ? OBJECT_MAPPER.writeValueAsString(value) : null; | 52 | return value != null ? OBJECT_MAPPER.writeValueAsString(value) : null; |
53 | } catch (JsonProcessingException e) { | 53 | } catch (JsonProcessingException e) { |
54 | throw new IllegalArgumentException("The given Json object value: " | 54 | throw new IllegalArgumentException("The given Json object value: " |
55 | - + value + " cannot be transformed to a String"); | 55 | + + value + " cannot be transformed to a String", e); |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
@@ -71,7 +71,7 @@ public class JacksonUtil { | @@ -71,7 +71,7 @@ public class JacksonUtil { | ||
71 | return fromString(toString(value), (Class<T>) value.getClass()); | 71 | return fromString(toString(value), (Class<T>) value.getClass()); |
72 | } | 72 | } |
73 | 73 | ||
74 | - public static JsonNode valueToTree(Alarm alarm) { | 74 | + public static <T> JsonNode valueToTree(T alarm) { |
75 | return OBJECT_MAPPER.valueToTree(alarm); | 75 | return OBJECT_MAPPER.valueToTree(alarm); |
76 | } | 76 | } |
77 | } | 77 | } |
@@ -47,16 +47,14 @@ import java.util.concurrent.ExecutionException; | @@ -47,16 +47,14 @@ import java.util.concurrent.ExecutionException; | ||
47 | class DeviceProfileAlarmState { | 47 | class DeviceProfileAlarmState { |
48 | 48 | ||
49 | private final EntityId originator; | 49 | private final EntityId originator; |
50 | - private final DeviceProfileAlarm alarmDefinition; | 50 | + private DeviceProfileAlarm alarmDefinition; |
51 | private volatile Map<AlarmSeverity, AlarmRule> createRulesSortedBySeverityDesc; | 51 | private volatile Map<AlarmSeverity, AlarmRule> createRulesSortedBySeverityDesc; |
52 | private volatile Alarm currentAlarm; | 52 | private volatile Alarm currentAlarm; |
53 | private volatile boolean initialFetchDone; | 53 | private volatile boolean initialFetchDone; |
54 | 54 | ||
55 | public DeviceProfileAlarmState(EntityId originator, DeviceProfileAlarm alarmDefinition) { | 55 | public DeviceProfileAlarmState(EntityId originator, DeviceProfileAlarm alarmDefinition) { |
56 | this.originator = originator; | 56 | this.originator = originator; |
57 | - this.alarmDefinition = alarmDefinition; | ||
58 | - this.createRulesSortedBySeverityDesc = new TreeMap<>(Comparator.comparingInt(AlarmSeverity::ordinal)); | ||
59 | - this.createRulesSortedBySeverityDesc.putAll(alarmDefinition.getCreateRules()); | 57 | + this.updateState(alarmDefinition); |
60 | } | 58 | } |
61 | 59 | ||
62 | public void process(TbContext ctx, TbMsg msg, DeviceDataSnapshot data) throws ExecutionException, InterruptedException { | 60 | public void process(TbContext ctx, TbMsg msg, DeviceDataSnapshot data) throws ExecutionException, InterruptedException { |
@@ -111,6 +109,12 @@ class DeviceProfileAlarmState { | @@ -111,6 +109,12 @@ class DeviceProfileAlarmState { | ||
111 | ctx.tellNext(newMsg, relationType); | 109 | ctx.tellNext(newMsg, relationType); |
112 | } | 110 | } |
113 | 111 | ||
112 | + public void updateState(DeviceProfileAlarm alarm) { | ||
113 | + this.alarmDefinition = alarm; | ||
114 | + this.createRulesSortedBySeverityDesc = new TreeMap<>(Comparator.comparingInt(AlarmSeverity::ordinal)); | ||
115 | + this.createRulesSortedBySeverityDesc.putAll(alarmDefinition.getCreateRules()); | ||
116 | + } | ||
117 | + | ||
114 | private TbAlarmResult calculateAlarmResult(TbContext ctx, AlarmSeverity severity) { | 118 | private TbAlarmResult calculateAlarmResult(TbContext ctx, AlarmSeverity severity) { |
115 | if (currentAlarm != null) { | 119 | if (currentAlarm != null) { |
116 | currentAlarm.setEndTs(System.currentTimeMillis()); | 120 | currentAlarm.setEndTs(System.currentTimeMillis()); |
@@ -20,6 +20,7 @@ import lombok.Getter; | @@ -20,6 +20,7 @@ import lombok.Getter; | ||
20 | import org.thingsboard.server.common.data.DeviceProfile; | 20 | import org.thingsboard.server.common.data.DeviceProfile; |
21 | import org.thingsboard.server.common.data.device.profile.AlarmRule; | 21 | import org.thingsboard.server.common.data.device.profile.AlarmRule; |
22 | import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; | 22 | import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; |
23 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
23 | import org.thingsboard.server.common.data.query.EntityKey; | 24 | import org.thingsboard.server.common.data.query.EntityKey; |
24 | import org.thingsboard.server.common.data.query.KeyFilter; | 25 | import org.thingsboard.server.common.data.query.KeyFilter; |
25 | 26 | ||
@@ -55,4 +56,8 @@ class DeviceProfileState { | @@ -55,4 +56,8 @@ class DeviceProfileState { | ||
55 | } | 56 | } |
56 | } | 57 | } |
57 | } | 58 | } |
59 | + | ||
60 | + public DeviceProfileId getProfileId() { | ||
61 | + return deviceProfile.getId(); | ||
62 | + } | ||
58 | } | 63 | } |
@@ -20,8 +20,10 @@ import org.thingsboard.rule.engine.api.TbContext; | @@ -20,8 +20,10 @@ import org.thingsboard.rule.engine.api.TbContext; | ||
20 | import org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode; | 20 | import org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode; |
21 | import org.thingsboard.server.common.data.DataConstants; | 21 | import org.thingsboard.server.common.data.DataConstants; |
22 | import org.thingsboard.server.common.data.Device; | 22 | import org.thingsboard.server.common.data.Device; |
23 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
23 | import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; | 24 | import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; |
24 | import org.thingsboard.server.common.data.id.DeviceId; | 25 | import org.thingsboard.server.common.data.id.DeviceId; |
26 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
25 | import org.thingsboard.server.common.data.id.EntityId; | 27 | import org.thingsboard.server.common.data.id.EntityId; |
26 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | 28 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
27 | import org.thingsboard.server.common.data.kv.KvEntry; | 29 | import org.thingsboard.server.common.data.kv.KvEntry; |
@@ -40,20 +42,44 @@ import java.util.Set; | @@ -40,20 +42,44 @@ import java.util.Set; | ||
40 | import java.util.concurrent.ConcurrentHashMap; | 42 | import java.util.concurrent.ConcurrentHashMap; |
41 | import java.util.concurrent.ConcurrentMap; | 43 | import java.util.concurrent.ConcurrentMap; |
42 | import java.util.concurrent.ExecutionException; | 44 | import java.util.concurrent.ExecutionException; |
45 | +import java.util.stream.Collectors; | ||
43 | 46 | ||
44 | class DeviceState { | 47 | class DeviceState { |
45 | 48 | ||
49 | + private final DeviceId deviceId; | ||
46 | private DeviceProfileState deviceProfile; | 50 | private DeviceProfileState deviceProfile; |
47 | private DeviceDataSnapshot latestValues; | 51 | private DeviceDataSnapshot latestValues; |
48 | private final ConcurrentMap<String, DeviceProfileAlarmState> alarmStates = new ConcurrentHashMap<>(); | 52 | private final ConcurrentMap<String, DeviceProfileAlarmState> alarmStates = new ConcurrentHashMap<>(); |
49 | 53 | ||
50 | - public DeviceState(DeviceProfileState deviceProfile) { | 54 | + public DeviceState(DeviceId deviceId, DeviceProfileState deviceProfile) { |
55 | + this.deviceId = deviceId; | ||
51 | this.deviceProfile = deviceProfile; | 56 | this.deviceProfile = deviceProfile; |
52 | } | 57 | } |
53 | 58 | ||
59 | + public void updateProfile(TbContext ctx, DeviceProfile deviceProfile) throws ExecutionException, InterruptedException { | ||
60 | + Set<EntityKey> oldKeys = this.deviceProfile.getEntityKeys(); | ||
61 | + this.deviceProfile.updateDeviceProfile(deviceProfile); | ||
62 | + if (latestValues != null) { | ||
63 | + Set<EntityKey> keysToFetch = new HashSet<>(this.deviceProfile.getEntityKeys()); | ||
64 | + keysToFetch.removeAll(oldKeys); | ||
65 | + if (!keysToFetch.isEmpty()) { | ||
66 | + addEntityKeysToSnapshot(ctx, deviceId, keysToFetch, latestValues); | ||
67 | + } | ||
68 | + } | ||
69 | + Set<String> newAlarmStateIds = this.deviceProfile.getAlarmSettings().stream().map(DeviceProfileAlarm::getId).collect(Collectors.toSet()); | ||
70 | + alarmStates.keySet().removeIf(id -> !newAlarmStateIds.contains(id)); | ||
71 | + for (DeviceProfileAlarm alarm : this.deviceProfile.getAlarmSettings()) { | ||
72 | + if (alarmStates.containsKey(alarm.getId())) { | ||
73 | + alarmStates.get(alarm.getId()).updateState(alarm); | ||
74 | + } else { | ||
75 | + alarmStates.putIfAbsent(alarm.getId(), new DeviceProfileAlarmState(deviceId, alarm)); | ||
76 | + } | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
54 | public void process(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException { | 80 | public void process(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException { |
55 | if (latestValues == null) { | 81 | if (latestValues == null) { |
56 | - latestValues = fetchLatestValues(ctx, msg.getOriginator()); | 82 | + latestValues = fetchLatestValues(ctx, deviceId); |
57 | } | 83 | } |
58 | if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) { | 84 | if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) { |
59 | processTelemetry(ctx, msg); | 85 | processTelemetry(ctx, msg); |
@@ -69,7 +95,7 @@ class DeviceState { | @@ -69,7 +95,7 @@ class DeviceState { | ||
69 | List<KvEntry> data = entry.getValue(); | 95 | List<KvEntry> data = entry.getValue(); |
70 | latestValues = merge(latestValues, ts, data); | 96 | latestValues = merge(latestValues, ts, data); |
71 | for (DeviceProfileAlarm alarm : deviceProfile.getAlarmSettings()) { | 97 | for (DeviceProfileAlarm alarm : deviceProfile.getAlarmSettings()) { |
72 | - DeviceProfileAlarmState alarmState = alarmStates.computeIfAbsent(alarm.getId(), a -> new DeviceProfileAlarmState(msg.getOriginator(), alarm)); | 98 | + DeviceProfileAlarmState alarmState = alarmStates.computeIfAbsent(alarm.getId(), a -> new DeviceProfileAlarmState(deviceId, alarm)); |
73 | alarmState.process(ctx, msg, latestValues); | 99 | alarmState.process(ctx, msg, latestValues); |
74 | } | 100 | } |
75 | } | 101 | } |
@@ -85,8 +111,13 @@ class DeviceState { | @@ -85,8 +111,13 @@ class DeviceState { | ||
85 | } | 111 | } |
86 | 112 | ||
87 | private DeviceDataSnapshot fetchLatestValues(TbContext ctx, EntityId originator) throws ExecutionException, InterruptedException { | 113 | private DeviceDataSnapshot fetchLatestValues(TbContext ctx, EntityId originator) throws ExecutionException, InterruptedException { |
88 | - DeviceDataSnapshot result = new DeviceDataSnapshot(deviceProfile.getEntityKeys()); | 114 | + Set<EntityKey> entityKeysToFetch = deviceProfile.getEntityKeys(); |
115 | + DeviceDataSnapshot result = new DeviceDataSnapshot(entityKeysToFetch); | ||
116 | + addEntityKeysToSnapshot(ctx, originator, entityKeysToFetch, result); | ||
117 | + return result; | ||
118 | + } | ||
89 | 119 | ||
120 | + private void addEntityKeysToSnapshot(TbContext ctx, EntityId originator, Set<EntityKey> entityKeysToFetch, DeviceDataSnapshot result) throws InterruptedException, ExecutionException { | ||
90 | Set<String> serverAttributeKeys = new HashSet<>(); | 121 | Set<String> serverAttributeKeys = new HashSet<>(); |
91 | Set<String> clientAttributeKeys = new HashSet<>(); | 122 | Set<String> clientAttributeKeys = new HashSet<>(); |
92 | Set<String> sharedAttributeKeys = new HashSet<>(); | 123 | Set<String> sharedAttributeKeys = new HashSet<>(); |
@@ -94,7 +125,7 @@ class DeviceState { | @@ -94,7 +125,7 @@ class DeviceState { | ||
94 | Set<String> latestTsKeys = new HashSet<>(); | 125 | Set<String> latestTsKeys = new HashSet<>(); |
95 | 126 | ||
96 | Device device = null; | 127 | Device device = null; |
97 | - for (EntityKey entityKey : deviceProfile.getEntityKeys()) { | 128 | + for (EntityKey entityKey : entityKeysToFetch) { |
98 | String key = entityKey.getKey(); | 129 | String key = entityKey.getKey(); |
99 | switch (entityKey.getType()) { | 130 | switch (entityKey.getType()) { |
100 | case SERVER_ATTRIBUTE: | 131 | case SERVER_ATTRIBUTE: |
@@ -159,8 +190,6 @@ class DeviceState { | @@ -159,8 +190,6 @@ class DeviceState { | ||
159 | addToSnapshot(result, commonAttributeKeys, | 190 | addToSnapshot(result, commonAttributeKeys, |
160 | ctx.getAttributesService().find(ctx.getTenantId(), originator, DataConstants.SERVER_SCOPE, serverAttributeKeys).get()); | 191 | ctx.getAttributesService().find(ctx.getTenantId(), originator, DataConstants.SERVER_SCOPE, serverAttributeKeys).get()); |
161 | } | 192 | } |
162 | - | ||
163 | - return result; | ||
164 | } | 193 | } |
165 | 194 | ||
166 | private void addToSnapshot(DeviceDataSnapshot snapshot, Set<String> commonAttributeKeys, List<AttributeKvEntry> data) { | 195 | private void addToSnapshot(DeviceDataSnapshot snapshot, Set<String> commonAttributeKeys, List<AttributeKvEntry> data) { |
@@ -192,4 +221,8 @@ class DeviceState { | @@ -192,4 +221,8 @@ class DeviceState { | ||
192 | } | 221 | } |
193 | } | 222 | } |
194 | 223 | ||
224 | + public DeviceProfileId getProfileId() { | ||
225 | + return deviceProfile.getProfileId(); | ||
226 | + } | ||
227 | + | ||
195 | } | 228 | } |
@@ -16,15 +16,6 @@ | @@ -16,15 +16,6 @@ | ||
16 | package org.thingsboard.rule.engine.profile; | 16 | package org.thingsboard.rule.engine.profile; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | -import org.apache.commons.lang3.BooleanUtils; | ||
20 | -import org.apache.kafka.clients.producer.KafkaProducer; | ||
21 | -import org.apache.kafka.clients.producer.Producer; | ||
22 | -import org.apache.kafka.clients.producer.ProducerConfig; | ||
23 | -import org.apache.kafka.clients.producer.ProducerRecord; | ||
24 | -import org.apache.kafka.clients.producer.RecordMetadata; | ||
25 | -import org.apache.kafka.common.header.Headers; | ||
26 | -import org.apache.kafka.common.header.internals.RecordHeader; | ||
27 | -import org.apache.kafka.common.header.internals.RecordHeaders; | ||
28 | import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; | 19 | import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; |
29 | import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache; | 20 | import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache; |
30 | import org.thingsboard.rule.engine.api.RuleNode; | 21 | import org.thingsboard.rule.engine.api.RuleNode; |
@@ -32,22 +23,14 @@ import org.thingsboard.rule.engine.api.TbContext; | @@ -32,22 +23,14 @@ import org.thingsboard.rule.engine.api.TbContext; | ||
32 | import org.thingsboard.rule.engine.api.TbNode; | 23 | import org.thingsboard.rule.engine.api.TbNode; |
33 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; | 24 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
34 | import org.thingsboard.rule.engine.api.TbNodeException; | 25 | import org.thingsboard.rule.engine.api.TbNodeException; |
35 | -import org.thingsboard.rule.engine.api.TbRelationTypes; | ||
36 | -import org.thingsboard.rule.engine.api.util.TbNodeUtils; | ||
37 | -import org.thingsboard.rule.engine.kafka.TbKafkaNodeConfiguration; | ||
38 | import org.thingsboard.server.common.data.DeviceProfile; | 26 | import org.thingsboard.server.common.data.DeviceProfile; |
39 | import org.thingsboard.server.common.data.EntityType; | 27 | import org.thingsboard.server.common.data.EntityType; |
40 | import org.thingsboard.server.common.data.id.DeviceId; | 28 | import org.thingsboard.server.common.data.id.DeviceId; |
41 | -import org.thingsboard.server.common.data.id.EntityId; | ||
42 | import org.thingsboard.server.common.data.plugin.ComponentType; | 29 | import org.thingsboard.server.common.data.plugin.ComponentType; |
43 | import org.thingsboard.server.common.msg.TbMsg; | 30 | import org.thingsboard.server.common.msg.TbMsg; |
44 | -import org.thingsboard.server.common.msg.TbMsgMetaData; | 31 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; |
45 | 32 | ||
46 | -import java.nio.charset.Charset; | ||
47 | -import java.nio.charset.StandardCharsets; | ||
48 | -import java.util.HashMap; | ||
49 | import java.util.Map; | 33 | import java.util.Map; |
50 | -import java.util.Properties; | ||
51 | import java.util.concurrent.ConcurrentHashMap; | 34 | import java.util.concurrent.ConcurrentHashMap; |
52 | import java.util.concurrent.ExecutionException; | 35 | import java.util.concurrent.ExecutionException; |
53 | 36 | ||
@@ -76,7 +59,6 @@ public class TbDeviceProfileNode implements TbNode { | @@ -76,7 +59,6 @@ public class TbDeviceProfileNode implements TbNode { | ||
76 | /** | 59 | /** |
77 | * TODO: | 60 | * TODO: |
78 | * 1. Duration in the alarm conditions; | 61 | * 1. Duration in the alarm conditions; |
79 | - * 2. Update of the Profile (rules); | ||
80 | * 3. Update of the Device attributes (client, server and shared); | 62 | * 3. Update of the Device attributes (client, server and shared); |
81 | * 4. Dynamic values evaluation; | 63 | * 4. Dynamic values evaluation; |
82 | */ | 64 | */ |
@@ -86,26 +68,37 @@ public class TbDeviceProfileNode implements TbNode { | @@ -86,26 +68,37 @@ public class TbDeviceProfileNode implements TbNode { | ||
86 | EntityType originatorType = msg.getOriginator().getEntityType(); | 68 | EntityType originatorType = msg.getOriginator().getEntityType(); |
87 | if (EntityType.DEVICE.equals(originatorType)) { | 69 | if (EntityType.DEVICE.equals(originatorType)) { |
88 | DeviceId deviceId = new DeviceId(msg.getOriginator().getId()); | 70 | DeviceId deviceId = new DeviceId(msg.getOriginator().getId()); |
89 | - DeviceState deviceState = getOrCreateDeviceState(ctx, msg, deviceId); | ||
90 | - if (deviceState != null) { | ||
91 | - deviceState.process(ctx, msg); | 71 | + if (msg.getType().equals("ENTITY_UPDATED")) { |
72 | + //TODO: handle if device profile id has changed. | ||
92 | } else { | 73 | } else { |
93 | - ctx.tellFailure(msg, new IllegalStateException("Device profile for device [" + deviceId + "] not found!")); | 74 | + DeviceState deviceState = getOrCreateDeviceState(ctx, deviceId); |
75 | + if (deviceState != null) { | ||
76 | + deviceState.process(ctx, msg); | ||
77 | + } else { | ||
78 | + ctx.tellFailure(msg, new IllegalStateException("Device profile for device [" + deviceId + "] not found!")); | ||
79 | + } | ||
94 | } | 80 | } |
95 | } else if (EntityType.DEVICE_PROFILE.equals(originatorType)) { | 81 | } else if (EntityType.DEVICE_PROFILE.equals(originatorType)) { |
96 | - //TODO: check that the profile rule set was changed. If yes - invalidate the rules. | 82 | + if (msg.getType().equals("ENTITY_UPDATED")) { |
83 | + DeviceProfile deviceProfile = JacksonUtil.fromString(msg.getData(), DeviceProfile.class); | ||
84 | + for (DeviceState state : deviceStates.values()) { | ||
85 | + if (deviceProfile.getId().equals(state.getProfileId())) { | ||
86 | + state.updateProfile(ctx, deviceProfile); | ||
87 | + } | ||
88 | + } | ||
89 | + } | ||
97 | ctx.tellSuccess(msg); | 90 | ctx.tellSuccess(msg); |
98 | } else { | 91 | } else { |
99 | ctx.tellSuccess(msg); | 92 | ctx.tellSuccess(msg); |
100 | } | 93 | } |
101 | } | 94 | } |
102 | 95 | ||
103 | - private DeviceState getOrCreateDeviceState(TbContext ctx, TbMsg msg, DeviceId deviceId) { | 96 | + private DeviceState getOrCreateDeviceState(TbContext ctx, DeviceId deviceId) { |
104 | DeviceState deviceState = deviceStates.get(deviceId); | 97 | DeviceState deviceState = deviceStates.get(deviceId); |
105 | if (deviceState == null) { | 98 | if (deviceState == null) { |
106 | DeviceProfile deviceProfile = cache.get(ctx.getTenantId(), deviceId); | 99 | DeviceProfile deviceProfile = cache.get(ctx.getTenantId(), deviceId); |
107 | if (deviceProfile != null) { | 100 | if (deviceProfile != null) { |
108 | - deviceState = new DeviceState(new DeviceProfileState(deviceProfile)); | 101 | + deviceState = new DeviceState(deviceId, new DeviceProfileState(deviceProfile)); |
109 | deviceStates.put(deviceId, deviceState); | 102 | deviceStates.put(deviceId, deviceState); |
110 | } | 103 | } |
111 | } | 104 | } |