Skip to main content

ActionDriver

Struct ActionDriver 

Source
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

Source

pub fn builder(addr: &str, port: u16) -> ActionDriverBuilder

Create a builder for configuring ActionDriver

Source

pub fn new(addr: &str, port: u16) -> Result<Self, NanonisError>

Create a new ActionDriver with default configuration (backward compatibility)

Examples found in repository?
examples/auto_approach_with_center.rs (line 5)
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}
Source

pub fn with_nanonis_client(client: NanonisClient) -> Self

Convenience method to create with existing NanonisClient (backward compatibility)

Source

pub fn client(&self) -> &NanonisClient

Get a reference to the underlying NanonisClient

Source

pub fn client_mut(&mut self) -> &mut NanonisClient

Get a mutable reference to the underlying NanonisClient

Source

pub fn set_shutdown_flag(&mut self, flag: Arc<AtomicBool>)

Set shutdown flag for graceful termination of long-running operations

Source

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.

Source

pub fn center_freq_shift(&mut self) -> Result<(), NanonisError>

Center the frequency shift using the PLL auto-center function.

Source

pub fn tcp_reader_config(&self) -> Option<&TCPReaderConfig>

Get TCP Logger configuration if set

Source

pub fn has_tcp_reader(&self) -> bool

Check if TCP logger is configured and available

Source

pub fn tcp_reader_mut(&mut self) -> Option<&mut BufferedTCPReader>

Source

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.

Source

pub fn signal_registry(&self) -> &SignalRegistry

Get reference to the signal registry

Source

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?
examples/auto_approach_with_center.rs (lines 8-12)
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}
Source

pub fn run_with_config( &mut self, request: ActionRequest, config: ExecutionConfig, ) -> Result<ExecutionResult, NanonisError>

Execute with explicit configuration (for advanced use)

Source

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

Source

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 execute
  • pre_duration - How much data to collect before action starts
  • post_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

Source

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 pulse
  • pre_duration - Data collection before pulse
  • post_duration - Data collection after pulse
§Returns

ExperimentData with pulse results and synchronized signal data

Source

pub fn tcp_buffer_stats(&self) -> Option<(usize, usize, Duration)>

Get current buffer statistics if buffering is active

§Returns

Optional tuple of (current_count, max_capacity, time_span) or None if no buffering

§Usage

Monitor buffer health, detect overruns, check data collection status

Source

pub fn stop_tcp_buffering( &mut self, ) -> Result<Vec<TimestampedSignalFrame>, NanonisError>

Stop TCP buffering and return final buffer state

§Returns

Vector containing all buffered data, or empty if buffering wasn’t active

§Usage

Optional manual cleanup - this happens automatically via Drop trait. Call this only if you need to access the final buffered data before ActionDriver is dropped.

Source

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 sequence
  • pre_duration - How much data to collect before chain starts
  • post_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

Source

pub fn start_tcp_logger(&mut self) -> Result<(), NanonisError>

Start TCP logger

Source

pub fn stop_tcp_logger(&mut self) -> Result<(), NanonisError>

Stop TCP logger

Source

pub fn set_tcp_logger_channels( &mut self, channels: Vec<i32>, ) -> Result<(), NanonisError>

Configure TCP logger channels

Source

pub fn set_tcp_logger_oversampling( &mut self, oversampling: i32, ) -> Result<(), NanonisError>

Set TCP logger oversampling

Source

pub fn get_tcp_logger_status(&mut self) -> Result<TCPLogStatus, NanonisError>

Get TCP logger status

Source

pub fn execute(&mut self, action: Action) -> Result<ActionResult, NanonisError>

Execute a single action

Source

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 execute
  • data_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))?;
Source

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 execute
  • data_collection - If true, collect TCP signal data for the entire chain
  • pre_duration - How much data to collect before chain starts
  • post_duration - How much data to collect after chain ends
§Returns

Vector of ActionResults

Source

pub fn execute_expecting<T>( &mut self, action: Action, ) -> Result<T, NanonisError>

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,
})?;
Source

pub fn execute_chain( &mut self, chain: impl Into<ActionChain>, ) -> Result<Vec<ActionResult>, NanonisError>

Execute a chain of actions sequentially

Source

pub fn execute_chain_final( &mut self, chain: impl Into<ActionChain>, ) -> Result<ActionResult, NanonisError>

Execute chain and return only the final result

Source

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

Source

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
Source

pub fn clear_storage(&mut self)

Clear all stored values

Source

pub fn stored_keys(&self) -> Vec<&String>

Get all stored value keys

Source

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); // Restore
Source

pub fn is_action_logging_enabled(&self) -> bool

Check if action logging is currently enabled

Source

pub fn flush_action_log(&mut self) -> Result<(), NanonisError>

Manually flush the action log buffer to file

§Returns

Result indicating if flush was successful

§Usage

Force immediate write of buffered actions to file, useful before critical operations or at experiment checkpoints

Source

pub fn action_log_stats(&self) -> Option<(usize, bool)>

Get action log buffer statistics

§Returns

Optional tuple of (current_buffer_count, is_logging_enabled) or None if no logger

§Usage

Monitor buffer utilization to understand logging overhead and frequency

Source

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.

Source

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

Source

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

Source

pub fn execute_chain_with_stats( &mut self, chain: impl Into<ActionChain>, ) -> Result<(Vec<ActionResult>, ExecutionStats), NanonisError>

Execute chain with detailed statistics

Trait Implementations§

Source§

impl Drop for ActionDriver

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.