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(
102                    format!("Invalid signal slot index: {}. Must be between 0-23 (signal slots, not full signal indices)", index)
103                ));
104            }
105        }
106        let num_channels = channel_indexes.len() as i32;
107
108        self.quick_send(
109            "TCPLog.ChsSet",
110            vec![
111                NanonisValue::I32(num_channels),
112                NanonisValue::ArrayI32(channel_indexes),
113            ],
114            vec!["i", "*i"],
115            vec![],
116        )?;
117        Ok(())
118    }
119
120    /// Set the oversampling value in the TCP Logger.
121    ///
122    /// The oversampling value controls the data acquisition rate.
123    ///
124    /// # Arguments
125    /// * `oversampling_value` - Oversampling index (0-1000)
126    ///
127    /// # Returns
128    /// `Ok(())` if the command succeeds.
129    ///
130    /// # Errors
131    /// Returns `NanonisError` if:
132    /// - Invalid oversampling value provided (outside 0-1000 range)
133    /// - Communication with the server fails
134    /// - Protocol error occurs
135    ///
136    /// # Examples
137    /// ```no_run
138    /// use nanonis_rs::NanonisClient;
139    ///
140    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
141    ///
142    /// // Set moderate oversampling
143    /// client.tcplog_oversampl_set(100)?;
144    ///
145    /// // Set maximum oversampling
146    /// client.tcplog_oversampl_set(1000)?;
147    /// # Ok::<(), Box<dyn std::error::Error>>(())
148    /// ```
149    pub fn tcplog_oversampl_set(&mut self, oversampling_value: i32) -> Result<(), NanonisError> {
150        if !(0..=1000).contains(&oversampling_value) {
151            return Err(NanonisError::Protocol(format!(
152                "Invalid oversampling value: {}. Must be between 0-1000",
153                oversampling_value
154            )));
155        }
156
157        self.quick_send(
158            "TCPLog.OversamplSet",
159            vec![NanonisValue::I32(oversampling_value)],
160            vec!["i"],
161            vec![],
162        )?;
163        Ok(())
164    }
165
166    /// Return the current status of the TCP Logger.
167    ///
168    /// # Returns
169    /// The current `TCPLogStatus` of the TCP Logger module.
170    ///
171    /// # Errors
172    /// Returns `NanonisError` if:
173    /// - Communication with the server fails
174    /// - Protocol error occurs
175    /// - Invalid status value returned from server
176    ///
177    /// # Examples
178    /// ```no_run
179    /// use nanonis_rs::NanonisClient;
180    /// use nanonis_rs::tcplog::TCPLogStatus;
181    ///
182    /// let mut client = NanonisClient::new("127.0.0.1", 6501)?;
183    ///
184    /// let status = client.tcplog_status_get()?;
185    /// match status {
186    ///     TCPLogStatus::Idle => println!("Logger is idle"),
187    ///     TCPLogStatus::Running => println!("Logger is running"),
188    ///     TCPLogStatus::BufferOverflow => println!("Warning: Buffer overflow detected!"),
189    ///     _ => println!("Logger status: {}", status),
190    /// }
191    /// # Ok::<(), Box<dyn std::error::Error>>(())
192    /// ```
193    pub fn tcplog_status_get(&mut self) -> Result<TCPLogStatus, NanonisError> {
194        let result = self.quick_send("TCPLog.StatusGet", vec![], vec![], vec!["i"])?;
195
196        debug!("TCPLog.StatusGet result: {result:?}");
197
198        match result.first() {
199            Some(value) => {
200                let value = value.as_i32()?;
201                match value {
202                    0 => Ok(TCPLogStatus::Disconnected),
203                    1 => Ok(TCPLogStatus::Idle),
204                    2 => Ok(TCPLogStatus::Start),
205                    3 => Ok(TCPLogStatus::Stop),
206                    4 => Ok(TCPLogStatus::Running),
207                    5 => Ok(TCPLogStatus::TCPConnect),
208                    6 => Ok(TCPLogStatus::TCPDisconnect),
209                    7 => Ok(TCPLogStatus::BufferOverflow),
210                    _ => Err(NanonisError::Protocol("Invalid Status value".to_string())),
211                }
212            }
213            None => Err(NanonisError::Protocol(
214                "No status value returned".to_string(),
215            )),
216        }
217    }
218}