Skip to main content

nanonis_rs/client/tcplog/
mod.rs

1mod types;
2pub use types::*;
3
4use super::NanonisClient;
5use crate::error::NanonisError;
6use crate::types::NanonisValue;
7use log::debug;
8
9impl NanonisClient {
10    /// Start the acquisition in the TCP Logger module.
11    ///
12    /// Before using this function, select the channels to record in the TCP Logger
13    /// using `tcplog_chs_set()`.
14    ///
15    /// # Returns
16    /// `Ok(())` if the command succeeds.
17    ///
18    /// # Errors
19    /// Returns `NanonisError` if:
20    /// - Communication with the server fails
21    /// - Protocol error occurs
22    ///
23    /// # Examples
24    /// ```no_run
25    /// use nanonis_rs::NanonisClient;
26    ///
27    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
28    ///
29    /// // Configure channels first (using signal slots, not full indices)
30    /// client.tcplog_chs_set(vec![0, 1, 2])?; // First 3 signal slots
31    ///
32    /// // Start logging
33    /// client.tcplog_start()?;
34    /// # Ok::<(), Box<dyn std::error::Error>>(())
35    /// ```
36    pub fn tcplog_start(&mut self) -> Result<(), NanonisError> {
37        self.quick_send("TCPLog.Start", vec![], vec![], vec![])?;
38        Ok(())
39    }
40
41    /// Stop the acquisition in the TCP Logger module.
42    ///
43    /// # Returns
44    /// `Ok(())` if the command succeeds.
45    ///
46    /// # Errors
47    /// Returns `NanonisError` if:
48    /// - Communication with the server fails
49    /// - Protocol error occurs
50    ///
51    /// # Examples
52    /// ```no_run
53    /// use nanonis_rs::NanonisClient;
54    ///
55    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
56    ///
57    /// // Stop logging
58    /// client.tcplog_stop()?;
59    /// # Ok::<(), Box<dyn std::error::Error>>(())
60    /// ```
61    pub fn tcplog_stop(&mut self) -> Result<(), NanonisError> {
62        self.quick_send("TCPLog.Stop", vec![], vec![], vec![])?;
63        Ok(())
64    }
65
66    /// Set the list of recorded channels in the TCP Logger module.
67    ///
68    /// The channel indexes are comprised between 0 and 23 for the 24 signals
69    /// assigned in the Signals Manager. To get the signal name and its
70    /// corresponding index in the list of the 128 available signals in the
71    /// Nanonis Controller, use the `signal_names_get()` function.
72    ///
73    /// # Arguments
74    /// * `channel_indexes` - Vector of channel indexes to record (0-23)
75    ///
76    /// # Returns
77    /// `Ok(())` if the command succeeds.
78    ///
79    /// # Errors
80    /// Returns `NanonisError` if:
81    /// - Invalid channel indexes provided
82    /// - Communication with the server fails
83    /// - Protocol error occurs
84    ///
85    /// # Examples
86    /// ```no_run
87    /// use nanonis_rs::NanonisClient;
88    ///
89    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
90    ///
91    /// // Record first few signal slots (current, height, etc.)
92    /// client.tcplog_chs_set(vec![0, 1, 2])?;
93    ///
94    /// // Record only the first slot (typically current)
95    /// client.tcplog_chs_set(vec![0])?;
96    /// # Ok::<(), Box<dyn std::error::Error>>(())
97    /// ```
98    pub fn tcplog_chs_set(&mut self, channel_indexes: Vec<i32>) -> Result<(), NanonisError> {
99        for &index in &channel_indexes {
100            if !(0..=23).contains(&index) {
101                return Err(NanonisError::Protocol(format!(
102                    "Invalid signal slot index: {}. Must be between 0-23 (signal slots, not full signal indices)",
103                    index
104                )));
105            }
106        }
107        let num_channels = channel_indexes.len() as i32;
108
109        self.quick_send(
110            "TCPLog.ChsSet",
111            vec![
112                NanonisValue::I32(num_channels),
113                NanonisValue::ArrayI32(channel_indexes),
114            ],
115            vec!["i", "*i"],
116            vec![],
117        )?;
118        Ok(())
119    }
120
121    /// Set the oversampling value in the TCP Logger.
122    ///
123    /// The oversampling value controls the data acquisition rate.
124    ///
125    /// # Arguments
126    /// * `oversampling_value` - Oversampling index (0-1000)
127    ///
128    /// # Returns
129    /// `Ok(())` if the command succeeds.
130    ///
131    /// # Errors
132    /// Returns `NanonisError` if:
133    /// - Invalid oversampling value provided (outside 0-1000 range)
134    /// - Communication with the server fails
135    /// - Protocol error occurs
136    ///
137    /// # Examples
138    /// ```no_run
139    /// use nanonis_rs::NanonisClient;
140    ///
141    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
142    ///
143    /// // Set moderate oversampling
144    /// client.tcplog_oversampl_set(100)?;
145    ///
146    /// // Set maximum oversampling
147    /// client.tcplog_oversampl_set(1000)?;
148    /// # Ok::<(), Box<dyn std::error::Error>>(())
149    /// ```
150    pub fn tcplog_oversampl_set(&mut self, oversampling_value: i32) -> Result<(), NanonisError> {
151        if !(0..=1000).contains(&oversampling_value) {
152            return Err(NanonisError::Protocol(format!(
153                "Invalid oversampling value: {}. Must be between 0-1000",
154                oversampling_value
155            )));
156        }
157
158        self.quick_send(
159            "TCPLog.OversamplSet",
160            vec![NanonisValue::I32(oversampling_value)],
161            vec!["i"],
162            vec![],
163        )?;
164        Ok(())
165    }
166
167    /// Return the current status of the TCP Logger.
168    ///
169    /// # Returns
170    /// The current `TCPLogStatus` of the TCP Logger module.
171    ///
172    /// # Errors
173    /// Returns `NanonisError` if:
174    /// - Communication with the server fails
175    /// - Protocol error occurs
176    /// - Invalid status value returned from server
177    ///
178    /// # Examples
179    /// ```no_run
180    /// use nanonis_rs::NanonisClient;
181    /// use nanonis_rs::tcplog::TCPLogStatus;
182    ///
183    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
184    ///
185    /// let status = client.tcplog_status_get()?;
186    /// match status {
187    ///     TCPLogStatus::Idle => println!("Logger is idle"),
188    ///     TCPLogStatus::Running => println!("Logger is running"),
189    ///     TCPLogStatus::BufferOverflow => println!("Warning: Buffer overflow detected!"),
190    ///     _ => println!("Logger status: {}", status),
191    /// }
192    /// # Ok::<(), Box<dyn std::error::Error>>(())
193    /// ```
194    pub fn tcplog_status_get(&mut self) -> Result<TCPLogStatus, NanonisError> {
195        let result = self.quick_send("TCPLog.StatusGet", vec![], vec![], vec!["i"])?;
196
197        debug!("TCPLog.StatusGet result: {result:?}");
198
199        match result.first() {
200            Some(value) => {
201                let value = value.as_i32()?;
202                match value {
203                    0 => Ok(TCPLogStatus::Disconnected),
204                    1 => Ok(TCPLogStatus::Idle),
205                    2 => Ok(TCPLogStatus::Start),
206                    3 => Ok(TCPLogStatus::Stop),
207                    4 => Ok(TCPLogStatus::Running),
208                    5 => Ok(TCPLogStatus::TCPConnect),
209                    6 => Ok(TCPLogStatus::TCPDisconnect),
210                    7 => Ok(TCPLogStatus::BufferOverflow),
211                    _ => Err(NanonisError::Protocol("Invalid Status value".to_string())),
212                }
213            }
214            None => Err(NanonisError::Protocol(
215                "No status value returned".to_string(),
216            )),
217        }
218    }
219}