Task specs¶
TaskSpec is the declarative configuration object for one NI task. See
design doc ยง8.1.
Shape¶
from nidaqlib import AnalogInputVoltage, AcquisitionMode, TaskSpec, Timing
spec = TaskSpec(
name="fast_ai",
channels=[
AnalogInputVoltage(
physical_channel="Dev1/ai0",
name="pressure",
unit="V",
min_val=-5.0,
max_val=5.0,
),
],
timing=Timing(
rate_hz=10_000.0,
mode=AcquisitionMode.CONTINUOUS,
samples_per_channel=10_000,
),
metadata={"run_id": "2026-04-29-a"},
)
Fields:
namelabels the NI task and emittedDaqReading/DaqBlockrows.channelsis one or moreChannelSpecinstances. Display names must be unique within the task.timing=Nonemeans software-polled/on-demand;Timing(...)configures an NI sample clock.triggeraccepts aTriggerSpecsuch asDigitalEdgeStartTriggerorDigitalEdgeReferenceTrigger.loggingacceptsTdmsLoggingfor NI driver-side TDMS logging.metadatais scalar, free-form run context propagated into emitted records.
TaskSpec and channel specs are frozen dataclasses. Construction
validates cheap invariants before anything reaches NI: non-empty task
names, at least one channel, duplicate display names, invalid ranges, and
malformed trigger/channel payloads.
Serialization¶
Every task spec round-trips through JSON-friendly dictionaries:
Channels and triggers carry a kind discriminator so subclasses survive
round-trip serialization. Timing, TriggerSpec, TdmsLogging, and
RunMetadata use the same pattern.
Opening¶
open_device is a plain async factory. Await it to get a configured
DaqSession; use the session as the async context manager:
from nidaqlib import open_device
async with await open_device(spec) as session:
block = await session.read_block(samples_per_channel=1000)
Pass autostart=False when a recorder needs to register callbacks before
NI starts the task. Pass confirm_start=True for counter-output tasks
that actuate on start.