Skip to content

Commit 6e6bcfb

Browse files
committed
Get TCPIP VISA Instrument Info from LXI ID Page Instead of *IDN?
This is a less disruptive way to get the Instrument information since it gets this information from the webpage instead of from the command processor on the instrument. Testing: This has been tested using NI VISA and a Keithley Model 2461
1 parent 6531224 commit 6e6bcfb

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

kic-discover-visa/src/visa.rs

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::HashSet, ffi::CString, time::Duration};
1+
use std::{collections::HashSet, ffi::CString, net::IpAddr, time::Duration};
22

33
use serde::{Deserialize, Serialize};
44
use tracing::{error, trace};
@@ -9,7 +9,19 @@ use tsp_toolkit_kic_lib::{
99
};
1010
use visa_rs::AsResourceManager;
1111

12-
use crate::{insert_disc_device, model_check, IoType};
12+
use crate::{ethernet::LxiDeviceInfo, insert_disc_device, model_check, IoType};
13+
14+
/// Extract the IP address from the resource string and then get the [`LxiDeviceInfo`]
15+
/// which can be converted to [`InstrumentInfo`].
16+
/// Returns [`None`] in all error cases
17+
pub async fn visa_tcpip_info(rsc: String) -> Option<InstrumentInfo> {
18+
let [_, ip_addr, ..] = rsc.split("::").collect::<Vec<&str>>()[..] else {
19+
return None;
20+
};
21+
let instr_addr: IpAddr = ip_addr.parse().ok()?;
22+
let lxi_xml = LxiDeviceInfo::query_lxi_xml(instr_addr).await?;
23+
Some(LxiDeviceInfo::parse_lxi_xml(&lxi_xml, instr_addr)?.into())
24+
}
1325

1426
#[tracing::instrument]
1527
pub async fn visa_discover(timeout: Option<Duration>) -> anyhow::Result<HashSet<InstrumentInfo>> {
@@ -32,53 +44,52 @@ pub async fn visa_discover(timeout: Option<Duration>) -> anyhow::Result<HashSet<
3244
let Ok(i) = i else {
3345
continue;
3446
};
47+
3548
if i.to_string().contains("SOCKET") || i.to_string().contains("INTFC") {
3649
continue;
3750
}
38-
trace!("Connecting to {i:?} to get info");
39-
let Ok(interface) = Protocol::try_from_visa(i.to_string()) else {
40-
trace!("Resource {i} no longer available, skipping.");
41-
continue;
42-
};
43-
let mut connected: Box<dyn Instrument> = match interface.try_into() {
44-
Ok(c) => c,
45-
Err(_) => {
51+
52+
let info = if i.to_string().starts_with("TCPIP") {
53+
trace!("Getting info from LXI page");
54+
visa_tcpip_info(i.to_string()).await
55+
} else {
56+
trace!("Connecting to {i:?} to get info");
57+
let Ok(interface) = Protocol::try_from_visa(i.to_string()) else {
4658
trace!("Resource {i} no longer available, skipping.");
4759
continue;
48-
}
49-
};
50-
//let Ok(mut connected) = rm.open(&i, AccessMode::NO_LOCK, visa_rs::TIMEOUT_IMMEDIATE) else {
51-
// trace!("Resource {i} no longer available, skipping.");
52-
// continue;
53-
//};
60+
};
61+
let mut connected: Box<dyn Instrument> = match interface.try_into() {
62+
Ok(c) => c,
63+
Err(_) => {
64+
trace!("Resource {i} no longer available, skipping.");
65+
continue;
66+
}
67+
};
5468

55-
trace!("Getting info from {:?}", i);
56-
let Ok(mut info) = connected.info() else {
57-
trace!("Unable to write to {i}, skipping");
58-
drop(connected);
59-
continue;
69+
trace!("Getting info from {:?}", i);
70+
connected.info().ok()
6071
};
61-
trace!("Dropping instrument");
62-
drop(connected);
6372

64-
info.address = Some(ConnectionAddr::Visa(i.clone()));
65-
trace!("Got info: {info:?}");
66-
let res = model_check(info.clone().model.unwrap_or("".to_string()).as_str());
67-
if res.0 {
68-
if let Ok(out_str) = serde_json::to_string(&VisaDeviceInfo {
69-
io_type: IoType::Visa,
70-
instr_address: i.to_string(),
71-
manufacturer: "Keithley Instruments".to_string(),
72-
model: info.clone().model.unwrap_or("UNKNOWN".to_string()),
73-
serial_number: info.clone().serial_number.unwrap_or("UNKNOWN".to_string()),
74-
firmware_revision: info.clone().firmware_rev.unwrap_or("UNKNOWN".to_string()),
75-
instr_categ: model_check(info.clone().model.unwrap_or("".to_string()).as_str())
76-
.1
77-
.to_string(),
78-
}) {
79-
insert_disc_device(out_str.as_str())?;
73+
if let Some(mut info) = info {
74+
info.address = Some(ConnectionAddr::Visa(i.clone()));
75+
trace!("Got info: {info:?}");
76+
let res = model_check(info.clone().model.unwrap_or("".to_string()).as_str());
77+
if res.0 {
78+
if let Ok(out_str) = serde_json::to_string(&VisaDeviceInfo {
79+
io_type: IoType::Visa,
80+
instr_address: i.to_string(),
81+
manufacturer: "Keithley Instruments".to_string(),
82+
model: info.clone().model.unwrap_or("UNKNOWN".to_string()),
83+
serial_number: info.clone().serial_number.unwrap_or("UNKNOWN".to_string()),
84+
firmware_revision: info.clone().firmware_rev.unwrap_or("UNKNOWN".to_string()),
85+
instr_categ: model_check(info.clone().model.unwrap_or("".to_string()).as_str())
86+
.1
87+
.to_string(),
88+
}) {
89+
insert_disc_device(out_str.as_str())?;
90+
}
91+
discovered_instruments.insert(info);
8092
}
81-
discovered_instruments.insert(info);
8293
}
8394
}
8495
Ok(discovered_instruments)

0 commit comments

Comments
 (0)