pub struct ActionDriver { /* private fields */ }Expand description
Direct 1:1 translation layer between Actions and NanonisClient calls Now with integrated always-buffer TCP data collection capability
Implementations§
Source§impl ActionDriver
impl ActionDriver
Sourcepub fn builder(addr: &str, port: u16) -> ActionDriverBuilder
pub fn builder(addr: &str, port: u16) -> ActionDriverBuilder
Create a builder for configuring ActionDriver
Sourcepub fn new(addr: &str, port: u16) -> Result<Self, NanonisError>
pub fn new(addr: &str, port: u16) -> Result<Self, NanonisError>
Create a new ActionDriver with default configuration (backward compatibility)
Examples found in repository?
4fn main() -> Result<(), Box<dyn Error>> {
5 let mut driver = rusty_tip::ActionDriver::new("127.0.0.1", 6501)?;
6
7 driver
8 .run(Action::AutoApproach {
9 wait_until_finished: true,
10 timeout: Duration::from_secs(50),
11 center_freq_shift: true,
12 })
13 .go()?;
14
15 Ok(())
16}Sourcepub fn with_nanonis_client(client: NanonisClient) -> Self
pub fn with_nanonis_client(client: NanonisClient) -> Self
Convenience method to create with existing NanonisClient (backward compatibility)
Sourcepub fn client(&self) -> &NanonisClient
pub fn client(&self) -> &NanonisClient
Get a reference to the underlying NanonisClient
Sourcepub fn client_mut(&mut self) -> &mut NanonisClient
pub fn client_mut(&mut self) -> &mut NanonisClient
Get a mutable reference to the underlying NanonisClient
Sourcepub fn set_shutdown_flag(&mut self, flag: Arc<AtomicBool>)
pub fn set_shutdown_flag(&mut self, flag: Arc<AtomicBool>)
Set shutdown flag for graceful termination of long-running operations
Sourcepub fn auto_approach(
&mut self,
wait_until_finished: bool,
timeout: Duration,
) -> Result<(), NanonisError>
pub fn auto_approach( &mut self, wait_until_finished: bool, timeout: Duration, ) -> Result<(), NanonisError>
Execute an auto-approach operation.
If wait_until_finished is true, blocks until approach completes or timeout.
If false, starts the approach and returns immediately.
Sourcepub fn center_freq_shift(&mut self) -> Result<(), NanonisError>
pub fn center_freq_shift(&mut self) -> Result<(), NanonisError>
Center the frequency shift using the PLL auto-center function.
Sourcepub fn tcp_reader_config(&self) -> Option<&TCPReaderConfig>
pub fn tcp_reader_config(&self) -> Option<&TCPReaderConfig>
Get TCP Logger configuration if set
Sourcepub fn has_tcp_reader(&self) -> bool
pub fn has_tcp_reader(&self) -> bool
Check if TCP logger is configured and available
pub fn tcp_reader_mut(&mut self) -> Option<&mut BufferedTCPReader>
Sourcepub fn clear_tcp_buffer(&self)
pub fn clear_tcp_buffer(&self)
Clear the TCP reader buffer
This removes all buffered data, which is useful to discard stale values before starting a new measurement or tip preparation sequence.
Sourcepub fn signal_registry(&self) -> &SignalRegistry
pub fn signal_registry(&self) -> &SignalRegistry
Get reference to the signal registry
Sourcepub fn run<R>(&mut self, request: R) -> ExecutionBuilder<'_>where
R: Into<ActionRequest>,
pub fn run<R>(&mut self, request: R) -> ExecutionBuilder<'_>where
R: Into<ActionRequest>,
Unified execution method with fluent configuration
§Usage
// Simple execution
let result = driver.run(action)?;
let results = driver.run(actions)?;
// With data collection
let data = driver.run(action).with_data_collection(pre, post).execute()?;
// Type-safe extraction
let signal: f64 = driver.run(read_signal).expecting()?;
// Performance modes
let results = driver.run(actions).deferred_logging().execute()?;
let final_result = driver.run(actions).final_only().execute()?;Examples found in repository?
4fn main() -> Result<(), Box<dyn Error>> {
5 let mut driver = rusty_tip::ActionDriver::new("127.0.0.1", 6501)?;
6
7 driver
8 .run(Action::AutoApproach {
9 wait_until_finished: true,
10 timeout: Duration::from_secs(50),
11 center_freq_shift: true,
12 })
13 .go()?;
14
15 Ok(())
16}Sourcepub fn run_with_config(
&mut self,
request: ActionRequest,
config: ExecutionConfig,
) -> Result<ExecutionResult, NanonisError>
pub fn run_with_config( &mut self, request: ActionRequest, config: ExecutionConfig, ) -> Result<ExecutionResult, NanonisError>
Execute with explicit configuration (for advanced use)
Sourcepub fn get_recent_tcp_data(
&self,
duration: Duration,
) -> Vec<TimestampedSignalFrame>
pub fn get_recent_tcp_data( &self, duration: Duration, ) -> Vec<TimestampedSignalFrame>
Get recent TCP signal data (always available if buffering enabled)
§Arguments
duration- How far back to collect data from current time
§Returns
Vector of recent timestamped signal frames, empty if buffering not active
§Usage
Perfect for real-time monitoring and checking recent signal trends without needing to plan data collection in advance
Sourcepub fn execute_with_data_collection(
&mut self,
action: Action,
pre_duration: Duration,
post_duration: Duration,
) -> Result<ExperimentData, NanonisError>
pub fn execute_with_data_collection( &mut self, action: Action, pre_duration: Duration, post_duration: Duration, ) -> Result<ExperimentData, NanonisError>
Execute action with time-windowed data collection
This is the core method for synchronized data collection during SPM operations. It captures data before, during, and after action execution using the always-buffer.
§Arguments
action- The SPM action to executepre_duration- How much data to collect before action startspost_duration- How much data to collect after action ends
§Returns
ExperimentData containing both action result and time-windowed signal data
§Errors
Returns error if buffering is not active or action execution fails
Sourcepub fn pulse_with_data_collection(
&mut self,
pulse_voltage: f32,
pulse_duration: Duration,
pre_duration: Duration,
post_duration: Duration,
) -> Result<ExperimentData, NanonisError>
pub fn pulse_with_data_collection( &mut self, pulse_voltage: f32, pulse_duration: Duration, pre_duration: Duration, post_duration: Duration, ) -> Result<ExperimentData, NanonisError>
Convenience method for bias pulse with data collection
§Arguments
pulse_voltage- Bias voltage for the pulse (V)pulse_duration- Duration of the pulsepre_duration- Data collection before pulsepost_duration- Data collection after pulse
§Returns
ExperimentData with pulse results and synchronized signal data
Sourcepub fn stop_tcp_buffering(
&mut self,
) -> Result<Vec<TimestampedSignalFrame>, NanonisError>
pub fn stop_tcp_buffering( &mut self, ) -> Result<Vec<TimestampedSignalFrame>, NanonisError>
Sourcepub fn execute_chain_with_data_collection(
&mut self,
actions: Vec<Action>,
pre_duration: Duration,
post_duration: Duration,
) -> Result<ChainExperimentData, NanonisError>
pub fn execute_chain_with_data_collection( &mut self, actions: Vec<Action>, pre_duration: Duration, post_duration: Duration, ) -> Result<ChainExperimentData, NanonisError>
Execute action chain with time-windowed data collection
This executes a sequence of actions while continuously collecting signal data, providing precise timing information for each action in the chain.
§Arguments
actions- Vector of actions to execute in sequencepre_duration- How much data to collect before chain startspost_duration- How much data to collect after chain ends
§Returns
ChainExperimentData containing results and timing for each action plus synchronized signal data
§Errors
Returns error if buffering is not active or any action execution fails
Sourcepub fn start_tcp_logger(&mut self) -> Result<(), NanonisError>
pub fn start_tcp_logger(&mut self) -> Result<(), NanonisError>
Start TCP logger
Sourcepub fn stop_tcp_logger(&mut self) -> Result<(), NanonisError>
pub fn stop_tcp_logger(&mut self) -> Result<(), NanonisError>
Stop TCP logger
Sourcepub fn set_tcp_logger_channels(
&mut self,
channels: Vec<i32>,
) -> Result<(), NanonisError>
pub fn set_tcp_logger_channels( &mut self, channels: Vec<i32>, ) -> Result<(), NanonisError>
Configure TCP logger channels
Sourcepub fn set_tcp_logger_oversampling(
&mut self,
oversampling: i32,
) -> Result<(), NanonisError>
pub fn set_tcp_logger_oversampling( &mut self, oversampling: i32, ) -> Result<(), NanonisError>
Set TCP logger oversampling
Sourcepub fn get_tcp_logger_status(&mut self) -> Result<TCPLogStatus, NanonisError>
pub fn get_tcp_logger_status(&mut self) -> Result<TCPLogStatus, NanonisError>
Get TCP logger status
Sourcepub fn execute(&mut self, action: Action) -> Result<ActionResult, NanonisError>
pub fn execute(&mut self, action: Action) -> Result<ActionResult, NanonisError>
Execute a single action
Sourcepub fn execute_with_options(
&mut self,
action: Action,
data_collection: bool,
pre_duration: Duration,
post_duration: Duration,
) -> Result<ActionResult, NanonisError>
pub fn execute_with_options( &mut self, action: Action, data_collection: bool, pre_duration: Duration, post_duration: Duration, ) -> Result<ActionResult, NanonisError>
Execute action with optional data collection (unified interface)
This provides a single interface for both normal execution and data collection. When data_collection is true, this method collects TCP signal data alongside action execution.
§Arguments
action- The action to executedata_collection- If true, collect TCP signal data (requires TCP reader to be active)pre_duration- How much data to collect before action (only used if data_collection=true)post_duration- How much data to collect after action (only used if data_collection=true)
§Returns
ActionResult for normal execution, or ActionResult::ExperimentData for data collection
§Usage
// Normal execution
let result = driver.execute_with_options(action, false, Duration::ZERO, Duration::ZERO)?;
// With data collection
let result = driver.execute_with_options(action, true, Duration::from_millis(100), Duration::from_millis(200))?;Sourcepub fn execute_chain_with_options(
&mut self,
chain: impl Into<ActionChain>,
data_collection: bool,
pre_duration: Duration,
post_duration: Duration,
) -> Result<Vec<ActionResult>, NanonisError>
pub fn execute_chain_with_options( &mut self, chain: impl Into<ActionChain>, data_collection: bool, pre_duration: Duration, post_duration: Duration, ) -> Result<Vec<ActionResult>, NanonisError>
Execute chain with optional data collection (unified interface)
§Arguments
chain- The action chain to executedata_collection- If true, collect TCP signal data for the entire chainpre_duration- How much data to collect before chain startspost_duration- How much data to collect after chain ends
§Returns
Vector of ActionResults
Sourcepub fn execute_expecting<T>(
&mut self,
action: Action,
) -> Result<T, NanonisError>where
ActionResult: ExpectFromAction<T>,
pub fn execute_expecting<T>(
&mut self,
action: Action,
) -> Result<T, NanonisError>where
ActionResult: ExpectFromAction<T>,
Execute action and extract specific type with validation
This is a convenience method that combines execute() with type extraction, providing better ergonomics while preserving type safety.
§Example
use rusty_tip::{ActionDriver, Action, Signal};
use rusty_tip::types::{DataToGet, OsciData};
let mut driver = ActionDriver::new("127.0.0.1", 6501)?;
let signal = Signal::new("Frequency Shift", 24, None).unwrap();
let osci_data: OsciData = driver.execute_expecting(Action::ReadOsci {
signal,
trigger: None,
data_to_get: DataToGet::Current,
is_stable: None,
})?;Sourcepub fn execute_chain(
&mut self,
chain: impl Into<ActionChain>,
) -> Result<Vec<ActionResult>, NanonisError>
pub fn execute_chain( &mut self, chain: impl Into<ActionChain>, ) -> Result<Vec<ActionResult>, NanonisError>
Execute a chain of actions sequentially
Sourcepub fn execute_chain_final(
&mut self,
chain: impl Into<ActionChain>,
) -> Result<ActionResult, NanonisError>
pub fn execute_chain_final( &mut self, chain: impl Into<ActionChain>, ) -> Result<ActionResult, NanonisError>
Execute chain and return only the final result
Sourcepub fn execute_chain_partial(
&mut self,
chain: impl Into<ActionChain>,
) -> Result<Vec<ActionResult>, (Vec<ActionResult>, NanonisError)>
pub fn execute_chain_partial( &mut self, chain: impl Into<ActionChain>, ) -> Result<Vec<ActionResult>, (Vec<ActionResult>, NanonisError)>
Execute chain with early termination on error, returning partial results
Sourcepub fn execute_chain_deferred(
&mut self,
chain: impl Into<ActionChain>,
) -> Result<Vec<ActionResult>, NanonisError>
pub fn execute_chain_deferred( &mut self, chain: impl Into<ActionChain>, ) -> Result<Vec<ActionResult>, NanonisError>
Execute chain with deferred logging for timing-critical operations
This method executes all actions using execute_internal() (no per-action logging) and then logs the entire chain as a single entry with total timing. Use this when you need precise timing without logging overhead between actions.
§Arguments
chain- The action chain to execute
§Returns
Vector of all action results
§Logging Behavior
- Individual actions are NOT logged during execution
- Single log entry created for the entire chain with total duration
- Log entry includes chain summary and final result
Sourcepub fn clear_storage(&mut self)
pub fn clear_storage(&mut self)
Clear all stored values
Sourcepub fn stored_keys(&self) -> Vec<&String>
pub fn stored_keys(&self) -> Vec<&String>
Get all stored value keys
Sourcepub fn set_action_logging_enabled(&mut self, enabled: bool) -> bool
pub fn set_action_logging_enabled(&mut self, enabled: bool) -> bool
Enable or disable action logging at runtime
§Arguments
enabled- true to enable logging, false to disable
§Returns
Previous logging state
§Usage
let previous_state = driver.set_action_logging_enabled(false);
// Execute timing-critical operations without logging overhead
driver.execute(critical_action)?;
driver.set_action_logging_enabled(previous_state); // RestoreSourcepub fn is_action_logging_enabled(&self) -> bool
pub fn is_action_logging_enabled(&self) -> bool
Check if action logging is currently enabled
Sourcepub fn flush_action_log(&mut self) -> Result<(), NanonisError>
pub fn flush_action_log(&mut self) -> Result<(), NanonisError>
Sourcepub fn action_log_stats(&self) -> Option<(usize, bool)>
pub fn action_log_stats(&self) -> Option<(usize, bool)>
Sourcepub fn finalize_action_log(&mut self) -> Result<(), NanonisError>
pub fn finalize_action_log(&mut self) -> Result<(), NanonisError>
Finalize action log as JSON array (if configured for JSON output)
§Returns
Result indicating if finalization was successful
§Usage
Call this at the end of your experiment to convert JSONL to JSON format for easier post-experiment analysis. This happens automatically on drop, but you can call it manually for explicit control.
Sourcepub fn read_oscilloscope(
&mut self,
signal: Signal,
trigger: Option<TriggerConfig>,
data_to_get: DataToGet,
) -> Result<Option<OsciData>, NanonisError>
pub fn read_oscilloscope( &mut self, signal: Signal, trigger: Option<TriggerConfig>, data_to_get: DataToGet, ) -> Result<Option<OsciData>, NanonisError>
Convenience method to read oscilloscope data directly
Sourcepub fn read_oscilloscope_with_stability(
&mut self,
signal: Signal,
trigger: Option<TriggerConfig>,
data_to_get: DataToGet,
is_stable: fn(&[f64]) -> bool,
) -> Result<Option<OsciData>, NanonisError>
pub fn read_oscilloscope_with_stability( &mut self, signal: Signal, trigger: Option<TriggerConfig>, data_to_get: DataToGet, is_stable: fn(&[f64]) -> bool, ) -> Result<Option<OsciData>, NanonisError>
Convenience method to read oscilloscope data with custom stability function
Source§impl ActionDriver
Extension for ActionDriver with execution statistics
impl ActionDriver
Extension for ActionDriver with execution statistics
Sourcepub fn execute_chain_with_stats(
&mut self,
chain: impl Into<ActionChain>,
) -> Result<(Vec<ActionResult>, ExecutionStats), NanonisError>
pub fn execute_chain_with_stats( &mut self, chain: impl Into<ActionChain>, ) -> Result<(Vec<ActionResult>, ExecutionStats), NanonisError>
Execute chain with detailed statistics