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 = self.quick_send(
410 "HSSwp.SaveBasenameGet",
411 vec![],
412 vec![],
413 vec!["i", "*-c", "*-c"],
414 )?;
415
416 if result.len() >= 3 {
417 Ok((
418 result[1].as_string()?.to_string(),
419 result[2].as_string()?.to_string(),
420 ))
421 } else {
422 Err(NanonisError::Protocol("Invalid response".to_string()))
423 }
424 }
425
426 pub fn hs_swp_save_data_set(&mut self, save: bool) -> Result<(), NanonisError> {
434 let flag = if save { 1i32 } else { 0i32 };
435 self.quick_send(
436 "HSSwp.SaveDataSet",
437 vec![NanonisValue::I32(flag)],
438 vec!["i"],
439 vec![],
440 )?;
441 Ok(())
442 }
443
444 pub fn hs_swp_save_data_get(&mut self) -> Result<bool, NanonisError> {
452 let result = self.quick_send("HSSwp.SaveDataGet", vec![], vec![], vec!["i"])?;
453
454 if !result.is_empty() {
455 Ok(result[0].as_i32()? != 0)
456 } else {
457 Err(NanonisError::Protocol("Invalid response".to_string()))
458 }
459 }
460
461 pub fn hs_swp_save_options_set(
469 &mut self,
470 options: &HSSwpSaveOptions,
471 ) -> Result<(), NanonisError> {
472 self.quick_send(
473 "HSSwp.SaveOptionsSet",
474 vec![
475 NanonisValue::String(options.comment.clone()),
476 NanonisValue::ArrayString(options.modules.clone()),
477 ],
478 vec!["+*c", "+*c"],
479 vec![],
480 )?;
481 Ok(())
482 }
483
484 pub fn hs_swp_save_options_get(&mut self) -> Result<HSSwpSaveOptions, NanonisError> {
492 let result = self.quick_send(
493 "HSSwp.SaveOptionsGet",
494 vec![],
495 vec![],
496 vec!["i", "*-c", "i", "i", "*+c"],
497 )?;
498
499 if result.len() >= 5 {
500 Ok(HSSwpSaveOptions {
501 comment: result[1].as_string()?.to_string(),
502 modules: result[4].as_string_array()?.to_vec(),
503 })
504 } else {
505 Err(NanonisError::Protocol("Invalid response".to_string()))
506 }
507 }
508
509 pub fn hs_swp_start(
518 &mut self,
519 wait_until_done: bool,
520 timeout_ms: i32,
521 ) -> Result<(), NanonisError> {
522 let wait_flag = if wait_until_done { 1i32 } else { 0i32 };
523 self.quick_send(
524 "HSSwp.Start",
525 vec![NanonisValue::I32(wait_flag), NanonisValue::I32(timeout_ms)],
526 vec!["i", "i"],
527 vec![],
528 )?;
529 Ok(())
530 }
531
532 pub fn hs_swp_stop(&mut self) -> Result<(), NanonisError> {
537 self.quick_send("HSSwp.Stop", vec![], vec![], vec![])?;
538 Ok(())
539 }
540
541 pub fn hs_swp_status_get(&mut self) -> Result<bool, NanonisError> {
549 let result = self.quick_send("HSSwp.StatusGet", vec![], vec![], vec!["I"])?;
550
551 if !result.is_empty() {
552 Ok(result[0].as_u32()? != 0)
553 } else {
554 Err(NanonisError::Protocol("Invalid response".to_string()))
555 }
556 }
557
558 pub fn hs_swp_swp_ch_sig_list_get(&mut self) -> Result<HSSwpSignalList, NanonisError> {
566 let result =
567 self.quick_send("HSSwp.SwpChSigListGet", vec![], vec![], vec!["+*c", "+*i"])?;
568
569 if result.len() >= 2 {
570 Ok(HSSwpSignalList {
571 names: result[0].as_string_array()?.to_vec(),
572 indices: result[1].as_i32_array()?.to_vec(),
573 })
574 } else {
575 Err(NanonisError::Protocol("Invalid response".to_string()))
576 }
577 }
578
579 pub fn hs_swp_swp_ch_signal_set(
588 &mut self,
589 signal_index: i32,
590 timed_sweep: bool,
591 ) -> Result<(), NanonisError> {
592 let timed_flag = if timed_sweep { 1i32 } else { 0i32 };
593 self.quick_send(
594 "HSSwp.SwpChSignalSet",
595 vec![
596 NanonisValue::I32(signal_index),
597 NanonisValue::I32(timed_flag),
598 ],
599 vec!["i", "i"],
600 vec![],
601 )?;
602 Ok(())
603 }
604
605 pub fn hs_swp_swp_ch_signal_get(&mut self) -> Result<(i32, bool), NanonisError> {
613 let result = self.quick_send("HSSwp.SwpChSignalGet", vec![], vec![], vec!["i", "i"])?;
614
615 if result.len() >= 2 {
616 Ok((result[0].as_i32()?, result[1].as_i32()? != 0))
617 } else {
618 Err(NanonisError::Protocol("Invalid response".to_string()))
619 }
620 }
621
622 pub fn hs_swp_swp_ch_limits_set(&mut self, limits: &HSSwpLimits) -> Result<(), NanonisError> {
630 let rel_flag = if limits.relative { 1i32 } else { 0i32 };
631 self.quick_send(
632 "HSSwp.SwpChLimitsSet",
633 vec![
634 NanonisValue::I32(rel_flag),
635 NanonisValue::F32(limits.start),
636 NanonisValue::F32(limits.stop),
637 ],
638 vec!["i", "f", "f"],
639 vec![],
640 )?;
641 Ok(())
642 }
643
644 pub fn hs_swp_swp_ch_limits_get(&mut self) -> Result<HSSwpLimits, NanonisError> {
652 let result =
653 self.quick_send("HSSwp.SwpChLimitsGet", vec![], vec![], vec!["i", "f", "f"])?;
654
655 if result.len() >= 3 {
656 Ok(HSSwpLimits {
657 relative: result[0].as_i32()? != 0,
658 start: result[1].as_f32()?,
659 stop: result[2].as_f32()?,
660 })
661 } else {
662 Err(NanonisError::Protocol("Invalid response".to_string()))
663 }
664 }
665
666 pub fn hs_swp_swp_ch_num_pts_set(&mut self, num_points: u32) -> Result<(), NanonisError> {
674 self.quick_send(
675 "HSSwp.SwpChNumPtsSet",
676 vec![NanonisValue::U32(num_points)],
677 vec!["I"],
678 vec![],
679 )?;
680 Ok(())
681 }
682
683 pub fn hs_swp_swp_ch_num_pts_get(&mut self) -> Result<i32, NanonisError> {
691 let result = self.quick_send("HSSwp.SwpChNumPtsGet", vec![], vec![], vec!["i"])?;
692
693 if !result.is_empty() {
694 Ok(result[0].as_i32()?)
695 } else {
696 Err(NanonisError::Protocol("Invalid response".to_string()))
697 }
698 }
699
700 pub fn hs_swp_swp_ch_timing_set(&mut self, timing: &HSSwpTiming) -> Result<(), NanonisError> {
708 self.quick_send(
709 "HSSwp.SwpChTimingSet",
710 vec![
711 NanonisValue::F32(timing.initial_settling_s),
712 NanonisValue::F32(timing.settling_s),
713 NanonisValue::F32(timing.integration_s),
714 NanonisValue::F32(timing.max_slew_rate),
715 ],
716 vec!["f", "f", "f", "f"],
717 vec![],
718 )?;
719 Ok(())
720 }
721
722 pub fn hs_swp_swp_ch_timing_get(&mut self) -> Result<HSSwpTiming, NanonisError> {
730 let result = self.quick_send(
731 "HSSwp.SwpChTimingGet",
732 vec![],
733 vec![],
734 vec!["f", "f", "f", "f"],
735 )?;
736
737 if result.len() >= 4 {
738 Ok(HSSwpTiming {
739 initial_settling_s: result[0].as_f32()?,
740 settling_s: result[1].as_f32()?,
741 integration_s: result[2].as_f32()?,
742 max_slew_rate: result[3].as_f32()?,
743 })
744 } else {
745 Err(NanonisError::Protocol("Invalid response".to_string()))
746 }
747 }
748
749 pub fn hs_swp_swp_ch_bwd_sw_set(&mut self, enabled: bool) -> Result<(), NanonisError> {
757 let flag = if enabled { 1u32 } else { 0u32 };
758 self.quick_send(
759 "HSSwp.SwpChBwdSwSet",
760 vec![NanonisValue::U32(flag)],
761 vec!["I"],
762 vec![],
763 )?;
764 Ok(())
765 }
766
767 pub fn hs_swp_swp_ch_bwd_sw_get(&mut self) -> Result<bool, NanonisError> {
775 let result = self.quick_send("HSSwp.SwpChBwdSwGet", vec![], vec![], vec!["I"])?;
776
777 if !result.is_empty() {
778 Ok(result[0].as_u32()? != 0)
779 } else {
780 Err(NanonisError::Protocol("Invalid response".to_string()))
781 }
782 }
783
784 pub fn hs_swp_swp_ch_bwd_delay_set(&mut self, delay_s: f32) -> Result<(), NanonisError> {
792 self.quick_send(
793 "HSSwp.SwpChBwdDelaySet",
794 vec![NanonisValue::F32(delay_s)],
795 vec!["f"],
796 vec![],
797 )?;
798 Ok(())
799 }
800
801 pub fn hs_swp_swp_ch_bwd_delay_get(&mut self) -> Result<f32, NanonisError> {
809 let result = self.quick_send("HSSwp.SwpChBwdDelayGet", vec![], vec![], vec!["f"])?;
810
811 if !result.is_empty() {
812 Ok(result[0].as_f32()?)
813 } else {
814 Err(NanonisError::Protocol("Invalid response".to_string()))
815 }
816 }
817
818 pub fn hs_swp_z_ctrl_off_set(&mut self, config: &HSSwpZCtrl) -> Result<(), NanonisError> {
826 let switch_off = if config.switch_off { 0i32 } else { 1i32 }; self.quick_send(
828 "HSSwp.ZCtrlOffSet",
829 vec![
830 NanonisValue::I32(switch_off),
831 NanonisValue::I32(config.controller_index),
832 NanonisValue::F32(config.averaging_time_s),
833 NanonisValue::F32(config.z_offset_m),
834 NanonisValue::F32(config.control_time_s),
835 ],
836 vec!["i", "i", "f", "f", "f"],
837 vec![],
838 )?;
839 Ok(())
840 }
841
842 pub fn hs_swp_z_ctrl_off_get(&mut self) -> Result<HSSwpZCtrl, NanonisError> {
850 let result = self.quick_send(
851 "HSSwp.ZCtrlOffGet",
852 vec![],
853 vec![],
854 vec!["i", "i", "f", "f", "f"],
855 )?;
856
857 if result.len() >= 5 {
858 Ok(HSSwpZCtrl {
859 switch_off: result[0].as_i32()? == 0, controller_index: result[1].as_i32()?,
861 averaging_time_s: result[2].as_f32()?,
862 z_offset_m: result[3].as_f32()?,
863 control_time_s: result[4].as_f32()?,
864 })
865 } else {
866 Err(NanonisError::Protocol("Invalid response".to_string()))
867 }
868 }
869}