rusty_tip/nanonis/client/
tcplog.rs

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