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}