step_insert/
step_insert.rs1use rs_teststand::{
17 AdapterKeyName, Engine, Error, PropertyOptions, ResultRecordingOption, RunMode, Sequence, Step,
18 StepGroup,
19};
20
21const VI_PATH: &str = "TS.SData.ViCall.VIPath";
23const PROJECT_PATH: &str = "TS.SData.ViCall.ProjectPath";
25const TARGET_STEP: &str = "Initialize Hardware";
27
28const fn none() -> i32 {
29 PropertyOptions::NONE.bits()
30}
31
32const fn insert_if_missing() -> i32 {
33 PropertyOptions::INSERT_IF_MISSING.bits()
34}
35
36fn vi_call_step(
38 engine: &Engine,
39 name: &str,
40 vi_path: &str,
41 project_path: &str,
42 run_mode: RunMode,
43) -> Result<Step, Error> {
44 let step = engine.new_step(AdapterKeyName::LabView.as_str(), "Action")?;
45 step.set_name(name)?;
46 step.set_run_mode(run_mode)?;
47 step.set_result_recording_option(ResultRecordingOption::Enabled)?;
50
51 let properties = step.as_property_object()?;
52 properties.set_val_string(VI_PATH, insert_if_missing(), vi_path)?;
53 if !project_path.is_empty() {
54 properties.set_val_string(PROJECT_PATH, insert_if_missing(), project_path)?;
55 }
56 Ok(step)
57}
58
59fn index_of(sequence: &Sequence, name: &str, group: StepGroup) -> Result<Option<i32>, Error> {
65 for index in 0..sequence.get_num_steps(group)? {
66 if sequence.get_step(index, group)?.name()? == name {
67 return Ok(Some(index));
68 }
69 }
70 Ok(None)
71}
72
73fn main() -> Result<(), Box<dyn std::error::Error>> {
74 let engine = Engine::new()?;
75
76 let sequence_file = engine.new_sequence_file()?;
79 let subsequence = engine.new_sequence()?;
80 subsequence.set_name("CustomSubsequence")?;
81 let existing = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "Action")?;
82 existing.set_name(TARGET_STEP)?;
83 subsequence.insert_step(&existing, 0, StepGroup::Main)?;
84 sequence_file.insert_sequence(&subsequence)?;
85
86 let insert_at = if let Some(index) = index_of(&subsequence, TARGET_STEP, StepGroup::Main)? {
88 println!("Found {TARGET_STEP} at index {index}; inserting in front of it.");
89 index
90 } else {
91 let end = subsequence.get_num_steps(StepGroup::Main)?;
92 println!("{TARGET_STEP} not found; appending at index {end}.");
93 end
94 };
95
96 for (offset, (name, vi, project, mode)) in [
97 (
98 "Measure Voltage (VI)",
99 r"instruments.lvlibp\measure_voltage.vi",
100 "",
101 RunMode::Normal,
102 ),
103 (
104 "Measure Current (VI)",
105 r"instruments.lvlibp\measure_current.vi",
106 r"instruments.lvproj",
107 RunMode::Skip,
108 ),
109 ]
110 .into_iter()
111 .enumerate()
112 {
113 let step = vi_call_step(&engine, name, vi, project, mode)?;
114 let at = insert_at + i32::try_from(offset).unwrap_or(0);
115 subsequence.insert_step(&step, at, StepGroup::Main)?;
116 }
117
118 println!(
119 "\n{} now holds {} step(s):",
120 subsequence.name()?,
121 subsequence.get_num_steps(StepGroup::Main)?
122 );
123 for index in 0..subsequence.get_num_steps(StepGroup::Main)? {
124 let step = subsequence.get_step(index, StepGroup::Main)?;
125 let properties = step.as_property_object()?;
126 let vi = properties
127 .get_val_string(VI_PATH, none())
128 .unwrap_or_else(|_| "<no VI>".to_owned());
129 println!(
130 " [{index}] {} - {:?}, run mode {:?}, records {:?}",
131 step.name()?,
132 step.adapter_key_name()?,
133 step.run_mode()?,
134 step.result_recording_option()?
135 );
136 if vi != "<no VI>" {
137 println!(" calls {vi}");
138 }
139 }
140
141 let path = std::env::temp_dir().join("rs_teststand_step_insert.seq");
142 let path = path.to_string_lossy().into_owned();
143 sequence_file.save(&path)?;
144 println!("\nSaved to {path}");
145 Ok(())
146}