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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// OPCUA for Rust
// SPDX-License-Identifier: MPL-2.0
// Copyright (C) 2017-2024 Adam Lock
//! The OPC UA Client module contains the functionality necessary for a client to connect to an OPC UA server,
//! authenticate itself, send messages, receive responses, get values, browse the address space and
//! provide callbacks for things to be propagated to the client.
//!
//! A client has to specify the endpoint description they wish to connect to, security policy and other
//! configurable options, e.g. paths to PKI keys. All of this is encapsulated in a [`Client`] object.
//!
//! One of these may be made programatically using a [`ClientBuilder`] or from a preexisting [`ClientConfig`]
//! which can be loaded fully or partially from disk. Use the way that suits you.
//!
//! Once the `Client` is created it can connect to a server by creating a [`Session`]. Multiple sessions
//! can be created from the same client. Functions on the [`Session`] correspond to OPC UA services so
//! it can be used to:
//!
//! * Discover endpoints
//! * Activate a session
//! * Create / modify / delete subscriptions
//! * Create / modify / delete monitored items
//! * Read and write values
//! * Browse the address space
//! * Add or remove nodes
//!
//! Functionality is synchronous and housekeeping such as renewing the active session and sending publish requests is
//! handled automatically.
//!
//! Data change and event notifications are via asynchronous callbacks.
//!
//! # Example
//!
//! Here is a complete example of a client that connects to the `samples/simple-server`, subscribes
//! to some values and prints out changes to those values. This example corresponds to the one
//! described in the in docs/client.md tutorial.
//!
//! ```no_run
//! use std::sync::Arc;
//! use opcua::client::prelude::*;
//! use opcua::sync::*;
//!
//! fn main() {
//! let mut client = ClientBuilder::new()
//! .application_name("My First Client")
//! .application_uri("urn:MyFirstClient")
//! .create_sample_keypair(true)
//! .trust_server_certs(false)
//! .session_retry_limit(3)
//! .client().unwrap();
//!
//! // Create an endpoint. The EndpointDescription can be made from a tuple consisting of
//! // the endpoint url, security policy, message security mode and user token policy.
//! let endpoint: EndpointDescription = ("opc.tcp://localhost:4855/", "None", MessageSecurityMode::None, UserTokenPolicy::anonymous()).into();
//!
//! // Create the session
//! let session = client.connect_to_endpoint(endpoint, IdentityToken::Anonymous).unwrap();
//!
//! // Create a subscription and monitored items
//! if subscribe_to_values(session.clone()).is_ok() {
//! let _ = Session::run(session);
//! } else {
//! println!("Error creating subscription");
//! }
//! }
//!
//! fn subscribe_to_values(session: Arc<RwLock<Session>>) -> Result<(), StatusCode> {
//! let mut session = session.write();
//! // Create a subscription polling every 2s with a callback
//! let subscription_id = session.create_subscription(2000.0, 10, 30, 0, 0, true, DataChangeCallback::new(|changed_monitored_items| {
//! println!("Data change from server:");
//! changed_monitored_items.iter().for_each(|item| print_value(item));
//! }))?;
//! // Create some monitored items
//! let items_to_create: Vec<MonitoredItemCreateRequest> = ["v1", "v2", "v3", "v4"].iter()
//! .map(|v| NodeId::new(2, *v).into()).collect();
//! let _ = session.create_monitored_items(subscription_id, TimestampsToReturn::Both, &items_to_create)?;
//! Ok(())
//! }
//!
//! fn print_value(item: &MonitoredItem) {
//! let node_id = &item.item_to_monitor().node_id;
//! let data_value = item.last_value();
//! if let Some(ref value) = data_value.value {
//! println!("Item \"{}\", Value = {:?}", node_id, value);
//! } else {
//! println!("Item \"{}\", Value not found, error: {}", node_id, data_value.status.as_ref().unwrap());
//! }
//!}
//! ```
//!
//! [`Client`]: ./client/struct.Client.html
//! [`ClientConfig`]: ./config/struct.ClientConfig.html
//! [`ClientBuilder`]: ./client_builder/struct.ClientBuilder.html
//! [`Session`]: ./session/struct.Session.html
use crateSupportedMessage;
use crate;
// Use through prelude
/// Process the service result, i.e. where the request "succeeded" but the response
/// contains a failure status code.
pub
pub