Skip to content

nidaqlib.system

nidaqlib.system

System discovery — :func:list_devices, :func:list_physical_channels.

Wraps :class:nidaqmx.system.System.local() enough to drive helpful CLI commands and basic preflight validation; not a clone of NI MAX (design doc §19).

DeviceInfo dataclass

DeviceInfo(
    *,
    name,
    product_type,
    serial_number,
    ai_physical_channels,
    ao_physical_channels,
    di_lines,
    do_lines,
    ci_physical_channels,
    co_physical_channels,
)

Snapshot of one NI device's identity and physical channel inventory.

Populated by :func:~nidaqlib.system.discovery.list_devices. Frozen so consumers can pass it around without worrying about staleness — re-call discovery to refresh.

list_devices

list_devices()

Enumerate visible NI devices and their physical-channel inventories.

Returns:

Name Type Description
One list[DeviceInfo]

class:DeviceInfo per device. Empty list when no NI hardware

list[DeviceInfo]

is present.

Raises:

Type Description
NIDaqBackendError

NI raised an unexpected error during enumeration.

NIDaqDependencyError

nidaqmx-python is not installed.

Source code in src/nidaqlib/system/discovery.py
def list_devices() -> list[DeviceInfo]:
    """Enumerate visible NI devices and their physical-channel inventories.

    Returns:
        One :class:`DeviceInfo` per device. Empty list when no NI hardware
        is present.

    Raises:
        NIDaqBackendError: NI raised an unexpected error during enumeration.
        NIDaqDependencyError: ``nidaqmx-python`` is not installed.
    """
    nidaqmx = _import_nidaqmx()
    try:
        system = nidaqmx.system.System.local()
        devices = list(system.devices)
    except nidaqmx.errors.DaqError as exc:  # pragma: no cover - hardware path
        raise NIDaqBackendError(
            "failed to enumerate NI devices",
            context=ErrorContext(
                operation="list_devices",
                ni_error_code=getattr(exc, "error_code", None),
            ),
        ) from exc

    return [
        DeviceInfo(
            name=dev.name,
            product_type=getattr(dev, "product_type", None),
            serial_number=str(getattr(dev, "serial_num", None) or "") or None,
            ai_physical_channels=_channel_names(getattr(dev, "ai_physical_chans", ())),
            ao_physical_channels=_channel_names(getattr(dev, "ao_physical_chans", ())),
            di_lines=_channel_names(getattr(dev, "di_lines", ())),
            do_lines=_channel_names(getattr(dev, "do_lines", ())),
            ci_physical_channels=_channel_names(getattr(dev, "ci_physical_chans", ())),
            co_physical_channels=_channel_names(getattr(dev, "co_physical_chans", ())),
        )
        for dev in devices
    ]

list_physical_channels

list_physical_channels(device)

Return AI physical channel names for device (e.g. "Dev1").

For inventories of AO / DI / DO / counters, use :func:list_devices and inspect the returned :class:DeviceInfo.

Raises:

Type Description
NIDaqBackendError

NI rejected the request (e.g. unknown device).

Source code in src/nidaqlib/system/discovery.py
def list_physical_channels(device: str) -> tuple[str, ...]:
    """Return AI physical channel names for ``device`` (e.g. ``"Dev1"``).

    For inventories of AO / DI / DO / counters, use :func:`list_devices` and
    inspect the returned :class:`DeviceInfo`.

    Raises:
        NIDaqBackendError: NI rejected the request (e.g. unknown device).
    """
    nidaqmx = _import_nidaqmx()
    try:
        dev = nidaqmx.system.Device(device)
        return _channel_names(dev.ai_physical_chans)
    except nidaqmx.errors.DaqError as exc:  # pragma: no cover - hardware path
        raise NIDaqBackendError(
            f"failed to list physical channels for {device!r}",
            context=ErrorContext(
                operation="list_physical_channels",
                ni_error_code=getattr(exc, "error_code", None),
            ),
        ) from exc