use rs_teststand::{
AdapterKeyName, Engine, Error, PropertyOptions, ResultRecordingOption, RunMode, Sequence, Step,
StepGroup,
};
const VI_PATH: &str = "TS.SData.ViCall.VIPath";
const PROJECT_PATH: &str = "TS.SData.ViCall.ProjectPath";
const TARGET_STEP: &str = "Initialize Hardware";
const fn none() -> i32 {
PropertyOptions::NONE.bits()
}
const fn insert_if_missing() -> i32 {
PropertyOptions::INSERT_IF_MISSING.bits()
}
fn vi_call_step(
engine: &Engine,
name: &str,
vi_path: &str,
project_path: &str,
run_mode: RunMode,
) -> Result<Step, Error> {
let step = engine.new_step(AdapterKeyName::LabView.as_str(), "Action")?;
step.set_name(name)?;
step.set_run_mode(run_mode)?;
step.set_result_recording_option(ResultRecordingOption::Enabled)?;
let properties = step.as_property_object()?;
properties.set_val_string(VI_PATH, insert_if_missing(), vi_path)?;
if !project_path.is_empty() {
properties.set_val_string(PROJECT_PATH, insert_if_missing(), project_path)?;
}
Ok(step)
}
fn index_of(sequence: &Sequence, name: &str, group: StepGroup) -> Result<Option<i32>, Error> {
for index in 0..sequence.get_num_steps(group)? {
if sequence.get_step(index, group)?.name()? == name {
return Ok(Some(index));
}
}
Ok(None)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let engine = Engine::new()?;
let sequence_file = engine.new_sequence_file()?;
let subsequence = engine.new_sequence()?;
subsequence.set_name("CustomSubsequence")?;
let existing = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "Action")?;
existing.set_name(TARGET_STEP)?;
subsequence.insert_step(&existing, 0, StepGroup::Main)?;
sequence_file.insert_sequence(&subsequence)?;
let insert_at = if let Some(index) = index_of(&subsequence, TARGET_STEP, StepGroup::Main)? {
println!("Found {TARGET_STEP} at index {index}; inserting in front of it.");
index
} else {
let end = subsequence.get_num_steps(StepGroup::Main)?;
println!("{TARGET_STEP} not found; appending at index {end}.");
end
};
for (offset, (name, vi, project, mode)) in [
(
"Measure Voltage (VI)",
r"instruments.lvlibp\measure_voltage.vi",
"",
RunMode::Normal,
),
(
"Measure Current (VI)",
r"instruments.lvlibp\measure_current.vi",
r"instruments.lvproj",
RunMode::Skip,
),
]
.into_iter()
.enumerate()
{
let step = vi_call_step(&engine, name, vi, project, mode)?;
let at = insert_at + i32::try_from(offset).unwrap_or(0);
subsequence.insert_step(&step, at, StepGroup::Main)?;
}
println!(
"\n{} now holds {} step(s):",
subsequence.name()?,
subsequence.get_num_steps(StepGroup::Main)?
);
for index in 0..subsequence.get_num_steps(StepGroup::Main)? {
let step = subsequence.get_step(index, StepGroup::Main)?;
let properties = step.as_property_object()?;
let vi = properties
.get_val_string(VI_PATH, none())
.unwrap_or_else(|_| "<no VI>".to_owned());
println!(
" [{index}] {} - {:?}, run mode {:?}, records {:?}",
step.name()?,
step.adapter_key_name()?,
step.run_mode()?,
step.result_recording_option()?
);
if vi != "<no VI>" {
println!(" calls {vi}");
}
}
let path = std::env::temp_dir().join("rs_teststand_step_insert.seq");
let path = path.to_string_lossy().into_owned();
sequence_file.save(&path)?;
println!("\nSaved to {path}");
Ok(())
}