Expand description
Rust wrapper for the open62541 library.
§Examples
§Client: Connect to server
Use AsyncClient to asynchronously connect to an OPC UA server:
use open62541::AsyncClient;
let client = AsyncClient::new("opc.tcp://opcuademo.sterfive.com:26543")?;This requires an async runtime such as tokio.
§Client: Read node’s value attribute
Read a variable node’s value attribute with AsyncClient::read_value():
use open62541::ua;
let node_id = ua::NodeId::numeric(0, 2258); // Server/ServerStatus/CurrentTime
let value = client.read_value(&node_id).await?;
println!("Received value: {value:?}");Use AsyncClient::read_attribute() and related methods to read other attributes other than
the value.
§Client: Watch node for changes in value attribute
Subscribe to a node’s value by creating a subscription with
AsyncClient::create_subscription() and adding monitored items to it with
AsyncSubscription::create_monitored_item():
// Create subscription that receives the updates.
let subscription = client.create_subscription().await?;
// Create monitored item to receive node updates.
let mut monitored_item = subscription.create_monitored_item(&node_id).await?;
while let Some(value) = monitored_item.next().await {
println!("Received value: {value:?}");
}§Server: Run server
Create an OPC UA server with Server::new(). When instantiating a server, you receive a
ServerRunner along with the Server. Use it to run the server until interrupted:
use open62541::Server;
let (server, runner) = Server::new();
// Define data nodes on `server`.
runner.run()?;By default, ServerRunner::run() runs on the current thread. Use
thread::spawn() to run it in a different thread.
§Server: Define object and managed variable nodes
Define nodes with Server::add_object_node() and related methods:
use open62541::{ObjectNode, ua, VariableNode};
use open62541_sys::{
UA_NS0ID_BASEDATAVARIABLETYPE, UA_NS0ID_FOLDERTYPE, UA_NS0ID_OBJECTSFOLDER,
UA_NS0ID_ORGANIZES, UA_NS0ID_STRING,
};
let object_node_id = server.add_object_node(ObjectNode {
requested_new_node_id: None,
parent_node_id: ua::NodeId::ns0(UA_NS0ID_OBJECTSFOLDER),
reference_type_id: ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
browse_name: ua::QualifiedName::new(1, "SomeFolder"),
type_definition: ua::NodeId::ns0(UA_NS0ID_FOLDERTYPE),
attributes: ua::ObjectAttributes::default(),
})?;
let variable_node_id = server.add_variable_node(VariableNode {
requested_new_node_id: None,
parent_node_id: object_node_id,
reference_type_id: ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
browse_name: ua::QualifiedName::new(1, "SomeVariable"),
type_definition: ua::NodeId::ns0(UA_NS0ID_BASEDATAVARIABLETYPE),
attributes: ua::VariableAttributes::default()
.with_data_type(&ua::NodeId::ns0(UA_NS0ID_STRING)),
})?;
server.write_value(
&variable_node_id,
&ua::Variant::scalar(ua::String::new("Lorem Ipsum")?),
)?;Nodes may also be added (and removed) while the server is running.
§Server: Define data source variable nodes (callback-driven)
Implement DataSource for custom types to enable callback-driven read and write access
through OPC UA variables.
Use DataSourceReadContext and DataSourceWriteContext to set the value to return to the
client, or access the incoming value received from the client:
use open62541::{DataSource, DataSourceReadContext, DataSourceResult, DataSourceWriteContext};
struct SomeDataSource {
some_value: u32,
}
impl DataSource for SomeDataSource {
fn read(&mut self, ctx: &mut DataSourceReadContext) -> DataSourceResult {
let value = format!("This is #{value}", value = self.some_value);
ctx.set_variant(ua::Variant::scalar(ua::String::new(&value)?));
Ok(())
}
fn write(&mut self, ctx: &mut DataSourceWriteContext) -> DataSourceResult {
println!("Received value: {value:?}", value = ctx.value());
self.some_value += 1;
Ok(())
}
}
let variable_node = VariableNode {
requested_new_node_id: None,
parent_node_id: object_node_id,
reference_type_id: ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
browse_name: ua::QualifiedName::new(1, "SomeVariable"),
type_definition: ua::NodeId::ns0(UA_NS0ID_BASEDATAVARIABLETYPE),
attributes: ua::VariableAttributes::default()
.with_data_type(&ua::NodeId::ns0(UA_NS0ID_STRING))
.with_access_level(
&ua::AccessLevel::NONE
.with_current_read(true)
.with_current_write(true),
),
};
let variable_node_id = server.add_data_source_variable_node(
variable_node,
SomeDataSource { some_value: 0 },
)?;Modules§
- Thin wrappers for
open62541_systypes.
Structs§
- Connected OPC UA client (with asynchronous API).
- Monitored item (with asynchronous API).
- Subscription (with asynchronous API).
- Type-erased one-shot callback.
- Type-erased stream sender.
- Connected OPC UA client.
- Builder for
Client. - Context when
DataSourceis being read from. - Context when
DataSourceis being written to. - Typed variant of
ua::DataValue. - Context when
MethodCallbackis being called. - OPC UA server.
- Builder for
Server. - Type-erased user data.
Enums§
- Error type used in this crate.
- Scalar value.
- Value of
ua::Variant.
Traits§
- Node attribute.
- Server node attributes.
- Data source with callbacks.
- Transparent wrapper for OPC UA data type.
- Method callback.
Type Aliases§
- Result type for browsing.
- Result from
DataSourceoperations. - Result from
MethodCallbackoperations. - Result type used in this crate.