nidaqmx 1.3.0.dev0__tar.gz → 1.4.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/PKG-INFO +8 -6
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/README.rst +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_base_interpreter.py +15 -4
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_dotenvpath.py +1 -16
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_feature_toggles.py +3 -5
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_grpc_interpreter.py +147 -13
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_install_daqmx.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_installer_metadata.json +6 -6
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_lib.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_library_interpreter.py +44 -36
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_linux_installation_commands.py +1 -1
- nidaqmx-1.4.0.dev0/generated/nidaqmx/_stubs/nidaqmx_pb2.py +2362 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/nidaqmx_pb2.pyi +213 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/nidaqmx_pb2_grpc.py +132 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/nidaqmx_pb2_grpc.pyi +68 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_time.py +20 -4
- nidaqmx-1.4.0.dev0/generated/nidaqmx/_waveform_utils.py +18 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_analog_multi_channel_reader.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_analog_single_channel_reader.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_channel_reader_base.py +2 -4
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_digital_multi_channel_reader.py +3 -5
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_channel_writer_base.py +2 -4
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_digital_multi_channel_writer.py +2 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/__init__.py +1 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/device_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/persisted_channel_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/persisted_scale_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/persisted_task_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/physical_channel_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_watchdog_modules/expiration_states_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/physical_channel.py +2 -3
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/system.py +5 -5
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/_in_stream.py +5 -5
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/_task.py +11 -7
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_channel_collection.py +1 -1
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/types.py +4 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/pyproject.toml +22 -25
- nidaqmx-1.3.0.dev0/generated/nidaqmx/_stubs/nidaqmx_pb2.py +0 -2343
- nidaqmx-1.3.0.dev0/generated/nidaqmx/_stubs/session_pb2.py +0 -52
- nidaqmx-1.3.0.dev0/generated/nidaqmx/_stubs/session_pb2.pyi +0 -240
- nidaqmx-1.3.0.dev0/generated/nidaqmx/_stubs/session_pb2_grpc.py +0 -204
- nidaqmx-1.3.0.dev0/generated/nidaqmx/_stubs/session_pb2_grpc.pyi +0 -130
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/LICENSE +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/__main__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_bitfield_utils.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_grpc_time.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_lib_time.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/data_moniker_pb2.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/data_moniker_pb2.pyi +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/data_moniker_pb2_grpc.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/_stubs/data_moniker_pb2_grpc.pyi +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/constants.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/error_codes.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/errors.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/grpc_session_options.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/scale.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_analog_unscaled_reader.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_counter_reader.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_digital_single_channel_reader.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_readers/_power_readers.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_analog_multi_channel_writer.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_analog_single_channel_writer.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_analog_unscaled_writer.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_counter_writer.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/stream_writers/_digital_single_channel_writer.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_collections/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_watchdog_modules/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/_watchdog_modules/expiration_state.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/device.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/storage/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/storage/persisted_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/storage/persisted_scale.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/storage/persisted_task.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/system/watchdog.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/_export_signals.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/_out_stream.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/_timing.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_ai_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_ao_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_ci_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_co_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_di_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/channels/_do_channel.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_ai_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_ao_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_ci_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_co_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_di_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/collections/_do_channel_collection.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/__init__.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_arm_start_trigger.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_handshake_trigger.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_pause_trigger.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_reference_trigger.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_start_trigger.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/task/triggering/_triggers.py +0 -0
- {nidaqmx-1.3.0.dev0 → nidaqmx-1.4.0.dev0}/generated/nidaqmx/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nidaqmx
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0.dev0
|
|
4
4
|
Summary: NI-DAQmx Python API
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: nidaqmx,nidaq,daqmx,daq
|
|
@@ -8,7 +8,7 @@ Author: NI
|
|
|
8
8
|
Author-email: opensource@ni.com
|
|
9
9
|
Maintainer: Zach Hindes
|
|
10
10
|
Maintainer-email: zach.hindes@ni.com
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.10,<4.0
|
|
12
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: Intended Audience :: Manufacturing
|
|
@@ -17,11 +17,11 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
17
17
|
Classifier: Operating System :: Microsoft :: Windows
|
|
18
18
|
Classifier: Operating System :: POSIX
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
27
|
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
@@ -31,8 +31,10 @@ Requires-Dist: deprecation (>=2.1)
|
|
|
31
31
|
Requires-Dist: distro (>=1.9.0) ; sys_platform == "linux"
|
|
32
32
|
Requires-Dist: grpcio (>=1.49.0,<2.0) ; extra == "grpc"
|
|
33
33
|
Requires-Dist: hightime (>=0.2.2)
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
34
|
+
Requires-Dist: ni-grpcdevice-v1-proto (>=1.0.0) ; extra == "grpc"
|
|
35
|
+
Requires-Dist: ni-protobuf-types (>=1.0.0) ; extra == "grpc"
|
|
36
|
+
Requires-Dist: nitypes (>=1.0.0)
|
|
37
|
+
Requires-Dist: numpy (>=1.22) ; python_version >= "3.10" and python_version < "3.13"
|
|
36
38
|
Requires-Dist: numpy (>=2.1) ; python_version >= "3.13" and python_version < "4.0"
|
|
37
39
|
Requires-Dist: protobuf (>=4.21) ; extra == "grpc"
|
|
38
40
|
Requires-Dist: python-decouple (>=3.8)
|
|
@@ -100,7 +102,7 @@ system.
|
|
|
100
102
|
Python Version Support
|
|
101
103
|
----------------------
|
|
102
104
|
|
|
103
|
-
**nidaqmx** supports CPython 3.
|
|
105
|
+
**nidaqmx** supports CPython 3.10+.
|
|
104
106
|
|
|
105
107
|
**nidaqmx** supports PyPy3 for non-gRPC use cases. For the status of PyPy support for gRPC,
|
|
106
108
|
see `PyPy support (grpc/grpc#4221) <https://github.com/grpc/grpc/issues/4221>`_.
|
|
@@ -55,7 +55,7 @@ system.
|
|
|
55
55
|
Python Version Support
|
|
56
56
|
----------------------
|
|
57
57
|
|
|
58
|
-
**nidaqmx** supports CPython 3.
|
|
58
|
+
**nidaqmx** supports CPython 3.10+.
|
|
59
59
|
|
|
60
60
|
**nidaqmx** supports PyPy3 for non-gRPC use cases. For the status of PyPy support for gRPC,
|
|
61
61
|
see `PyPy support (grpc/grpc#4221) <https://github.com/grpc/grpc/issues/4221>`_.
|
|
@@ -4,7 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
import abc
|
|
5
5
|
import numpy
|
|
6
6
|
from nitypes.waveform import AnalogWaveform, DigitalWaveform
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from collections.abc import Sequence
|
|
8
10
|
from nidaqmx.constants import WaveformAttributeMode
|
|
9
11
|
|
|
10
12
|
|
|
@@ -1093,6 +1095,10 @@ class BaseInterpreter(abc.ABC):
|
|
|
1093
1095
|
def get_timing_attribute_string(self, task, attribute):
|
|
1094
1096
|
raise NotImplementedError
|
|
1095
1097
|
|
|
1098
|
+
@abc.abstractmethod
|
|
1099
|
+
def get_timing_attribute_timestamp(self, task, attribute):
|
|
1100
|
+
raise NotImplementedError
|
|
1101
|
+
|
|
1096
1102
|
@abc.abstractmethod
|
|
1097
1103
|
def get_timing_attribute_uint32(self, task, attribute):
|
|
1098
1104
|
raise NotImplementedError
|
|
@@ -1852,6 +1858,11 @@ class BaseInterpreter(abc.ABC):
|
|
|
1852
1858
|
def hash_task_handle(self, task_handle):
|
|
1853
1859
|
raise NotImplementedError
|
|
1854
1860
|
|
|
1861
|
+
@property
|
|
1862
|
+
@abc.abstractmethod
|
|
1863
|
+
def driver_version(self):
|
|
1864
|
+
raise NotImplementedError
|
|
1865
|
+
|
|
1855
1866
|
@abc.abstractmethod
|
|
1856
1867
|
def read_analog_waveform(
|
|
1857
1868
|
self,
|
|
@@ -1873,7 +1884,7 @@ class BaseInterpreter(abc.ABC):
|
|
|
1873
1884
|
waveform_attribute_mode: WaveformAttributeMode
|
|
1874
1885
|
) -> int:
|
|
1875
1886
|
raise NotImplementedError
|
|
1876
|
-
|
|
1887
|
+
|
|
1877
1888
|
@abc.abstractmethod
|
|
1878
1889
|
def read_digital_waveform(
|
|
1879
1890
|
self,
|
|
@@ -1929,7 +1940,7 @@ class BaseInterpreter(abc.ABC):
|
|
|
1929
1940
|
timeout: float
|
|
1930
1941
|
) -> int:
|
|
1931
1942
|
raise NotImplementedError
|
|
1932
|
-
|
|
1943
|
+
|
|
1933
1944
|
@abc.abstractmethod
|
|
1934
1945
|
def write_digital_waveform(
|
|
1935
1946
|
self,
|
|
@@ -1939,7 +1950,7 @@ class BaseInterpreter(abc.ABC):
|
|
|
1939
1950
|
timeout: float,
|
|
1940
1951
|
) -> int:
|
|
1941
1952
|
raise NotImplementedError
|
|
1942
|
-
|
|
1953
|
+
|
|
1943
1954
|
def write_digital_waveforms(
|
|
1944
1955
|
self,
|
|
1945
1956
|
task_handle: object,
|
|
@@ -45,27 +45,12 @@ def _get_caller_path() -> Path | None:
|
|
|
45
45
|
for frame, _ in traceback.walk_stack(inspect.currentframe()):
|
|
46
46
|
if frame.f_code.co_filename:
|
|
47
47
|
module_path = Path(frame.f_code.co_filename)
|
|
48
|
-
if
|
|
48
|
+
if module_path.exists() and not module_path.is_relative_to(package_path):
|
|
49
49
|
return module_path
|
|
50
50
|
|
|
51
51
|
return None
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
# Path.exists() throws OSError when the path has invalid file characters.
|
|
55
|
-
# https://github.com/python/cpython/issues/79487
|
|
56
|
-
if sys.version_info >= (3, 10):
|
|
57
|
-
|
|
58
|
-
def _exists(path: Path) -> bool:
|
|
59
|
-
return path.exists()
|
|
60
|
-
|
|
61
|
-
else:
|
|
62
|
-
|
|
63
|
-
def _exists(path: Path) -> bool:
|
|
64
|
-
import os
|
|
65
|
-
|
|
66
|
-
return os.path.exists(path)
|
|
67
|
-
|
|
68
|
-
|
|
69
54
|
def _get_package_path() -> Path:
|
|
70
55
|
"""Get the path of this package."""
|
|
71
56
|
module = sys.modules[__package__]
|
|
@@ -4,8 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import functools
|
|
6
6
|
import sys
|
|
7
|
+
from collections.abc import Callable
|
|
7
8
|
from enum import Enum
|
|
8
|
-
from typing import TYPE_CHECKING,
|
|
9
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
9
10
|
|
|
10
11
|
from decouple import AutoConfig, Undefined, undefined
|
|
11
12
|
|
|
@@ -13,10 +14,7 @@ from nidaqmx._dotenvpath import get_dotenv_search_path
|
|
|
13
14
|
from nidaqmx.errors import FeatureNotSupportedError
|
|
14
15
|
|
|
15
16
|
if TYPE_CHECKING:
|
|
16
|
-
|
|
17
|
-
from typing import ParamSpec
|
|
18
|
-
else:
|
|
19
|
-
from typing_extensions import ParamSpec
|
|
17
|
+
from typing import ParamSpec
|
|
20
18
|
|
|
21
19
|
if sys.version_info >= (3, 11):
|
|
22
20
|
from typing import Self
|
|
@@ -6,10 +6,11 @@ import threading
|
|
|
6
6
|
import typing
|
|
7
7
|
import warnings
|
|
8
8
|
from nitypes.waveform import AnalogWaveform, DigitalWaveform
|
|
9
|
-
from typing import Any,
|
|
9
|
+
from typing import Any, Generic, TypeVar
|
|
10
|
+
|
|
11
|
+
from collections.abc import Callable, Sequence
|
|
10
12
|
|
|
11
13
|
import google.protobuf.message
|
|
12
|
-
from google.protobuf.timestamp_pb2 import Timestamp as GrpcTimestamp
|
|
13
14
|
import grpc
|
|
14
15
|
import numpy
|
|
15
16
|
|
|
@@ -17,10 +18,18 @@ from . import errors as errors
|
|
|
17
18
|
from nidaqmx._base_interpreter import BaseEventHandler, BaseInterpreter
|
|
18
19
|
from nidaqmx._stubs import nidaqmx_pb2 as grpc_types
|
|
19
20
|
from nidaqmx._stubs import nidaqmx_pb2_grpc as nidaqmx_grpc
|
|
20
|
-
from
|
|
21
|
+
from ni.protobuf.types.waveform_conversion import (
|
|
22
|
+
digital_waveform_from_protobuf,
|
|
23
|
+
digital_waveform_to_protobuf,
|
|
24
|
+
float64_analog_waveform_from_protobuf,
|
|
25
|
+
float64_analog_waveform_to_protobuf
|
|
26
|
+
)
|
|
21
27
|
from nidaqmx.constants import WaveformAttributeMode
|
|
22
28
|
from nidaqmx.error_codes import DAQmxErrors
|
|
29
|
+
from nidaqmx.types import DriverVersion
|
|
23
30
|
from nidaqmx._grpc_time import convert_time_to_timestamp, convert_timestamp_to_time
|
|
31
|
+
from nidaqmx._waveform_utils import get_num_samps_per_chan
|
|
32
|
+
from session_pb2 import Session
|
|
24
33
|
|
|
25
34
|
_logger = logging.getLogger(__name__)
|
|
26
35
|
|
|
@@ -86,11 +95,21 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
86
95
|
__slots__ = [
|
|
87
96
|
'_grpc_options',
|
|
88
97
|
'_client',
|
|
98
|
+
'_driver_version',
|
|
89
99
|
]
|
|
90
100
|
|
|
91
101
|
def __init__(self, grpc_options):
|
|
92
102
|
self._grpc_options = grpc_options
|
|
93
103
|
self._client = nidaqmx_grpc.NiDAQmxStub(grpc_options.grpc_channel)
|
|
104
|
+
try:
|
|
105
|
+
major_version = self.get_system_info_attribute_uint32(0x1272)
|
|
106
|
+
minor_version = self.get_system_info_attribute_uint32(0x1923)
|
|
107
|
+
update_version = self.get_system_info_attribute_uint32(0x2f22)
|
|
108
|
+
except Exception:
|
|
109
|
+
major_version = 0
|
|
110
|
+
minor_version = 0
|
|
111
|
+
update_version = 0
|
|
112
|
+
self._driver_version = DriverVersion(major_version, minor_version, update_version)
|
|
94
113
|
|
|
95
114
|
def _invoke(self, func, request, metadata=None):
|
|
96
115
|
try:
|
|
@@ -169,6 +188,10 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
169
188
|
except grpc.RpcError as rpc_error:
|
|
170
189
|
self._handle_rpc_error(rpc_error)
|
|
171
190
|
|
|
191
|
+
@property
|
|
192
|
+
def driver_version(self):
|
|
193
|
+
return self._driver_version
|
|
194
|
+
|
|
172
195
|
def add_cdaq_sync_connection(self, port_list):
|
|
173
196
|
response = self._invoke(
|
|
174
197
|
self._client.AddCDAQSyncConnection,
|
|
@@ -2181,6 +2204,12 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
2181
2204
|
grpc_types.GetTimingAttributeStringRequest(task=task, attribute_raw=attribute))
|
|
2182
2205
|
return response.value
|
|
2183
2206
|
|
|
2207
|
+
def get_timing_attribute_timestamp(self, task, attribute):
|
|
2208
|
+
response = self._invoke(
|
|
2209
|
+
self._client.GetTimingAttributeTimestamp,
|
|
2210
|
+
grpc_types.GetTimingAttributeTimestampRequest(task=task, attribute_raw=attribute))
|
|
2211
|
+
return convert_timestamp_to_time(response.value)
|
|
2212
|
+
|
|
2184
2213
|
def get_timing_attribute_uint32(self, task, attribute):
|
|
2185
2214
|
response = self._invoke(
|
|
2186
2215
|
self._client.GetTimingAttributeUInt32,
|
|
@@ -3610,7 +3639,13 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3610
3639
|
waveform: AnalogWaveform[numpy.float64],
|
|
3611
3640
|
waveform_attribute_mode: WaveformAttributeMode
|
|
3612
3641
|
) -> int:
|
|
3613
|
-
|
|
3642
|
+
return self.read_analog_waveforms(
|
|
3643
|
+
task_handle,
|
|
3644
|
+
number_of_samples_per_channel,
|
|
3645
|
+
timeout,
|
|
3646
|
+
[waveform],
|
|
3647
|
+
waveform_attribute_mode
|
|
3648
|
+
)
|
|
3614
3649
|
|
|
3615
3650
|
def read_analog_waveforms(
|
|
3616
3651
|
self,
|
|
@@ -3620,7 +3655,30 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3620
3655
|
waveforms: Sequence[AnalogWaveform[numpy.float64]],
|
|
3621
3656
|
waveform_attribute_mode: WaveformAttributeMode
|
|
3622
3657
|
) -> int:
|
|
3623
|
-
|
|
3658
|
+
assert isinstance(task_handle, Session)
|
|
3659
|
+
response = self._invoke(
|
|
3660
|
+
self._client.ReadAnalogWaveforms,
|
|
3661
|
+
grpc_types.ReadAnalogWaveformsRequest(
|
|
3662
|
+
task=task_handle,
|
|
3663
|
+
num_samps_per_chan=number_of_samples_per_channel,
|
|
3664
|
+
timeout=timeout,
|
|
3665
|
+
waveform_attribute_mode_raw=waveform_attribute_mode.value
|
|
3666
|
+
))
|
|
3667
|
+
|
|
3668
|
+
if len(response.waveforms) != len(waveforms):
|
|
3669
|
+
raise ValueError(f"Expected {len(waveforms)} waveforms but received {len(response.waveforms)} from server")
|
|
3670
|
+
|
|
3671
|
+
for i, grpc_waveform in enumerate(response.waveforms):
|
|
3672
|
+
temp_waveform = float64_analog_waveform_from_protobuf(grpc_waveform)
|
|
3673
|
+
waveforms[i].load_data(temp_waveform.scaled_data)
|
|
3674
|
+
|
|
3675
|
+
waveforms[i].scale_mode = temp_waveform.scale_mode
|
|
3676
|
+
waveforms[i].timing = temp_waveform.timing
|
|
3677
|
+
waveforms[i].extended_properties.clear()
|
|
3678
|
+
waveforms[i].extended_properties.update(temp_waveform.extended_properties)
|
|
3679
|
+
|
|
3680
|
+
self._check_for_error_from_response(response.status, samps_per_chan_read=response.samps_per_chan_read)
|
|
3681
|
+
return response.samps_per_chan_read
|
|
3624
3682
|
|
|
3625
3683
|
def read_digital_waveform(
|
|
3626
3684
|
self,
|
|
@@ -3630,7 +3688,15 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3630
3688
|
waveform: DigitalWaveform[Any],
|
|
3631
3689
|
waveform_attribute_mode: WaveformAttributeMode
|
|
3632
3690
|
) -> int:
|
|
3633
|
-
|
|
3691
|
+
return self.read_digital_waveforms(
|
|
3692
|
+
task_handle,
|
|
3693
|
+
1, # channel_count
|
|
3694
|
+
number_of_samples_per_channel,
|
|
3695
|
+
waveform.signal_count, # number_of_signals_per_sample
|
|
3696
|
+
timeout,
|
|
3697
|
+
[waveform],
|
|
3698
|
+
waveform_attribute_mode
|
|
3699
|
+
)
|
|
3634
3700
|
|
|
3635
3701
|
def read_digital_waveforms(
|
|
3636
3702
|
self,
|
|
@@ -3642,7 +3708,32 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3642
3708
|
waveforms: Sequence[DigitalWaveform[Any]],
|
|
3643
3709
|
waveform_attribute_mode: WaveformAttributeMode,
|
|
3644
3710
|
) -> int:
|
|
3645
|
-
|
|
3711
|
+
assert isinstance(task_handle, Session)
|
|
3712
|
+
response = self._invoke(
|
|
3713
|
+
self._client.ReadDigitalWaveforms,
|
|
3714
|
+
grpc_types.ReadDigitalWaveformsRequest(
|
|
3715
|
+
task=task_handle,
|
|
3716
|
+
num_samps_per_chan=number_of_samples_per_channel,
|
|
3717
|
+
timeout=timeout,
|
|
3718
|
+
waveform_attribute_mode_raw=waveform_attribute_mode.value
|
|
3719
|
+
))
|
|
3720
|
+
|
|
3721
|
+
if len(response.waveforms) != len(waveforms):
|
|
3722
|
+
raise ValueError(f"Expected {len(waveforms)} waveforms but received {len(response.waveforms)} from server")
|
|
3723
|
+
|
|
3724
|
+
for i, grpc_waveform in enumerate(response.waveforms):
|
|
3725
|
+
temp_waveform = digital_waveform_from_protobuf(grpc_waveform)
|
|
3726
|
+
data = temp_waveform.data
|
|
3727
|
+
if data.dtype != waveforms[i].dtype:
|
|
3728
|
+
data = data.view(waveforms[i].dtype)
|
|
3729
|
+
waveforms[i].load_data(data)
|
|
3730
|
+
|
|
3731
|
+
waveforms[i].timing = temp_waveform.timing
|
|
3732
|
+
waveforms[i].extended_properties.clear()
|
|
3733
|
+
waveforms[i].extended_properties.update(temp_waveform.extended_properties)
|
|
3734
|
+
|
|
3735
|
+
self._check_for_error_from_response(response.status, samps_per_chan_read=response.samps_per_chan_read)
|
|
3736
|
+
return response.samps_per_chan_read
|
|
3646
3737
|
|
|
3647
3738
|
def read_new_digital_waveforms(
|
|
3648
3739
|
self,
|
|
@@ -3653,7 +3744,20 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3653
3744
|
timeout: float,
|
|
3654
3745
|
waveform_attribute_mode: WaveformAttributeMode,
|
|
3655
3746
|
) -> Sequence[DigitalWaveform[numpy.uint8]]:
|
|
3656
|
-
|
|
3747
|
+
assert isinstance(task_handle, Session)
|
|
3748
|
+
response = self._invoke(
|
|
3749
|
+
self._client.ReadDigitalWaveforms,
|
|
3750
|
+
grpc_types.ReadDigitalWaveformsRequest(
|
|
3751
|
+
task=task_handle,
|
|
3752
|
+
num_samps_per_chan=number_of_samples_per_channel,
|
|
3753
|
+
timeout=timeout,
|
|
3754
|
+
waveform_attribute_mode_raw=waveform_attribute_mode.value
|
|
3755
|
+
))
|
|
3756
|
+
|
|
3757
|
+
waveforms = [digital_waveform_from_protobuf(grpc_waveform) for grpc_waveform in response.waveforms]
|
|
3758
|
+
|
|
3759
|
+
self._check_for_error_from_response(response.status, samps_per_chan_read=response.samps_per_chan_read)
|
|
3760
|
+
return waveforms
|
|
3657
3761
|
|
|
3658
3762
|
def write_analog_waveform(
|
|
3659
3763
|
self,
|
|
@@ -3662,7 +3766,7 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3662
3766
|
auto_start: bool,
|
|
3663
3767
|
timeout: float
|
|
3664
3768
|
) -> int:
|
|
3665
|
-
|
|
3769
|
+
return self.write_analog_waveforms(task_handle, [waveform], auto_start, timeout)
|
|
3666
3770
|
|
|
3667
3771
|
def write_analog_waveforms(
|
|
3668
3772
|
self,
|
|
@@ -3671,7 +3775,22 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3671
3775
|
auto_start: bool,
|
|
3672
3776
|
timeout: float
|
|
3673
3777
|
) -> int:
|
|
3674
|
-
|
|
3778
|
+
assert isinstance(task_handle, Session)
|
|
3779
|
+
num_samps_per_chan = get_num_samps_per_chan(waveforms)
|
|
3780
|
+
|
|
3781
|
+
grpc_waveforms = [float64_analog_waveform_to_protobuf(waveform) for waveform in waveforms]
|
|
3782
|
+
|
|
3783
|
+
response = self._invoke(
|
|
3784
|
+
self._client.WriteAnalogWaveforms,
|
|
3785
|
+
grpc_types.WriteAnalogWaveformsRequest(
|
|
3786
|
+
task=task_handle,
|
|
3787
|
+
auto_start=auto_start,
|
|
3788
|
+
timeout=timeout,
|
|
3789
|
+
waveforms=grpc_waveforms
|
|
3790
|
+
))
|
|
3791
|
+
|
|
3792
|
+
self._check_for_error_from_response(response.status, samps_per_chan_written=response.samps_per_chan_written)
|
|
3793
|
+
return response.samps_per_chan_written
|
|
3675
3794
|
|
|
3676
3795
|
def write_digital_waveform(
|
|
3677
3796
|
self,
|
|
@@ -3680,16 +3799,31 @@ class GrpcStubInterpreter(BaseInterpreter):
|
|
|
3680
3799
|
auto_start: bool,
|
|
3681
3800
|
timeout: float,
|
|
3682
3801
|
) -> int:
|
|
3683
|
-
|
|
3802
|
+
return self.write_digital_waveforms(task_handle, [waveform], auto_start, timeout)
|
|
3684
3803
|
|
|
3685
3804
|
def write_digital_waveforms(
|
|
3686
3805
|
self,
|
|
3687
3806
|
task_handle: object,
|
|
3688
|
-
|
|
3807
|
+
waveforms: Sequence[DigitalWaveform[Any]],
|
|
3689
3808
|
auto_start: bool,
|
|
3690
3809
|
timeout: float,
|
|
3691
3810
|
) -> int:
|
|
3692
|
-
|
|
3811
|
+
assert isinstance(task_handle, Session)
|
|
3812
|
+
num_samps_per_chan = get_num_samps_per_chan(waveforms)
|
|
3813
|
+
|
|
3814
|
+
grpc_waveforms = [digital_waveform_to_protobuf(waveform) for waveform in waveforms]
|
|
3815
|
+
|
|
3816
|
+
response = self._invoke(
|
|
3817
|
+
self._client.WriteDigitalWaveforms,
|
|
3818
|
+
grpc_types.WriteDigitalWaveformsRequest(
|
|
3819
|
+
task=task_handle,
|
|
3820
|
+
auto_start=auto_start,
|
|
3821
|
+
timeout=timeout,
|
|
3822
|
+
waveforms=grpc_waveforms
|
|
3823
|
+
))
|
|
3824
|
+
|
|
3825
|
+
self._check_for_error_from_response(response.status, samps_per_chan_written=response.samps_per_chan_written)
|
|
3826
|
+
return response.samps_per_chan_written
|
|
3693
3827
|
|
|
3694
3828
|
def _assign_numpy_array(numpy_array, grpc_array):
|
|
3695
3829
|
"""
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"Windows": [
|
|
3
3
|
{
|
|
4
|
-
"Version": "25.
|
|
5
|
-
"Release": "
|
|
6
|
-
"Location": "https://download.ni.com/support/nipkg/products/ni-d/ni-daqmx/25.
|
|
4
|
+
"Version": "25.8.0",
|
|
5
|
+
"Release": "2025Q4",
|
|
6
|
+
"Location": "https://download.ni.com/support/nipkg/products/ni-d/ni-daqmx/25.8/online/ni-daqmx_25.8_online.exe",
|
|
7
7
|
"supportedOS": [
|
|
8
8
|
"Windows 11",
|
|
9
9
|
"Windows Server 2022 64-bit",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
],
|
|
16
16
|
"Linux": [
|
|
17
17
|
{
|
|
18
|
-
"Version": "25.
|
|
19
|
-
"Release": "
|
|
18
|
+
"Version": "25.8.0",
|
|
19
|
+
"Release": "2025Q4",
|
|
20
20
|
"_comment": "Location url must be of the format 'https://download.ni.com/support/softlib/MasterRepository/LinuxDrivers<Release>/NILinux<Release>DeviceDrivers.zip'. Any change to the format will require a change in the code.",
|
|
21
|
-
"Location": "https://download.ni.com/support/softlib/MasterRepository/
|
|
21
|
+
"Location": "https://download.ni.com/support/softlib/MasterRepository/LinuxDrivers2025Q4/NILinux2025Q4DeviceDrivers.zip",
|
|
22
22
|
"supportedOS": [
|
|
23
23
|
"ubuntu 20.04",
|
|
24
24
|
"ubuntu 22.04",
|