Skip to content

Commit 635d51e

Browse files
syyyrj4r0u53k
andcommitted
alarms: Add stateAlarm
Co-authored-by: Jaroslav Beran <jara.beran@gmail.com>
1 parent cf972a2 commit 635d51e

1 file changed

Lines changed: 35 additions & 10 deletions

File tree

src/alarm.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,33 @@ impl From<Alarm> for RpcValue {
124124
}
125125
}
126126

127+
trait AlarmGetter {
128+
fn alarm_getter(f: &impl FieldDescriptionMethods) -> Option<&str>;
129+
}
130+
131+
struct CommonAlarm;
132+
impl AlarmGetter for CommonAlarm {
133+
fn alarm_getter(f: &impl FieldDescriptionMethods) -> Option<&str> {
134+
f.alarm()
135+
}
136+
}
137+
138+
struct StateAlarm;
139+
impl AlarmGetter for StateAlarm {
140+
fn alarm_getter(f: &impl FieldDescriptionMethods) -> Option<&str> {
141+
f.state_alarm()
142+
}
143+
}
144+
127145
pub fn collect_alarms(type_info: &TypeInfo, shv_path: impl AsRef<str>, value: &RpcValue) -> Vec<Alarm> {
146+
impl_collect_alarms::<CommonAlarm>(type_info, shv_path, value)
147+
}
148+
149+
pub fn collect_state_alarms(type_info: &TypeInfo, shv_path: impl AsRef<str>, value: &RpcValue) -> Vec<Alarm> {
150+
impl_collect_alarms::<StateAlarm>(type_info, shv_path, value)
151+
}
152+
153+
fn impl_collect_alarms<Getter: AlarmGetter>(type_info: &TypeInfo, shv_path: impl AsRef<str>, value: &RpcValue) -> Vec<Alarm> {
128154
if value.is_null() {
129155
// value not available, keep previous alarms active
130156
return vec![];
@@ -136,7 +162,7 @@ pub fn collect_alarms(type_info: &TypeInfo, shv_path: impl AsRef<str>, value: &R
136162
return vec![];
137163
}
138164

139-
if let Some(alarm) = property_description.alarm() && !alarm.is_empty() {
165+
if let Some(alarm) = Getter::alarm_getter(&property_description) && !alarm.is_empty() {
140166
vec![
141167
Alarm {
142168
path: shv_path.into(),
@@ -148,11 +174,11 @@ pub fn collect_alarms(type_info: &TypeInfo, shv_path: impl AsRef<str>, value: &R
148174
}
149175
]
150176
} else {
151-
collect_alarms_for_type(type_info, shv_path, property_description.type_name().unwrap_or_default(), value)
177+
collect_alarms_for_type::<Getter>(type_info, shv_path, property_description.type_name().unwrap_or_default(), value)
152178
}
153179
}
154180

155-
fn collect_alarms_for_type(type_info: &TypeInfo, shv_path: impl AsRef<str>, type_name: impl AsRef<str>, value: &RpcValue) -> Vec<Alarm> {
181+
fn collect_alarms_for_type<Getter: AlarmGetter>(type_info: &TypeInfo, shv_path: impl AsRef<str>, type_name: impl AsRef<str>, value: &RpcValue) -> Vec<Alarm> {
156182
let Some(type_descr) = type_info.find_type_description(type_name).filter(|descr| descr.is_valid()) else {
157183
return vec![]
158184
};
@@ -164,7 +190,7 @@ fn collect_alarms_for_type(type_info: &TypeInfo, shv_path: impl AsRef<str>, type
164190
.flat_map(|fld_descr| {
165191
let sub_path = format!("{shv_path}/{fld_descr_name}", fld_descr_name = fld_descr.name());
166192
let bitfield_value = fld_descr.bitfield_value(value.as_u64());
167-
if let Some(alarm) = fld_descr.alarm().filter(|alarm| !alarm.is_empty()) {
193+
if let Some(alarm) = Getter::alarm_getter(fld_descr).filter(|alarm| !alarm.is_empty()) {
168194
vec![
169195
Alarm {
170196
path: sub_path,
@@ -176,7 +202,7 @@ fn collect_alarms_for_type(type_info: &TypeInfo, shv_path: impl AsRef<str>, type
176202
}
177203
]
178204
} else {
179-
collect_alarms_for_type(
205+
collect_alarms_for_type::<Getter>(
180206
type_info,
181207
sub_path,
182208
fld_descr.type_name().unwrap_or_default(),
@@ -191,17 +217,16 @@ fn collect_alarms_for_type(type_info: &TypeInfo, shv_path: impl AsRef<str>, type
191217

192218
let has_alarm_definition = fields
193219
.iter()
194-
.any(|field| field
195-
.alarm()
220+
.any(|field| Getter::alarm_getter(field)
196221
.is_some_and(|f| !f.is_empty())
197222
);
198223
if !has_alarm_definition {
199224
return vec![];
200225
}
201226

202227
let active_alarm_field = fields
203-
.iter()
204-
.find(|field| field.alarm().is_some_and(|alarm| !alarm.is_empty())
228+
.into_iter()
229+
.find(|field| Getter::alarm_getter(field).is_some_and(|alarm| !alarm.is_empty())
205230
&& field.bit_range().is_some_and(|bit_range| bit_range.as_u64() == value.as_u64()));
206231
match active_alarm_field {
207232
Some(field) => vec![
@@ -211,7 +236,7 @@ fn collect_alarms_for_type(type_info: &TypeInfo, shv_path: impl AsRef<str>, type
211236
description: field.description().unwrap_or_default().into(),
212237
label: field.label().unwrap_or_default().into(),
213238
level: field.alarm_level().unwrap_or_default(),
214-
severity: field.alarm().unwrap_or_default().into(),
239+
severity: Getter::alarm_getter(&field).unwrap_or_default().into(),
215240
}
216241
],
217242
None => vec![

0 commit comments

Comments
 (0)