1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{
date_time::DateTime,
diagnostic_info::DiagnosticInfo,
encoding::DecodingLimits,
extension_object::ExtensionObject,
node_id::NodeId,
node_ids::ObjectId,
service_types::{
DataChangeNotification, EventFieldList, EventNotificationList, MonitoredItemNotification,
NotificationMessage, StatusChangeNotification,
},
status_code::StatusCode,
};
impl NotificationMessage {
pub fn data_change(sequence_number: u32, publish_time: DateTime, data_change_notifications: Vec<MonitoredItemNotification>, event_notifications: Vec<EventFieldList>) -> NotificationMessage {
if data_change_notifications.is_empty() && event_notifications.is_empty() {
panic!("No notifications supplied to data_change()");
}
let mut notification_data = Vec::with_capacity(2);
if !data_change_notifications.is_empty() {
let data_change_notification = DataChangeNotification {
monitored_items: Some(data_change_notifications),
diagnostic_infos: None,
};
trace!("data change notification = {:?}", data_change_notification);
notification_data.push(ExtensionObject::from_encodable(ObjectId::DataChangeNotification_Encoding_DefaultBinary, &data_change_notification));
}
if !event_notifications.is_empty() {
let event_notification_list = EventNotificationList {
events: Some(event_notifications)
};
trace!("event notification = {:?}", event_notification_list);
notification_data.push(ExtensionObject::from_encodable(ObjectId::EventNotificationList_Encoding_DefaultBinary, &event_notification_list));
}
NotificationMessage {
sequence_number,
publish_time,
notification_data: Some(notification_data),
}
}
pub fn status_change(sequence_number: u32, publish_time: DateTime, status: StatusCode) -> NotificationMessage {
let status_change_notification = StatusChangeNotification {
status,
diagnostic_info: DiagnosticInfo::null(),
};
let notification_data = ExtensionObject::from_encodable(ObjectId::StatusChangeNotification_Encoding_DefaultBinary, &status_change_notification);
NotificationMessage {
sequence_number,
publish_time,
notification_data: Some(vec![notification_data]),
}
}
pub fn keep_alive(sequence_number: u32, publish_time: DateTime) -> NotificationMessage {
NotificationMessage {
sequence_number,
publish_time,
notification_data: None,
}
}
pub fn notifications(&self, decoding_limits: &DecodingLimits) -> Option<(Vec<DataChangeNotification>, Vec<EventNotificationList>)> {
if let Some(ref notification_data) = self.notification_data {
let data_change_notification_id: NodeId = ObjectId::DataChangeNotification_Encoding_DefaultBinary.into();
let event_notification_list_id: NodeId = ObjectId::EventNotificationList_Encoding_DefaultBinary.into();
let mut data_changes = Vec::with_capacity(notification_data.len());
let mut events = Vec::with_capacity(notification_data.len());
notification_data.iter().for_each(|n| {
if n.node_id == data_change_notification_id {
if let Ok(v) = n.decode_inner::<DataChangeNotification>(decoding_limits) {
data_changes.push(v);
}
} else if n.node_id == event_notification_list_id {
if let Ok(v) = n.decode_inner::<EventNotificationList>(decoding_limits) {
events.push(v);
}
} else {
debug!("Ignoring a notification of type {:?}", n.node_id);
}
});
if data_changes.is_empty() && events.is_empty() {
None
} else {
Some((data_changes, events))
}
} else {
None
}
}
}