Browse Source

DeviceProfileRuleNode

pull/3551/head
Andrii Shvaika 6 years ago
parent
commit
1278339e61
  1. 5
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java
  2. 35
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionSpec.java
  3. 24
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionSpecType.java
  4. 1
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java
  5. 35
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java
  6. 24
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmScheduleType.java
  7. 25
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java
  8. 33
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java
  9. 30
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeScheduleItem.java
  10. 32
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java
  11. 31
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java
  12. 26
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java
  13. 35
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java
  14. 107
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java
  15. 16
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java
  16. 29
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNode.java
  17. 1
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/state/PersistedAlarmRuleState.java

5
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.common.data.device.profile; package org.thingsboard.server.common.data.device.profile;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.query.KeyFilter; import org.thingsboard.server.common.data.query.KeyFilter;
@ -22,10 +23,10 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Data @Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmCondition { public class AlarmCondition {
private List<KeyFilter> condition; private List<KeyFilter> condition;
private TimeUnit durationUnit; private AlarmConditionSpec spec;
private long durationValue;
} }

35
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionSpec.java

@ -0,0 +1,35 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = SimpleAlarmConditionSpec.class, name = "SIMPLE"),
@JsonSubTypes.Type(value = DurationAlarmConditionSpec.class, name = "DURATION"),
@JsonSubTypes.Type(value = RepeatingAlarmConditionSpec.class, name = "REPEATING")})
public interface AlarmConditionSpec {
AlarmConditionSpecType getType();
}

24
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionSpecType.java

@ -0,0 +1,24 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
public enum AlarmConditionSpecType {
SIMPLE,
DURATION,
REPEATING
}

1
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java

@ -21,6 +21,7 @@ import lombok.Data;
public class AlarmRule { public class AlarmRule {
private AlarmCondition condition; private AlarmCondition condition;
private AlarmSchedule schedule;
// Advanced // Advanced
private String alarmDetails; private String alarmDetails;

35
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java

@ -0,0 +1,35 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = SimpleAlarmConditionSpec.class, name = "ANY_TIME"),
@JsonSubTypes.Type(value = DurationAlarmConditionSpec.class, name = "SPECIFIC_TIME"),
@JsonSubTypes.Type(value = RepeatingAlarmConditionSpec.class, name = "CUSTOM")})
public interface AlarmSchedule {
AlarmScheduleType getType();
}

24
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmScheduleType.java

@ -0,0 +1,24 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
public enum AlarmScheduleType {
ANY_TIME,
SPECIFIC_TIME,
CUSTOM
}

25
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java

@ -0,0 +1,25 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
public class AnyTimeSchedule implements AlarmSchedule {
@Override
public AlarmScheduleType getType() {
return AlarmScheduleType.ANY_TIME;
}
}

33
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java

@ -0,0 +1,33 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
import java.util.List;
@Data
public class CustomTimeSchedule implements AlarmSchedule {
private String timezone;
private List<CustomTimeScheduleItem> items;
@Override
public AlarmScheduleType getType() {
return AlarmScheduleType.CUSTOM;
}
}

30
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeScheduleItem.java

@ -0,0 +1,30 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
import java.util.List;
@Data
public class CustomTimeScheduleItem {
private boolean enabled;
private Integer dayOfWeek;
private long startsOn;
private long endsOn;
}

32
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
import java.util.concurrent.TimeUnit;
@Data
public class DurationAlarmConditionSpec implements AlarmConditionSpec {
private TimeUnit unit;
private long value;
@Override
public AlarmConditionSpecType getType() {
return AlarmConditionSpecType.SIMPLE;
}
}

31
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
import java.util.concurrent.TimeUnit;
@Data
public class RepeatingAlarmConditionSpec implements AlarmConditionSpec {
private int count;
@Override
public AlarmConditionSpecType getType() {
return AlarmConditionSpecType.SIMPLE;
}
}

26
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
@Data
public class SimpleAlarmConditionSpec implements AlarmConditionSpec {
@Override
public AlarmConditionSpecType getType() {
return AlarmConditionSpecType.SIMPLE;
}
}

