Skip to main content

nanonis_rs/client/
script.rs

1use super::NanonisClient;
2use crate::error::NanonisError;
3use crate::types::NanonisValue;
4
5/// Acquire buffer selection for Script module.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum AcquireBuffer {
8    /// Both buffers for autosave
9    Both = 0,
10    #[default]
11    /// Acquire Buffer 1
12    Buffer1 = 1,
13    /// Acquire Buffer 2
14    Buffer2 = 2,
15}
16
17impl From<AcquireBuffer> for u16 {
18    fn from(buf: AcquireBuffer) -> Self {
19        buf as u16
20    }
21}
22
23/// Script data returned from a sweep.
24#[derive(Debug, Clone, Default)]
25pub struct ScriptData {
26    /// Data rows (one per channel)
27    pub data: Vec<Vec<f32>>,
28}
29
30impl NanonisClient {
31    // ==================== Script Module ====================
32
33    /// Open the Script module.
34    ///
35    /// # Errors
36    /// Returns `NanonisError` if communication fails.
37    pub fn script_open(&mut self) -> Result<(), NanonisError> {
38        self.quick_send("Script.Open", vec![], vec![], vec![])?;
39        Ok(())
40    }
41
42    /// Load a script in the Script module.
43    ///
44    /// # Arguments
45    /// * `script_index` - Script slot (1 to total scripts, -1 for current)
46    /// * `file_path` - Path to the script file
47    /// * `load_session` - If true, loads from session file instead of file_path
48    ///
49    /// # Errors
50    /// Returns `NanonisError` if communication fails.
51    pub fn script_load(
52        &mut self,
53        script_index: i32,
54        file_path: &str,
55        load_session: bool,
56    ) -> Result<(), NanonisError> {
57        self.quick_send(
58            "Script.Load",
59            vec![
60                NanonisValue::I32(script_index),
61                NanonisValue::String(file_path.to_string()),
62                NanonisValue::U32(if load_session { 1 } else { 0 }),
63            ],
64            vec!["i", "+*c", "I"],
65            vec![],
66        )?;
67        Ok(())
68    }
69
70    /// Save the current script to a file.
71    ///
72    /// # Arguments
73    /// * `script_index` - Script slot (1 to total scripts, -1 for current)
74    /// * `file_path` - Path to save the script file
75    /// * `save_session` - If true, saves to session file instead
76    ///
77    /// # Errors
78    /// Returns `NanonisError` if communication fails.
79    pub fn script_save(
80        &mut self,
81        script_index: i32,
82        file_path: &str,
83        save_session: bool,
84    ) -> Result<(), NanonisError> {
85        self.quick_send(
86            "Script.Save",
87            vec![
88                NanonisValue::I32(script_index),
89                NanonisValue::String(file_path.to_string()),
90                NanonisValue::U32(if save_session { 1 } else { 0 }),
91            ],
92            vec!["i", "+*c", "I"],
93            vec![],
94        )?;
95        Ok(())
96    }
97
98    /// Deploy a script in the Script module.
99    ///
100    /// # Arguments
101    /// * `script_index` - Script slot (1 to total scripts, -1 for current)
102    ///
103    /// # Errors
104    /// Returns `NanonisError` if communication fails.
105    pub fn script_deploy(&mut self, script_index: i32) -> Result<(), NanonisError> {
106        self.quick_send(
107            "Script.Deploy",
108            vec![NanonisValue::I32(script_index)],
109            vec!["i"],
110            vec![],
111        )?;
112        Ok(())
113    }
114
115    /// Undeploy a script in the Script module.
116    ///
117    /// # Arguments
118    /// * `script_index` - Script slot (1 to total scripts, -1 for current)
119    ///
120    /// # Errors
121    /// Returns `NanonisError` if communication fails.
122    pub fn script_undeploy(&mut self, script_index: i32) -> Result<(), NanonisError> {
123        self.quick_send(
124            "Script.Undeploy",
125            vec![NanonisValue::I32(script_index)],
126            vec!["i"],
127            vec![],
128        )?;
129        Ok(())
130    }
131
132    /// Run a script in the Script module.
133    ///
134    /// # Arguments
135    /// * `script_index` - Script slot (1 to total scripts, -1 for current)
136    /// * `wait` - If true, waits until script finishes
137    ///
138    /// # Errors
139    /// Returns `NanonisError` if communication fails.
140    pub fn script_run(&mut self, script_index: i32, wait: bool) -> Result<(), NanonisError> {
141        self.quick_send(
142            "Script.Run",
143            vec![
144                NanonisValue::I32(script_index),
145                NanonisValue::U32(if wait { 1 } else { 0 }),
146            ],
147            vec!["i", "I"],
148            vec![],
149        )?;
150        Ok(())
151    }
152
153    /// Stop the running script.
154    ///
155    /// # Errors
156    /// Returns `NanonisError` if communication fails.
157    pub fn script_stop(&mut self) -> Result<(), NanonisError> {
158        self.quick_send("Script.Stop", vec![], vec![], vec![])?;
159        Ok(())
160    }
161
162    /// Get the list of acquired channels in the Script module.
163    ///
164    /// # Arguments
165    /// * `buffer` - Acquire buffer to read from
166    ///
167    /// # Returns
168    /// Vector of channel indexes (0-23).
169    ///
170    /// # Errors
171    /// Returns `NanonisError` if communication fails.
172    pub fn script_chs_get(&mut self, buffer: AcquireBuffer) -> Result<Vec<i32>, NanonisError> {
173        let result = self.quick_send(
174            "Script.ChsGet",
175            vec![NanonisValue::U16(buffer.into())],
176            vec!["H"],
177            vec!["i", "*i"],
178        )?;
179
180        result[1].as_i32_array().map(|a| a.to_vec())
181    }
182
183    /// Set the list of acquired channels in the Script module.
184    ///
185    /// # Arguments
186    /// * `buffer` - Acquire buffer to configure
187    /// * `channel_indexes` - Channel indexes (0-23)
188    ///
189    /// # Errors
190    /// Returns `NanonisError` if communication fails.
191    pub fn script_chs_set(
192        &mut self,
193        buffer: AcquireBuffer,
194        channel_indexes: &[i32],
195    ) -> Result<(), NanonisError> {
196        self.quick_send(
197            "Script.ChsSet",
198            vec![
199                NanonisValue::U16(buffer.into()),
200                NanonisValue::ArrayI32(channel_indexes.to_vec()),
201            ],
202            vec!["H", "+*i"],
203            vec![],
204        )?;
205        Ok(())
206    }
207
208    /// Get the data acquired in the Script module.
209    ///
210    /// # Arguments
211    /// * `buffer` - Acquire buffer to read from
212    /// * `sweep_number` - Sweep number (starts at 0)
213    ///
214    /// # Returns
215    /// 2D array of script data.
216    ///
217    /// # Errors
218    /// Returns `NanonisError` if communication fails.
219    pub fn script_data_get(
220        &mut self,
221        buffer: AcquireBuffer,
222        sweep_number: i32,
223    ) -> Result<ScriptData, NanonisError> {
224        let result = self.quick_send(
225            "Script.DataGet",
226            vec![
227                NanonisValue::U16(buffer.into()),
228                NanonisValue::I32(sweep_number),
229            ],
230            vec!["H", "i"],
231            vec!["i", "i", "2f"],
232        )?;
233
234        Ok(ScriptData {
235            data: result[2].as_f32_2d_array()?.to_vec(),
236        })
237    }
238
239    /// Autosave script data to file.
240    ///
241    /// # Arguments
242    /// * `buffer` - Acquire buffer(s) to save
243    /// * `sweep_number` - Sweep number (-1 for all sweeps)
244    /// * `all_sweeps_to_same_file` - If true, saves all sweeps to one file
245    /// * `folder_path` - Folder path (empty for last used)
246    /// * `basename` - File basename (empty for last used)
247    ///
248    /// # Errors
249    /// Returns `NanonisError` if communication fails.
250    pub fn script_autosave(
251        &mut self,
252        buffer: AcquireBuffer,
253        sweep_number: i32,
254        all_sweeps_to_same_file: bool,
255        folder_path: &str,
256        basename: &str,
257    ) -> Result<(), NanonisError> {
258        self.quick_send(
259            "Script.Autosave",
260            vec![
261                NanonisValue::U16(buffer.into()),
262                NanonisValue::I32(sweep_number),
263                NanonisValue::U32(if all_sweeps_to_same_file { 1 } else { 0 }),
264                NanonisValue::String(folder_path.to_string()),
265                NanonisValue::String(basename.to_string()),
266            ],
267            vec!["H", "i", "I", "+*c", "+*c"],
268            vec![],
269        )?;
270        Ok(())
271    }
272
273    /// Open the LUT (Look Up Table) Editor from the Script module.
274    ///
275    /// # Errors
276    /// Returns `NanonisError` if communication fails.
277    pub fn script_lut_open(&mut self) -> Result<(), NanonisError> {
278        self.quick_send("Script.LUTOpen", vec![], vec![], vec![])?;
279        Ok(())
280    }
281
282    /// Load a LUT from file or from values.
283    ///
284    /// # Arguments
285    /// * `lut_index` - LUT index (1 to total LUTs)
286    /// * `file_path` - Path to .luts file (empty to use values)
287    /// * `values` - LUT values (used if file_path is empty)
288    ///
289    /// # Errors
290    /// Returns `NanonisError` if communication fails.
291    pub fn script_lut_load(
292        &mut self,
293        lut_index: i32,
294        file_path: &str,
295        values: &[f32],
296    ) -> Result<(), NanonisError> {
297        self.quick_send(
298            "Script.LUTLoad",
299            vec![
300                NanonisValue::I32(lut_index),
301                NanonisValue::String(file_path.to_string()),
302                NanonisValue::ArrayF32(values.to_vec()),
303            ],
304            vec!["i", "+*c", "+*f"],
305            vec![],
306        )?;
307        Ok(())
308    }
309
310    /// Save a LUT to file.
311    ///
312    /// # Arguments
313    /// * `lut_index` - LUT index (1 to total LUTs)
314    /// * `file_path` - Path to save .luts file
315    ///
316    /// # Errors
317    /// Returns `NanonisError` if communication fails.
318    pub fn script_lut_save(&mut self, lut_index: i32, file_path: &str) -> Result<(), NanonisError> {
319        self.quick_send(
320            "Script.LUTSave",
321            vec![
322                NanonisValue::I32(lut_index),
323                NanonisValue::String(file_path.to_string()),
324            ],
325            vec!["i", "+*c"],
326            vec![],
327        )?;
328        Ok(())
329    }
330
331    /// Deploy a LUT from the LUT Editor.
332    ///
333    /// # Arguments
334    /// * `lut_index` - LUT index (1 to total LUTs)
335    /// * `wait` - If true, waits until deployment finishes
336    /// * `timeout_ms` - Timeout in milliseconds (-1 for forever)
337    ///
338    /// # Errors
339    /// Returns `NanonisError` if communication fails.
340    pub fn script_lut_deploy(
341        &mut self,
342        lut_index: i32,
343        wait: bool,
344        timeout_ms: i32,
345    ) -> Result<(), NanonisError> {
346        self.quick_send(
347            "Script.LUTDeploy",
348            vec![
349                NanonisValue::I32(lut_index),
350                NanonisValue::U32(if wait { 1 } else { 0 }),
351                NanonisValue::I32(timeout_ms),
352            ],
353            vec!["i", "I", "i"],
354            vec![],
355        )?;
356        Ok(())
357    }
358}