Merge branch 'fix/device-profile' of https://github.com/YevhenBondarenko/thingsboard
This commit is contained in:
		
						commit
						1104c4e8f6
					
				@ -229,18 +229,10 @@ class AlarmRuleState {
 | 
				
			|||||||
        long repeatingTimes = 0;
 | 
					        long repeatingTimes = 0;
 | 
				
			||||||
        AlarmConditionSpec alarmConditionSpec = getSpec();
 | 
					        AlarmConditionSpec alarmConditionSpec = getSpec();
 | 
				
			||||||
        AlarmConditionSpecType specType = alarmConditionSpec.getType();
 | 
					        AlarmConditionSpecType specType = alarmConditionSpec.getType();
 | 
				
			||||||
        if(specType.equals(AlarmConditionSpecType.REPEATING)) {
 | 
					        if (specType.equals(AlarmConditionSpecType.REPEATING)) {
 | 
				
			||||||
            RepeatingAlarmConditionSpec repeating = (RepeatingAlarmConditionSpec) spec;
 | 
					            RepeatingAlarmConditionSpec repeating = (RepeatingAlarmConditionSpec) spec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            repeatingTimes = repeating.getPredicate().getDefaultValue();
 | 
					            repeatingTimes = resolveDynamicValue(data, repeating.getPredicate());
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (repeating.getPredicate().getDynamicValue() != null &&
 | 
					 | 
				
			||||||
                    repeating.getPredicate().getDynamicValue().getSourceAttribute() != null) {
 | 
					 | 
				
			||||||
                EntityKeyValue repeatingKeyValue = getDynamicPredicateValue(data, repeating.getPredicate().getDynamicValue());
 | 
					 | 
				
			||||||
                if (repeatingKeyValue != null) {
 | 
					 | 
				
			||||||
                    repeatingTimes = repeatingKeyValue.getLngValue();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return repeatingTimes;
 | 
					        return repeatingTimes;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -249,22 +241,33 @@ class AlarmRuleState {
 | 
				
			|||||||
        long durationTimeInMs = 0;
 | 
					        long durationTimeInMs = 0;
 | 
				
			||||||
        AlarmConditionSpec alarmConditionSpec = getSpec();
 | 
					        AlarmConditionSpec alarmConditionSpec = getSpec();
 | 
				
			||||||
        AlarmConditionSpecType specType = alarmConditionSpec.getType();
 | 
					        AlarmConditionSpecType specType = alarmConditionSpec.getType();
 | 
				
			||||||
        if(specType.equals(AlarmConditionSpecType.DURATION)) {
 | 
					        if (specType.equals(AlarmConditionSpecType.DURATION)) {
 | 
				
			||||||
            DurationAlarmConditionSpec duration = (DurationAlarmConditionSpec) spec;
 | 
					            DurationAlarmConditionSpec duration = (DurationAlarmConditionSpec) spec;
 | 
				
			||||||
            TimeUnit timeUnit = duration.getUnit();
 | 
					            TimeUnit timeUnit = duration.getUnit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            durationTimeInMs = timeUnit.toMillis(duration.getPredicate().getDefaultValue());
 | 
					            durationTimeInMs = timeUnit.toMillis(resolveDynamicValue(data, duration.getPredicate()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return durationTimeInMs;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (duration.getPredicate().getDynamicValue() != null &&
 | 
					    private Long resolveDynamicValue(DataSnapshot data, FilterPredicateValue<? extends Number> predicate) {
 | 
				
			||||||
                    duration.getPredicate().getDynamicValue().getSourceAttribute() != null) {
 | 
					        DynamicValue<?> dynamicValue = predicate.getDynamicValue();
 | 
				
			||||||
                EntityKeyValue durationKeyValue = getDynamicPredicateValue(data, duration.getPredicate().getDynamicValue());
 | 
					        Long defaultValue = predicate.getDefaultValue().longValue();
 | 
				
			||||||
                if (durationKeyValue != null) {
 | 
					        if (dynamicValue == null || dynamicValue.getSourceAttribute() == null) {
 | 
				
			||||||
                    durationTimeInMs = timeUnit.toMillis(durationKeyValue.getLngValue());
 | 
					            return defaultValue;
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return durationTimeInMs;
 | 
					        EntityKeyValue keyValue = getDynamicPredicateValue(data, dynamicValue);
 | 
				
			||||||
 | 
					        if (keyValue == null) {
 | 
				
			||||||
 | 
					            return defaultValue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var longValue = getLongValue(keyValue);
 | 
				
			||||||
 | 
					        if (longValue == null) {
 | 
				
			||||||
 | 
					            String sourceAttribute = dynamicValue.getSourceAttribute();
 | 
				
			||||||
 | 
					            throw new NumericParseException(String.format("could not parse attribute [%s: %s] from source!", sourceAttribute, getStrValue(keyValue)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return longValue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public AlarmEvalResult eval(long ts, DataSnapshot dataSnapshot) {
 | 
					    public AlarmEvalResult eval(long ts, DataSnapshot dataSnapshot) {
 | 
				
			||||||
@ -545,4 +548,28 @@ class AlarmRuleState {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static Long getLongValue(EntityKeyValue ekv) {
 | 
				
			||||||
 | 
					        switch (ekv.getDataType()) {
 | 
				
			||||||
 | 
					            case LONG:
 | 
				
			||||||
 | 
					                return ekv.getLngValue();
 | 
				
			||||||
 | 
					            case DOUBLE:
 | 
				
			||||||
 | 
					                return ekv.getDblValue() != null ? ekv.getDblValue().longValue() : null;
 | 
				
			||||||
 | 
					            case BOOLEAN:
 | 
				
			||||||
 | 
					                return ekv.getBoolValue() != null ? (ekv.getBoolValue() ? 1 : 0L) : null;
 | 
				
			||||||
 | 
					            case STRING:
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    return Long.parseLong(ekv.getStrValue());
 | 
				
			||||||
 | 
					                } catch (RuntimeException e) {
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            case JSON:
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    return Long.parseLong(ekv.getJsonValue());
 | 
				
			||||||
 | 
					                } catch (RuntimeException e) {
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ import java.util.function.BiFunction;
 | 
				
			|||||||
@Slf4j
 | 
					@Slf4j
 | 
				
			||||||
class AlarmState {
 | 
					class AlarmState {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final String ERROR_MSG = "Failed to process alarm state for Device [%s]: %s";
 | 
				
			||||||
    private final ProfileState deviceProfile;
 | 
					    private final ProfileState deviceProfile;
 | 
				
			||||||
    private final EntityId originator;
 | 
					    private final EntityId originator;
 | 
				
			||||||
    private DeviceProfileAlarm alarmDefinition;
 | 
					    private DeviceProfileAlarm alarmDefinition;
 | 
				
			||||||
@ -75,12 +76,20 @@ class AlarmState {
 | 
				
			|||||||
        lastMsgMetaData = msg.getMetaData();
 | 
					        lastMsgMetaData = msg.getMetaData();
 | 
				
			||||||
        lastMsgQueueName = msg.getQueueName();
 | 
					        lastMsgQueueName = msg.getQueueName();
 | 
				
			||||||
        this.dataSnapshot = data;
 | 
					        this.dataSnapshot = data;
 | 
				
			||||||
        return createOrClearAlarms(ctx, msg, data, update, AlarmRuleState::eval);
 | 
					        try {
 | 
				
			||||||
 | 
					            return createOrClearAlarms(ctx, msg, data, update, AlarmRuleState::eval);
 | 
				
			||||||
 | 
					        } catch (NumericParseException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException(String.format(ERROR_MSG, originator.getId().toString(), e.getMessage()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean process(TbContext ctx, long ts) throws ExecutionException, InterruptedException {
 | 
					    public boolean process(TbContext ctx, long ts) throws ExecutionException, InterruptedException {
 | 
				
			||||||
        initCurrentAlarm(ctx);
 | 
					        initCurrentAlarm(ctx);
 | 
				
			||||||
        return createOrClearAlarms(ctx, null, ts, null, (alarmState, tsParam) -> alarmState.eval(tsParam, dataSnapshot));
 | 
					        try {
 | 
				
			||||||
 | 
					            return createOrClearAlarms(ctx, null, ts, null, (alarmState, tsParam) -> alarmState.eval(tsParam, dataSnapshot));
 | 
				
			||||||
 | 
					        } catch (NumericParseException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException(String.format(ERROR_MSG, originator.getId().toString(), e.getMessage()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public <T> boolean createOrClearAlarms(TbContext ctx, TbMsg msg, T data, SnapshotUpdate update, BiFunction<AlarmRuleState, T, AlarmEvalResult> evalFunction) {
 | 
					    public <T> boolean createOrClearAlarms(TbContext ctx, TbMsg msg, T data, SnapshotUpdate update, BiFunction<AlarmRuleState, T, AlarmEvalResult> evalFunction) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2022 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.rule.engine.profile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class NumericParseException extends RuntimeException {
 | 
				
			||||||
 | 
					    public NumericParseException(String message) {
 | 
				
			||||||
 | 
					        super(message);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user