35
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java

@ -0,0 +1,35 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.profile;
import lombok.Data;
import java.util.List;
@Data
public class SpecificTimeSchedule implements AlarmSchedule {
private String timezone;
private List<Integer> daysOfWeek;
private long startsOn;
private long endsOn;
@Override
public AlarmScheduleType getType() {
return AlarmScheduleType.SPECIFIC_TIME;
}
}

107
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java

@ -19,7 +19,11 @@ import lombok.Data;
import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState; import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.device.profile.AlarmCondition; import org.thingsboard.server.common.data.device.profile.AlarmCondition;
import org.thingsboard.server.common.data.device.profile.AlarmConditionSpec;
import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.AlarmRule;
import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec;
import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec;
import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec;
import org.thingsboard.server.common.data.query.BooleanFilterPredicate; import org.thingsboard.server.common.data.query.BooleanFilterPredicate;
import org.thingsboard.server.common.data.query.ComplexFilterPredicate; import org.thingsboard.server.common.data.query.ComplexFilterPredicate;
import org.thingsboard.server.common.data.query.KeyFilter; import org.thingsboard.server.common.data.query.KeyFilter;
@ -32,7 +36,9 @@ public class AlarmRuleState {
private final AlarmSeverity severity; private final AlarmSeverity severity;
private final AlarmRule alarmRule; private final AlarmRule alarmRule;
private final AlarmConditionSpec spec;
private final long requiredDurationInMs; private final long requiredDurationInMs;
private final long requiredRepeats;
private PersistedAlarmRuleState state; private PersistedAlarmRuleState state;
private boolean updateFlag; private boolean updateFlag;
@ -42,13 +48,31 @@ public class AlarmRuleState {
if (state != null) { if (state != null) {
this.state = state; this.state = state;
} else { } else {
this.state = new PersistedAlarmRuleState(0L, 0L); this.state = new PersistedAlarmRuleState(0L, 0L, 0L);
} }
if (alarmRule.getCondition().getDurationValue() > 0) { this.spec = getSpec(alarmRule);
requiredDurationInMs = alarmRule.getCondition().getDurationUnit().toMillis(alarmRule.getCondition().getDurationValue()); long requiredDurationInMs = 0;
} else { long requiredRepeats = 0;
requiredDurationInMs = 0; switch (spec.getType()) {
case DURATION:
DurationAlarmConditionSpec duration = (DurationAlarmConditionSpec) spec;
requiredDurationInMs = duration.getUnit().toMillis(duration.getValue());
break;
case REPEATING:
RepeatingAlarmConditionSpec repeating = (RepeatingAlarmConditionSpec) spec;
requiredRepeats = repeating.getCount();
break;
} }
this.requiredDurationInMs = requiredDurationInMs;
this.requiredRepeats = requiredRepeats;
}
public AlarmConditionSpec getSpec(AlarmRule alarmRule) {
AlarmConditionSpec spec = alarmRule.getCondition().getSpec();
if (spec == null) {
spec = new SimpleAlarmConditionSpec();
}
return spec;
} }
public boolean checkUpdate() { public boolean checkUpdate() {
@ -61,38 +85,70 @@ public class AlarmRuleState {
} }
public boolean eval(DeviceDataSnapshot data) { public boolean eval(DeviceDataSnapshot data) {
if (requiredDurationInMs > 0) { switch (spec.getType()) {
boolean eval = eval(alarmRule.getCondition(), data); case SIMPLE:
if (eval) { return eval(alarmRule.getCondition(), data);
if (state.getLastEventTs() > 0) { case DURATION:
if (data.getTs() > state.getLastEventTs()) { return evalDuration(data);
state.setDuration(state.getDuration() + (data.getTs() - state.getLastEventTs())); case REPEATING:
state.setLastEventTs(data.getTs()); return evalRepeating(data);
updateFlag = true; default:
} return false;
} else { }
}
private boolean evalRepeating(DeviceDataSnapshot data) {
boolean eval = eval(alarmRule.getCondition(), data);
if (eval) {
state.setEventCount(state.getEventCount() + 1);
updateFlag = true;
return state.getEventCount() > requiredRepeats;
} else {
if (state.getEventCount() > 0) {
state.setEventCount(0L);
updateFlag = true;
}
return false;
}
}
private boolean evalDuration(DeviceDataSnapshot data) {
boolean eval = eval(alarmRule.getCondition(), data);
if (eval) {
if (state.getLastEventTs() > 0) {
if (data.getTs() > state.getLastEventTs()) {
state.setDuration(state.getDuration() + (data.getTs() - state.getLastEventTs()));
state.setLastEventTs(data.getTs()); state.setLastEventTs(data.getTs());
state.setDuration(0L);
updateFlag = true; updateFlag = true;
} }
return state.getDuration() > requiredDurationInMs;
} else { } else {
state.setLastEventTs(0L); state.setLastEventTs(data.getTs());
state.setDuration(0L); state.setDuration(0L);
updateFlag = true; updateFlag = true;
return false;
} }
return state.getDuration() > requiredDurationInMs;
} else { } else {
return eval(alarmRule.getCondition(), data); if (state.getLastEventTs() > 0 || state.getDuration() > 0) {
state.setLastEventTs(0L);
state.setDuration(0L);
updateFlag = true;
}
return false;
} }
} }
public boolean eval(long ts) { public boolean eval(long ts) {
if (requiredDurationInMs > 0 && state.getLastEventTs() > 0 && ts > state.getLastEventTs()) { switch (spec.getType()) {
long duration = state.getDuration() + (ts - state.getLastEventTs()); case SIMPLE:
return duration > requiredDurationInMs; case REPEATING:
} else { return false;
return false; case DURATION:
if (requiredDurationInMs > 0 && state.getLastEventTs() > 0 && ts > state.getLastEventTs()) {
long duration = state.getDuration() + (ts - state.getLastEventTs());
return duration > requiredDurationInMs;
}
default:
return false;
} }
} }
@ -144,7 +200,6 @@ public class AlarmRuleState {
} }
} }
private boolean evalBoolPredicate(EntityKeyValue ekv, BooleanFilterPredicate predicate) { private boolean evalBoolPredicate(EntityKeyValue ekv, BooleanFilterPredicate predicate) {
Boolean value; Boolean value;
switch (ekv.getDataType()) { switch (ekv.getDataType()) {

16
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java

@ -62,18 +62,22 @@ class DeviceState {
private DeviceDataSnapshot latestValues; private DeviceDataSnapshot latestValues;
private final ConcurrentMap<String, DeviceProfileAlarmState> alarmStates = new ConcurrentHashMap<>(); private final ConcurrentMap<String, DeviceProfileAlarmState> alarmStates = new ConcurrentHashMap<>();
public DeviceState(TbContext ctx, TbDeviceProfileNodeConfiguration config, DeviceId deviceId, DeviceProfileState deviceProfile) { public DeviceState(TbContext ctx, TbDeviceProfileNodeConfiguration config, DeviceId deviceId, DeviceProfileState deviceProfile, RuleNodeState state) {
this.persistState = config.isPersistAlarmRulesState(); this.persistState = config.isPersistAlarmRulesState();
this.deviceId = deviceId; this.deviceId = deviceId;
this.deviceProfile = deviceProfile; this.deviceProfile = deviceProfile;
if (config.isPersistAlarmRulesState()) { if (config.isPersistAlarmRulesState()) {
state = ctx.findRuleNodeStateForEntity(deviceId);
if (state != null) { if (state != null) {
pds = JacksonUtil.fromString(state.getStateData(), PersistedDeviceState.class); this.state = state;
} else { } else {
state = new RuleNodeState(); this.state = ctx.findRuleNodeStateForEntity(deviceId);
state.setRuleNodeId(ctx.getSelfId()); }
state.setEntityId(deviceId); if (this.state != null) {
pds = JacksonUtil.fromString(this.state.getStateData(), PersistedDeviceState.class);
} else {
this.state = new RuleNodeState();
this.state.setRuleNodeId(ctx.getSelfId());
this.state.setEntityId(deviceId);
pds = new PersistedDeviceState(); pds = new PersistedDeviceState();
pds.setAlarmStates(new HashMap<>()); pds.setAlarmStates(new HashMap<>());
} }

29
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNode.java

@ -30,6 +30,8 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleNodeState; import org.thingsboard.server.common.data.rule.RuleNodeState;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@ -65,11 +67,28 @@ public class TbDeviceProfileNode implements TbNode {
this.config = TbNodeUtils.convert(configuration, TbDeviceProfileNodeConfiguration.class); this.config = TbNodeUtils.convert(configuration, TbDeviceProfileNodeConfiguration.class);
this.cache = ctx.getDeviceProfileCache(); this.cache = ctx.getDeviceProfileCache();
scheduleAlarmHarvesting(ctx); scheduleAlarmHarvesting(ctx);
//TODO: launch a process of fetching the alarm rule states from the database; if (config.isFetchAlarmRulesStateOnStart()) {
PageLink pageLink = new PageLink(1024);
while (true) {
PageData<RuleNodeState> states = ctx.findRuleNodeStates(pageLink);
if (!states.getData().isEmpty()) {
for (RuleNodeState rns : states.getData()) {
if (rns.getEntityId().getEntityType().equals(EntityType.DEVICE) && ctx.isLocalEntity(rns.getEntityId())) {
getOrCreateDeviceState(ctx, new DeviceId(rns.getEntityId().getId()), rns);
}
}
}
if (!states.hasNext()) {
break;
} else {
pageLink = pageLink.nextPageLink();
}
}
}
} }
/** /**
* 2. Dynamic values evaluation; * TODO: Dynamic values evaluation;
*/ */
@Override @Override
public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException { public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException {
@ -85,7 +104,7 @@ public class TbDeviceProfileNode implements TbNode {
} else if (msg.getType().equals(DataConstants.ENTITY_DELETED)) { } else if (msg.getType().equals(DataConstants.ENTITY_DELETED)) {
deviceStates.remove(deviceId); deviceStates.remove(deviceId);
} else { } else {
DeviceState deviceState = getOrCreateDeviceState(ctx, deviceId); DeviceState deviceState = getOrCreateDeviceState(ctx, deviceId, null);
if (deviceState != null) { if (deviceState != null) {
deviceState.process(ctx, msg); deviceState.process(ctx, msg);
} else { } else {
@ -124,12 +143,12 @@ public class TbDeviceProfileNode implements TbNode {
deviceStates.clear(); deviceStates.clear();
} }
protected DeviceState getOrCreateDeviceState(TbContext ctx, DeviceId deviceId) { protected DeviceState getOrCreateDeviceState(TbContext ctx, DeviceId deviceId, RuleNodeState rns) {
DeviceState deviceState = deviceStates.get(deviceId); DeviceState deviceState = deviceStates.get(deviceId);
if (deviceState == null) { if (deviceState == null) {
DeviceProfile deviceProfile = cache.get(ctx.getTenantId(), deviceId); DeviceProfile deviceProfile = cache.get(ctx.getTenantId(), deviceId);
if (deviceProfile != null) { if (deviceProfile != null) {
deviceState = new DeviceState(ctx, config, deviceId, new DeviceProfileState(deviceProfile)); deviceState = new DeviceState(ctx, config, deviceId, new DeviceProfileState(deviceProfile), rns);
deviceStates.put(deviceId, deviceState); deviceStates.put(deviceId, deviceState);
} }
} }

1
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/state/PersistedAlarmRuleState.java

@ -26,5 +26,6 @@ public class PersistedAlarmRuleState {
private long lastEventTs; private long lastEventTs;
private long duration; private long duration;
private long eventCount;
} }

Loading…
Cancel
Save