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}