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