前面分析设备相关的时候我们提到设备,其中设备配置类里面有个json类的字段,也就profileData,继续跟踪代码发现这个类,最终实例化为DeviceProfileData类,具体定义
public class DeviceProfileData implements Serializable { @ApiModelProperty(position = 1, value = "JSON object of device profile configuration") private DeviceProfileConfiguration configuration; @Valid @ApiModelProperty(position = 2, value = "JSON object of device profile transport configuration") private DeviceProfileTransportConfiguration transportConfiguration; @ApiModelProperty(position = 3, value = "JSON object of provisioning strategy type per device profile") private DeviceProfileProvisionConfiguration provisionConfiguration; @Valid @ApiModelProperty(position = 4, value = "JSON array of alarm rules configuration per device profile") private List<DeviceProfileAlarm> alarms; }
其中前几个属性,我们暂时不讲,我们关心的是最后一个属性,也是最重要的一个属性,alarms这个列表中,保存着产生报警的规则。那就继续跟踪DeviceProfileAlarm这个类
public class DeviceProfileAlarm implements Serializable { @ApiModelProperty(position = 1, value = "String value representing the alarm rule id", example = "highTemperatureAlarmID") private String id; @Length(fieldName = "alarm type") @NoXss @ApiModelProperty(position = 2, value = "String value representing type of the alarm", example = "High Temperature Alarm") private String alarmType; @Valid @ApiModelProperty(position = 3, value = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + "There can be 5 create alarm rules configured per a single alarm type. See method implementation notes and AlarmRule model for more details") private TreeMap<AlarmSeverity, AlarmRule> createRules; @Valid @ApiModelProperty(position = 4, value = "JSON object representing clear alarm rule") private AlarmRule clearRule; // Hidden in advanced settings @ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; @ApiModelProperty(position = 6, value = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List<String> propagateRelationTypes; }
前两个属性很好理解,一个是id,一个叫type其实我认为就是报警名字,如高温报警、越界报警等等。
接下来两个属性,我觉得是是重点,一个是产生报警的规则MAP,一个是清除报警的规则,这里产生报警的规则是个列表,清除的规则只是一个规则,map的健值是表示的报警的级别,thingsboard中分为5个级别,这个在后面处理的是非常有用。清除报警只需要设置一个规则,就够了。
最后两个是报警传播的配置,我们也房子后面分析。
接下来就到了具体报警规则AlarmRule
public class AlarmRule implements Serializable { @Valid @ApiModelProperty(position = 1, value = "JSON object representing the alarm rule condition") private AlarmCondition condition; @ApiModelProperty(position = 2, value = "JSON object representing time interval during which the rule is active") private AlarmSchedule schedule; // Advanced @NoXss @ApiModelProperty(position = 3, value = "String value representing the additional details for an alarm rule") private String alarmDetails; @ApiModelProperty(position = 4, value = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") private DashboardId dashboardId; }
我们只研究前两个属性,condition就是产生或者清除报警的条件,第二个schedule是产生报警的时间,有几种,一直产生,固定时间段,循环时间段,就想咱们手机的闹钟设定。
我们还是先看AlarmCondition
public class AlarmCondition implements Serializable { @Valid @ApiModelProperty(position = 1, value = "JSON array of alarm condition filters") private List<AlarmConditionFilter> condition; @ApiModelProperty(position = 2, value = "JSON object representing alarm condition type") private AlarmConditionSpec spec;//分为简单,期间,和重复 }
首先是产生的条件AlarmConditionFilter
@ApiModel @Data public class AlarmConditionFilter implements Serializable { @Valid @ApiModelProperty(position = 1, value = "JSON object for specifying alarm condition by specific key") private AlarmConditionFilterKey key; //制定产生报警的属性或者遥测数据的健,如遥测数据的当前温度 @ApiModelProperty(position = 2, value = "String representation of the type of the value", example = "NUMERIC") private EntityKeyValueType valueType;//数据来源的类型,目前4中数字,字符串,日期、开关 @NoXss @ApiModelProperty(position = 3, value = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") private Object value; @Valid @ApiModelProperty(position = 4, value = "JSON object representing filter condition") private KeyFilterPredicate predicate;//计算条件,接下来详细分析 }
重点分析KeyFilterPredicate
@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = StringFilterPredicate.class, name = "STRING"), @JsonSubTypes.Type(value = NumericFilterPredicate.class, name = "NUMERIC"), @JsonSubTypes.Type(value = BooleanFilterPredicate.class, name = "BOOLEAN"), @JsonSubTypes.Type(value = ComplexFilterPredicate.class, name = "COMPLEX")}) public interface KeyFilterPredicate extends Serializable { @JsonIgnore FilterPredicateType getType(); }
这里可以看出来,他有4个实现,我们分析一个,
@Data public class NumericFilterPredicate implements SimpleKeyFilterPredicate<Double> { private NumericOperation operation; //计算符合,等于,大于,不等于这些 private FilterPredicateValue<Double> value; //设定值,这个设计也比较有意思 @Override public FilterPredicateType getType() { return FilterPredicateType.NUMERIC; } public enum NumericOperation { EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL } }
public class FilterPredicateValue<T> implements Serializable { @Getter @NoXss private final T defaultValue; @Getter @NoXss private final T userValue; @Getter @Valid private final DynamicValue<T> dynamicValue; public FilterPredicateValue(T defaultValue) { this(defaultValue, null, null); } @JsonCreator public FilterPredicateValue(@JsonProperty("defaultValue") T defaultValue, @JsonProperty("userValue") T userValue, @JsonProperty("dynamicValue") DynamicValue<T> dynamicValue) { this.defaultValue = defaultValue; this.userValue = userValue; this.dynamicValue = dynamicValue; } @JsonIgnore public T getValue() { if (this.userValue != null) { return this.userValue; } else { if (this.dynamicValue != null && this.dynamicValue.getResolvedValue() != null) { return this.dynamicValue.getResolvedValue(); } else { return defaultValue; } } } public static FilterPredicateValue<Double> fromDouble(double value) { return new FilterPredicateValue<>(value); } public static FilterPredicateValue<String> fromString(String value) { return new FilterPredicateValue<>(value); } public static FilterPredicateValue<Boolean> fromBoolean(boolean value) { return new FilterPredicateValue<>(value); } }
这类可以设置三个值,依次是缺省值,就是对应的一个固定值。在其他两个值没有的情况下取用,最有意思就是DynamicValue,这个参数,可以制定动态取值的来源,也就是对应的属性的健值,还有一个就是取值的范围,当前用户,当前租户,当前客户,以及当前的设备。也是计算过程中最优先取得值,只有他为空的时候才会取接下的值。
这里面有个比较特殊就是ComplexFilterPredicate,就是几个条件的计算。可以时候or和and。
今天先说到这里,因为要一直,所以必须弄清楚这里面的关系,具体移植中,做了相应的调整,后面我们会谈到,下一篇打算说一下,他的计算过程。