1use super::NanonisClient;
2use crate::error::NanonisError;
3use crate::types::NanonisValue;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum ReverseCondition {
8 #[default]
10 GreaterThan = 0,
11 LessThan = 1,
13}
14
15impl From<ReverseCondition> for i32 {
16 fn from(c: ReverseCondition) -> Self {
17 c as i32
18 }
19}
20
21impl TryFrom<i32> for ReverseCondition {
22 type Error = NanonisError;
23
24 fn try_from(value: i32) -> Result<Self, Self::Error> {
25 match value {
26 0 => Ok(ReverseCondition::GreaterThan),
27 1 => Ok(ReverseCondition::LessThan),
28 _ => Err(NanonisError::Protocol(format!(
29 "Invalid ReverseCondition value: {}",
30 value
31 ))),
32 }
33 }
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
38pub enum ConditionLinkage {
39 #[default]
41 Off = 0,
42 Or = 1,
44 And = 2,
46 Then = 3,
48}
49
50impl From<ConditionLinkage> for i32 {
51 fn from(l: ConditionLinkage) -> Self {
52 l as i32
53 }
54}
55
56impl TryFrom<i32> for ConditionLinkage {
57 type Error = NanonisError;
58
59 fn try_from(value: i32) -> Result<Self, Self::Error> {
60 match value {
61 0 => Ok(ConditionLinkage::Off),
62 1 => Ok(ConditionLinkage::Or),
63 2 => Ok(ConditionLinkage::And),
64 3 => Ok(ConditionLinkage::Then),
65 _ => Err(NanonisError::Protocol(format!(
66 "Invalid ConditionLinkage value: {}",
67 value
68 ))),
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, Default)]
75pub struct HSSwpAutoReverse {
76 pub enabled: bool,
78 pub condition: ReverseCondition,
80 pub signal_index: i32,
82 pub threshold: f32,
84 pub linkage: ConditionLinkage,
86 pub condition2: ReverseCondition,
88 pub signal2_index: i32,
90 pub threshold2: f32,
92}
93
94#[derive(Debug, Clone, Copy, Default)]
96pub struct HSSwpTiming {
97 pub initial_settling_s: f32,
99 pub settling_s: f32,
101 pub integration_s: f32,
103 pub max_slew_rate: f32,
105}
106
107#[derive(Debug, Clone, Copy, Default)]
109pub struct HSSwpLimits {
110 pub relative: bool,
112 pub start: f32,
114 pub stop: f32,
116}
117
118#[derive(Debug, Clone, Copy, Default)]
120pub struct HSSwpZCtrl {
121 pub switch_off: bool,
123 pub controller_index: i32,
125 pub averaging_time_s: f32,
127 pub z_offset_m: f32,
129 pub control_time_s: f32,
131}
132
133#[derive(Debug, Clone, Default)]
135pub struct HSSwpAvailableChannels {
136 pub selected_indices: Vec<u32>,
138 pub available_names: Vec<String>,
140 pub available_indices: Vec<i32>,
142}
143
144#[derive(Debug, Clone, Default)]
146pub struct HSSwpSignalList {
147 pub names: Vec<String>,
149 pub indices: Vec<i32>,
151}
152
153#[derive(Debug, Clone, Default)]
155pub struct HSSwpSaveOptions {
156 pub comment: String,
158 pub modules: Vec<String>,
160}
161
162impl NanonisClient {
163 pub fn hs_swp_acq_chs_set(&mut self, channel_indices: &[i32]) -> Result<(), NanonisError> {
171 self.quick_send(
172 "HSSwp.AcqChsSet",
173 vec![NanonisValue::ArrayI32(channel_indices.to_vec())],
174 vec!["+*i"],
175 vec![],
176 )?;
177 Ok(())
178 }
179
180 pub fn hs_swp_acq_chs_get(&mut self) -> Result<HSSwpAvailableChannels, NanonisError> {
188 let result = self.quick_send(
189 "HSSwp.AcqChsGet",
190 vec![],
191 vec![],
192 vec!["i", "*I", "i", "i", "*+c", "i", "*i"],
193 )?;
194
195 if result.len() >= 7 {
196 Ok(HSSwpAvailableChannels {
197 selected_indices: result[1].as_u32_array()?.to_vec(),
198 available_names: result[4].as_string_array()?.to_vec(),
199 available_indices: result[6].as_i32_array()?.to_vec(),
200 })
201 } else {
202 Err(NanonisError::Protocol("Invalid response".to_string()))
203 }
204 }
205
206 pub fn hs_swp_auto_reverse_set(
214 &mut self,
215 config: &HSSwpAutoReverse,
216 ) -> Result<(), NanonisError> {
217 let on_off = if config.enabled { 1i32 } else { 0i32 };
218 self.quick_send(
219 "HSSwp.AutoReverseSet",
220 vec![
221 NanonisValue::I32(on_off),
222 NanonisValue::I32(config.condition.into()),
223 NanonisValue::I32(config.signal_index),
224 NanonisValue::F32(config.threshold),
225 NanonisValue::I32(config.linkage.into()),
226 NanonisValue::I32(config.condition2.into()),
227 NanonisValue::I32(config.signal2_index),
228 NanonisValue::F32(config.threshold2),
229 ],
230 vec!["i", "i", "i", "f", "i", "i", "i", "f"],
231 vec![],
232 )?;
233 Ok(())
234 }
235
236 pub fn hs_swp_auto_reverse_get(&mut self) -> Result<HSSwpAutoReverse, NanonisError> {
244 let result = self.quick_send(
245 "HSSwp.AutoReverseGet",
246 vec![],
247 vec![],
248 vec!["i", "i", "i", "f", "i", "i", "i", "f"],
249 )?;
250
251 if result.len() >= 8 {
252 Ok(HSSwpAutoReverse {
253 enabled: result[0].as_i32()? != 0,
254 condition: result[1].as_i32()?.try_into()?,
255 signal_index: result[2].as_i32()?,
256 threshold: result[3].as_f32()?,
257 linkage: result[4].as_i32()?.try_into()?,
258 condition2: result[5].as_i32()?.try_into()?,
259 signal2_index: result[6].as_i32()?,
260 threshold2: result[7].as_f32()?,
261 })
262 } else {
263 Err(NanonisError::Protocol("Invalid response".to_string()))
264 }
265 }
266
267 pub fn hs_swp_end_settl_set(&mut self, time_s: f32) -> Result<(), NanonisError> {
275 self.quick_send(
276 "HSSwp.EndSettlSet",
277 vec![NanonisValue::F32(time_s)],
278 vec!["f"],
279 vec![],
280 )?;
281 Ok(())
282 }
283
284 pub fn hs_swp_end_settl_get(&mut self) -> Result<f32, NanonisError> {
292 let result = self.quick_send("HSSwp.EndSettlGet", vec![], vec![], vec!["f"])?;
293
294 if !result.is_empty() {
295 Ok(result[0].as_f32()?)
296 } else {
297 Err(NanonisError::Protocol("Invalid response".to_string()))
298 }
299 }
300
301 pub fn hs_swp_num_sweeps_set(
310 &mut self,
311 num_sweeps: u32,
312 continuous: bool,
313 ) -> Result<(), NanonisError> {
314 let cont_flag = if continuous { 1i32 } else { 0i32 };
315 self.quick_send(
316 "HSSwp.NumSweepsSet",
317 vec![NanonisValue::U32(num_sweeps), NanonisValue::I32(cont_flag)],
318 vec!["I", "i"],
319 vec![],
320 )?;
321 Ok(())
322 }
323
324 pub fn hs_swp_num_sweeps_get(&mut self) -> Result<(u32, bool), NanonisError> {
332 let result = self.quick_send("HSSwp.NumSweepsGet", vec![], vec![], vec!["I", "i"])?;
333
334 if result.len() >= 2 {
335 Ok((result[0].as_u32()?, result[1].as_i32()? != 0))
336 } else {
337 Err(NanonisError::Protocol("Invalid response".to_string()))
338 }
339 }
340
341 pub fn hs_swp_reset_signals_set(&mut self, reset: bool) -> Result<(), NanonisError> {
349 let flag = if reset { 1i32 } else { 0i32 };
350 self.quick_send(
351 "HSSwp.ResetSignalsSet",
352 vec![NanonisValue::I32(flag)],
353 vec!["i"],
354 vec![],
355 )?;
356 Ok(())
357 }
358
359 pub fn hs_swp_reset_signals_get(&mut self) -> Result<bool, NanonisError> {
367 let result = self.quick_send("HSSwp.ResetSignalsGet", vec![], vec![], vec!["i"])?;
368
369 if !result.is_empty() {
370 Ok(result[0].as_i32()? != 0)
371 } else {
372 Err(NanonisError::Protocol("Invalid response".to_string()))
373 }
374 }
375
376 pub fn hs_swp_save_basename_set(
385 &mut self,
386 basename: &str,
387 path: &str,
388 ) -> Result<(), NanonisError> {
389 self.quick_send(
390 "HSSwp.SaveBasenameSet",
391 vec![
392 NanonisValue::String(basename.to_string()),
393 NanonisValue::String(path.to_string()),
394 ],
395 vec!["+*c", "+*c"],
396 vec![],
397 )?;
398 Ok(())
399 }
400
401 pub fn hs_swp_save_basename_get(&mut self) -> Result<(String, String), NanonisError> {
409 let result =
410 self.quick_send("HSSwp.SaveBasenameGet", vec![], vec![], vec!["i", "*-c", "*-c"])?;
411
412 if result.len() >= 3 {
413 Ok((
414 result[1].as_string()?.to_string(),
415 result[2].as_string()?.to_string(),
416 ))
417 } else {
418 Err(NanonisError::Protocol("Invalid response".to_string()))
419 }
420 }
421
422 pub fn hs_swp_save_data_set(&mut self, save: bool) -> Result<(), NanonisError> {
430 let flag = if save { 1i32 } else { 0i32 };
431 self.quick_send(
432 "HSSwp.SaveDataSet",
433 vec![NanonisValue::I32(flag)],
434 vec!["i"],
435 vec![],
436 )?;
437 Ok(())
438 }
439
440 pub fn hs_swp_save_data_get(&mut self) -> Result<bool, NanonisError> {
448 let result = self.quick_send("HSSwp.SaveDataGet", vec![], vec![], vec!["i"])?;
449
450 if !result.is_empty() {
451 Ok(result[0].as_i32()? != 0)
452 } else {
453 Err(NanonisError::Protocol("Invalid response".to_string()))
454 }
455 }
456
457 pub fn hs_swp_save_options_set(&mut self, options: &HSSwpSaveOptions) -> Result<(), NanonisError> {
465 self.quick_send(
466 "HSSwp.SaveOptionsSet",
467 vec![
468 NanonisValue::String(options.comment.clone()),
469 NanonisValue::ArrayString(options.modules.clone()),
470 ],
471 vec!["+*c", "+*c"],
472 vec![],
473 )?;
474 Ok(())
475 }
476
477 pub fn hs_swp_save_options_get(&mut self) -> Result<HSSwpSaveOptions, NanonisError> {
485 let result = self.quick_send(
486 "HSSwp.SaveOptionsGet",
487 vec![],
488 vec![],
489 vec!["i", "*-c", "i", "i", "*+c"],
490 )?;
491
492 if result.len() >= 5 {
493 Ok(HSSwpSaveOptions {
494 comment: result[1].as_string()?.to_string(),
495 modules: result[4].as_string_array()?.to_vec(),
496 })
497 } else {
498 Err(NanonisError::Protocol("Invalid response".to_string()))
499 }
500 }
501
502 pub fn hs_swp_start(&mut self, wait_until_done: bool, timeout_ms: i32) -> Result<(), NanonisError> {
511 let wait_flag = if wait_until_done { 1i32 } else { 0i32 };
512 self.quick_send(
513 "HSSwp.Start",
514 vec![NanonisValue::I32(wait_flag), NanonisValue::I32(timeout_ms)],
515 vec!["i", "i"],
516 vec![],
517 )?;
518 Ok(())
519 }
520
521 pub fn hs_swp_stop(&mut self) -> Result<(), NanonisError> {
526 self.quick_send("HSSwp.Stop", vec![], vec![], vec![])?;
527 Ok(())
528 }
529
530 pub fn hs_swp_status_get(&mut self) -> Result<bool, NanonisError> {
538 let result = self.quick_send("HSSwp.StatusGet", vec![], vec![], vec!["I"])?;
539
540 if !result.is_empty() {
541 Ok(result[0].as_u32()? != 0)
542 } else {
543 Err(NanonisError::Protocol("Invalid response".to_string()))
544 }
545 }
546
547 pub fn hs_swp_swp_ch_sig_list_get(&mut self) -> Result<HSSwpSignalList, NanonisError> {
555 let result =
556 self.quick_send("HSSwp.SwpChSigListGet", vec![], vec![], vec!["+*c", "+*i"])?;
557
558 if result.len() >= 2 {
559 Ok(HSSwpSignalList {
560 names: result[0].as_string_array()?.to_vec(),
561 indices: result[1].as_i32_array()?.to_vec(),
562 })
563 } else {
564 Err(NanonisError::Protocol("Invalid response".to_string()))
565 }
566 }
567
568 pub fn hs_swp_swp_ch_signal_set(
577 &mut self,
578 signal_index: i32,
579 timed_sweep: bool,
580 ) -> Result<(), NanonisError> {
581 let timed_flag = if timed_sweep { 1i32 } else { 0i32 };
582 self.quick_send(
583 "HSSwp.SwpChSignalSet",
584 vec![NanonisValue::I32(signal_index), NanonisValue::I32(timed_flag)],
585 vec!["i", "i"],
586 vec![],
587 )?;
588 Ok(())
589 }
590
591 pub fn hs_swp_swp_ch_signal_get(&mut self) -> Result<(i32, bool), NanonisError> {
599 let result = self.quick_send("HSSwp.SwpChSignalGet", vec![], vec![], vec!["i", "i"])?;
600
601 if result.len() >= 2 {
602 Ok((result[0].as_i32()?, result[1].as_i32()? != 0))
603 } else {
604 Err(NanonisError::Protocol("Invalid response".to_string()))
605 }
606 }
607
608 pub fn hs_swp_swp_ch_limits_set(&mut self, limits: &HSSwpLimits) -> Result<(), NanonisError> {
616 let rel_flag = if limits.relative { 1i32 } else { 0i32 };
617 self.quick_send(
618 "HSSwp.SwpChLimitsSet",
619 vec![
620 NanonisValue::I32(rel_flag),
621 NanonisValue::F32(limits.start),
622 NanonisValue::F32(limits.stop),
623 ],
624 vec!["i", "f", "f"],
625 vec![],
626 )?;
627 Ok(())
628 }
629
630 pub fn hs_swp_swp_ch_limits_get(&mut self) -> Result<HSSwpLimits, NanonisError> {
638 let result = self.quick_send("HSSwp.SwpChLimitsGet", vec![], vec![], vec!["i", "f", "f"])?;
639
640 if result.len() >= 3 {
641 Ok(HSSwpLimits {
642 relative: result[0].as_i32()? != 0,
643 start: result[1].as_f32()?,
644 stop: result[2].as_f32()?,
645 })
646 } else {
647 Err(NanonisError::Protocol("Invalid response".to_string()))
648 }
649 }
650
651 pub fn hs_swp_swp_ch_num_pts_set(&mut self, num_points: u32) -> Result<(), NanonisError> {
659 self.quick_send(
660 "HSSwp.SwpChNumPtsSet",
661 vec![NanonisValue::U32(num_points)],
662 vec!["I"],
663 vec![],
664 )?;
665 Ok(())
666 }
667
668 pub fn hs_swp_swp_ch_num_pts_get(&mut self) -> Result<i32, NanonisError> {
676 let result = self.quick_send("HSSwp.SwpChNumPtsGet", vec![], vec![], vec!["i"])?;
677
678 if !result.is_empty() {
679 Ok(result[0].as_i32()?)
680 } else {
681 Err(NanonisError::Protocol("Invalid response".to_string()))
682 }
683 }
684
685 pub fn hs_swp_swp_ch_timing_set(&mut self, timing: &HSSwpTiming) -> Result<(), NanonisError> {
693 self.quick_send(
694 "HSSwp.SwpChTimingSet",
695 vec![
696 NanonisValue::F32(timing.initial_settling_s),
697 NanonisValue::F32(timing.settling_s),
698 NanonisValue::F32(timing.integration_s),
699 NanonisValue::F32(timing.max_slew_rate),
700 ],
701 vec!["f", "f", "f", "f"],
702 vec![],
703 )?;
704 Ok(())
705 }
706
707 pub fn hs_swp_swp_ch_timing_get(&mut self) -> Result<HSSwpTiming, NanonisError> {
715 let result =
716 self.quick_send("HSSwp.SwpChTimingGet", vec![], vec![], vec!["f", "f", "f", "f"])?;
717
718 if result.len() >= 4 {
719 Ok(HSSwpTiming {
720 initial_settling_s: result[0].as_f32()?,
721 settling_s: result[1].as_f32()?,
722 integration_s: result[2].as_f32()?,
723 max_slew_rate: result[3].as_f32()?,
724 })
725 } else {
726 Err(NanonisError::Protocol("Invalid response".to_string()))
727 }
728 }
729
730 pub fn hs_swp_swp_ch_bwd_sw_set(&mut self, enabled: bool) -> Result<(), NanonisError> {
738 let flag = if enabled { 1u32 } else { 0u32 };
739 self.quick_send(
740 "HSSwp.SwpChBwdSwSet",
741 vec![NanonisValue::U32(flag)],
742 vec!["I"],
743 vec![],
744 )?;
745 Ok(())
746 }
747
748 pub fn hs_swp_swp_ch_bwd_sw_get(&mut self) -> Result<bool, NanonisError> {
756 let result = self.quick_send("HSSwp.SwpChBwdSwGet", vec![], vec![], vec!["I"])?;
757
758 if !result.is_empty() {
759 Ok(result[0].as_u32()? != 0)
760 } else {
761 Err(NanonisError::Protocol("Invalid response".to_string()))
762 }
763 }
764
765 pub fn hs_swp_swp_ch_bwd_delay_set(&mut self, delay_s: f32) -> Result<(), NanonisError> {
773 self.quick_send(
774 "HSSwp.SwpChBwdDelaySet",
775 vec![NanonisValue::F32(delay_s)],
776 vec!["f"],
777 vec![],
778 )?;
779 Ok(())
780 }
781
782 pub fn hs_swp_swp_ch_bwd_delay_get(&mut self) -> Result<f32, NanonisError> {
790 let result = self.quick_send("HSSwp.SwpChBwdDelayGet", vec![], vec![], vec!["f"])?;
791
792 if !result.is_empty() {
793 Ok(result[0].as_f32()?)
794 } else {
795 Err(NanonisError::Protocol("Invalid response".to_string()))
796 }
797 }
798
799 pub fn hs_swp_z_ctrl_off_set(&mut self, config: &HSSwpZCtrl) -> Result<(), NanonisError> {
807 let switch_off = if config.switch_off { 0i32 } else { 1i32 }; self.quick_send(
809 "HSSwp.ZCtrlOffSet",
810 vec![
811 NanonisValue::I32(switch_off),
812 NanonisValue::I32(config.controller_index),
813 NanonisValue::F32(config.averaging_time_s),
814 NanonisValue::F32(config.z_offset_m),
815 NanonisValue::F32(config.control_time_s),
816 ],
817 vec!["i", "i", "f", "f", "f"],
818 vec![],
819 )?;
820 Ok(())
821 }
822
823 pub fn hs_swp_z_ctrl_off_get(&mut self) -> Result<HSSwpZCtrl, NanonisError> {
831 let result =
832 self.quick_send("HSSwp.ZCtrlOffGet", vec![], vec![], vec!["i", "i", "f", "f", "f"])?;
833
834 if result.len() >= 5 {
835 Ok(HSSwpZCtrl {
836 switch_off: result[0].as_i32()? == 0, controller_index: result[1].as_i32()?,
838 averaging_time_s: result[2].as_f32()?,
839 z_offset_m: result[3].as_f32()?,
840 control_time_s: result[4].as_f32()?,
841 })
842 } else {
843 Err(NanonisError::Protocol("Invalid response".to_string()))
844 }
845 }
846}