use super::*;
fn setup_bitstring(
pv: &[u8],
mask: &[u8],
alarm_values: Vec<Vec<u8>>,
) -> (ObjectDatabase, ObjectIdentifier) {
let oid = ObjectIdentifier::new(ObjectType::BINARY_INPUT, 10).unwrap();
let mut obj = MockObject::new(oid);
obj.set(
PropertyIdentifier::EVENT_TYPE,
PropertyValue::Enumerated(EventType::CHANGE_OF_BITSTRING.to_raw()),
);
obj.set(
PropertyIdentifier::EVENT_ENABLE,
PropertyValue::Unsigned(0x07),
);
obj.set(
PropertyIdentifier::EVENT_STATE,
PropertyValue::Enumerated(EventState::NORMAL.to_raw()),
);
obj.set(
PropertyIdentifier::PRESENT_VALUE,
PropertyValue::BitString {
unused_bits: 0,
data: pv.to_vec(),
},
);
obj.set(
PropertyIdentifier::BIT_MASK,
PropertyValue::BitString {
unused_bits: 0,
data: mask.to_vec(),
},
);
obj.set(PropertyIdentifier::TIME_DELAY, PropertyValue::Unsigned(0));
let alarm_pvs: Vec<PropertyValue> = alarm_values
.into_iter()
.map(|d| PropertyValue::BitString {
unused_bits: 0,
data: d,
})
.collect();
obj.set(
PropertyIdentifier::ALARM_VALUES,
PropertyValue::List(alarm_pvs),
);
let mut db = ObjectDatabase::new();
db.add(Box::new(obj)).unwrap();
(db, oid)
}
#[test]
fn cob_normal_to_offnormal() {
let (db, _oid) = setup_bitstring(&[0xFF], &[0x0F], vec![vec![0x0F]]);
let mut engine = IntrinsicReportingEngine::new();
let events = engine.evaluate(&db);
assert_eq!(events.len(), 1);
assert_eq!(events[0].change.to, EventState::OFFNORMAL);
}
#[test]
fn cob_stays_normal_no_match() {
let (db, _) = setup_bitstring(&[0xFF], &[0x0F], vec![vec![0x03]]);
let mut engine = IntrinsicReportingEngine::new();
assert!(engine.evaluate(&db).is_empty());
}
#[test]
fn cob_offnormal_to_normal() {
let (mut db, oid) = setup_bitstring(&[0xFF], &[0x0F], vec![vec![0x0F]]);
let mut engine = IntrinsicReportingEngine::new();
let events = engine.evaluate(&db);
assert_eq!(events[0].change.to, EventState::OFFNORMAL);
let obj = db.get_mut(&oid).unwrap();
obj.write_property(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::BitString {
unused_bits: 0,
data: vec![0xF0],
},
None,
)
.unwrap();
let events = engine.evaluate(&db);
assert_eq!(events.len(), 1);
assert_eq!(events[0].change.to, EventState::NORMAL);
}
#[test]
fn cob_time_delay() {
let oid = ObjectIdentifier::new(ObjectType::BINARY_INPUT, 11).unwrap();
let mut obj = MockObject::new(oid);
obj.set(
PropertyIdentifier::EVENT_TYPE,
PropertyValue::Enumerated(EventType::CHANGE_OF_BITSTRING.to_raw()),
);
obj.set(
PropertyIdentifier::EVENT_ENABLE,
PropertyValue::Unsigned(0x07),
);
obj.set(
PropertyIdentifier::EVENT_STATE,
PropertyValue::Enumerated(EventState::NORMAL.to_raw()),
);
obj.set(
PropertyIdentifier::PRESENT_VALUE,
PropertyValue::BitString {
unused_bits: 0,
data: vec![0xFF],
},
);
obj.set(
PropertyIdentifier::BIT_MASK,
PropertyValue::BitString {
unused_bits: 0,
data: vec![0xFF],
},
);
obj.set(PropertyIdentifier::TIME_DELAY, PropertyValue::Unsigned(2));
obj.set(
PropertyIdentifier::ALARM_VALUES,
PropertyValue::List(vec![PropertyValue::BitString {
unused_bits: 0,
data: vec![0xFF],
}]),
);
let mut db = ObjectDatabase::new();
db.add(Box::new(obj)).unwrap();
let mut engine = IntrinsicReportingEngine::new();
assert!(engine.evaluate(&db).is_empty());
assert!(engine.evaluate(&db).is_empty());
let events = engine.evaluate(&db);
assert_eq!(events.len(), 1);
}