| Crates.io | nominal-connect-client |
| lib.rs | nominal-connect-client |
| version | 0.66.1 |
| created_at | 2025-12-04 20:41:40.688823+00 |
| updated_at | 2025-12-04 20:41:40.688823+00 |
| description | Rust client library for Connect |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1967044 |
| size | 62,231 |
The Connect Client facilitates communication with a Connect app through a Rust binary.
Add this to your Cargo.toml:
[dependencies]
nominal-connect-client = "0.x.y" # replace this with the exact version of Nominal Connect you intend to use
All client operations return Result<T, ConnectClientError>. The ConnectClientError enum has three variants:
Zmq(zmq::Error)Serde(serde_json::Error)IncompatibleClient(String) - Version mismatch between the client library and Connect instanceuse nominal_connect_client::Client;
let mut client = Client::new()?;
Read user values from the Connect app. Note that get_value and get_values return Result types that may fail with ConnectClientError:
use nominal_connect_client::{UserValue, error};
// Get a single value by ID with error handling
let frequency = match client.get_value("frequency") {
Ok(Some(UserValue::Number(f))) if *f > 0.0 => *f,
Ok(_) => 1.0, // value exists but isn't a positive number
Err(e) => {
error!("Error reading frequency: {e}");
1.0 // default value on error
}
};
// Get all values (propagates ConnectClientError)
let all_values = client.get_values()?;
Update user values in the Connect app. All setter methods return Result<(), ConnectClientError>:
use nominal_connect_client::{UserValue, ConnectClientError, error};
// Set a number value (propagates error)
client.set_value("amplitude", UserValue::Number(2.5))?;
// Set a text value with explicit error handling
if let Err(ConnectClientError::Zmq(e)) = client.set_value("message", UserValue::Text("Hello, Connect!".to_string())) {
error!("ZMQ error while setting message: {e}");
}
client.set_value("enabled", UserValue::Bool(true))?;
// Clear specific values
client.clear_values(vec!["value1".to_string(), "value2".to_string()])?;
// Clear all values
client.clear_all_values()?;
Stream data points to Connect for visualization. Both stream and stream_from_map return Result<(), ConnectClientError>:
use std::time::{SystemTime, UNIX_EPOCH};
// Stream a single scalar value
let timestamp_nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;
// Basic usage with error propagation
client.stream(
"sine_wave",
timestamp_nanos,
1.5, // value (f64, i64, or String)
Some("sine"), // channel name (optional)
Some("V"), // channel unit (optional)
)?;
// Stream multiple channels at once
let channel_map = vec![
("temperature".to_string(), 25.5),
("humidity".to_string(), 60.0),
];
client.stream_from_map(
"sensor_data",
timestamp_nanos,
channel_map,
None, // units map (optional)
)?;
Clear stream data. All clear methods return Result<(), ConnectClientError>:
use nominal_connect_client::error;
// Clear a single stream
client.clear_stream("sine_wave")?;
// Clear multiple streams (returns error if any stream fails to clear)
client.clear_streams(&["stream1", "stream2"])?;
// Clear all streams
if let Err(e) = client.clear_all_streams() {
error!("Failed to clear streams: {e}");
}
The client library uses the tracing crate for logging. When you create a new Client with Client::new(), a tracing subscriber is automatically initialized.
use nominal_connect_client::{Client, error, warn, info};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Client::new()?;
info!("Client initialized successfully");
match client.get_value("frequency") {
Ok(Some(value)) => {
info!("Retrieved frequency value: {:?}", value);
}
Ok(None) => {
warn!("Frequency value not found, using default");
}
Err(e) => {
error!("Error reading frequency: {}", e);
}
}
Ok(())
}