# DiscoveredInstrument

## class DiscoveredInstrument( resource: str, idn: str, category: str, driver_name: str, num_channels: int | None = None, transport: str = 'visa', backend: str | None = None, serial_config: SerialConfig | None = None, )[source]

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object "(in Python v3.15)")

An instrument that discovery identified and matched to a registered driver.

The record is enough to construct the driver ([`make_driver()`](https://dev.nominal.io/instro/ref/library/instro.lib.discover.DiscoveredInstrument.md#instro.lib.discover.DiscoveredInstrument.make_driver "instro.lib.discover.DiscoveredInstrument.make_driver")) or to emit the `driver`
block of an instro JSON config ([`config_block()`](https://dev.nominal.io/instro/ref/library/instro.lib.discover.DiscoveredInstrument.md#instro.lib.discover.DiscoveredInstrument.config_block "instro.lib.discover.DiscoveredInstrument.config_block")), so scripts and fixtures don’t re-derive
either from the resource string.

Variables:
:   - **resource** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – Address the driver opens: a VISA resource string, or for other transports whatever
      the driver’s constructor takes (an NI-DAQmx device name, an MCC serial number, …).
    - **idn** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – Identity reply the match was made from (the raw `*IDN?` string for SCPI instruments).
    - **category** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – Instrument category (`"psu"`, `"dmm"`, `"daq"`, …).
    - **driver_name** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – Key of the matched driver in the category’s registry
      ([`driver_registry()`](https://dev.nominal.io/instro/ref/library/instro.lib.registry.driver_registry.md#instro.lib.registry.driver_registry "instro.lib.registry.driver_registry")), e.g. `"BK9115"`.
    - **num_channels** ([*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)") *|* *None*) – Programmable channel count where the category tracks it, else `None`.
    - **transport** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – `"visa"` for SCPI-over-VISA instruments. Discovery providers for vendor SDKs
      set their own token; only `"visa"` records can build a [`VisaConfig`](https://dev.nominal.io/instro/ref/library/instro.lib.transports.visa.VisaConfig.md#instro.lib.transports.visa.VisaConfig "instro.lib.discover.VisaConfig").
    - **backend** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*) – pyvisa backend the scan was asked for (`None` for the default with fallback), so
      [`visa_config()`](https://dev.nominal.io/instro/ref/library/instro.lib.discover.DiscoveredInstrument.md#instro.lib.discover.DiscoveredInstrument.visa_config "instro.lib.discover.DiscoveredInstrument.visa_config") resolves it the same way the scan did.
    - **serial_config** ([*SerialConfig*](https://dev.nominal.io/instro/ref/library/instro.lib.transports.visa.SerialConfig.md#instro.lib.transports.visa.SerialConfig "instro.lib.transports.visa.SerialConfig") *|* *None*) – Serial settings a serial (`ASRL`) instrument answered with, else `None`.

Example:

```
report = scan_visa_resources()
psu = next(i for i in report.instruments if i.category == "psu")
instro_psu = InstroPSU(name="psu", driver=psu.make_driver(), num_channels=psu.num_channels)
```

### resource: str

### idn: str

### category: str

### driver_name: str

### num_channels: int | None = None

### transport: str = 'visa'

### backend: str | None = None

### serial_config: SerialConfig | None = None

### property driver_class_name: str

Deprecated alias of [`driver_name`](https://dev.nominal.io/instro/ref/library/instro.lib.discover.DiscoveredInstrument.md#instro.lib.discover.DiscoveredInstrument.driver_name "instro.lib.discover.DiscoveredInstrument.driver_name").

### visa_config() → VisaConfig[source]

The [`VisaConfig`](https://dev.nominal.io/instro/ref/library/instro.lib.transports.visa.VisaConfig.md#instro.lib.transports.visa.VisaConfig "instro.lib.discover.VisaConfig") that reaches this instrument, carrying the backend and serial settings it answered with.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – the instrument is not on the VISA transport.

### driver_class() → type[source]

The matched driver class, loaded from the category’s driver registry on demand.

Raises:
:   [**KeyError**](https://docs.python.org/3/builtins/exceptions.html#KeyError "(in Python v3.15)") – `driver_name` is not registered for `category`.

### make_driver() → Any[source]

A new, unopened driver for this instrument.

VISA instruments get a [`VisaConfig`](https://dev.nominal.io/instro/ref/library/instro.lib.transports.visa.VisaConfig.md#instro.lib.transports.visa.VisaConfig "instro.lib.discover.VisaConfig"); drivers on other transports receive
[`resource`](https://dev.nominal.io/instro/ref/library/instro.lib.discover.DiscoveredInstrument.md#instro.lib.discover.DiscoveredInstrument.resource "instro.lib.discover.DiscoveredInstrument.resource") directly, which is the `device_id` convention the DAQ vendor drivers use.

### config_block() → dict[str, Any][source]

The `driver` block of an instro JSON config for this instrument.

`num_channels` is included when discovery knows it, which is exactly the set of categories
whose driver config requires it (psu, scope, awg).

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – the instrument is not on the VISA transport, which is the only one with a
    JSON config schema today.
