From 985ac5518ab3dab7ed7fa80584861dbd80b4dcd4 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Wed, 31 Jan 2024 14:45:48 +0800 Subject: [PATCH 1/9] Add support for WaitForValidTimestamp to nidaqmx-python --- generated/nidaqmx/_base_interpreter.py | 4 ++++ generated/nidaqmx/_grpc_interpreter.py | 8 ++++++++ generated/nidaqmx/_library_interpreter.py | 17 +++++++++++++++++ src/codegen/metadata/functions.py | 12 +++++++++--- src/codegen/utilities/function_helpers.py | 6 ++++++ src/codegen/utilities/interpreter_helpers.py | 2 +- 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/generated/nidaqmx/_base_interpreter.py b/generated/nidaqmx/_base_interpreter.py index 20f1ceee..cbc4e14b 100644 --- a/generated/nidaqmx/_base_interpreter.py +++ b/generated/nidaqmx/_base_interpreter.py @@ -1661,6 +1661,10 @@ def unregister_signal_event(self, task, signal_id): def unreserve_network_device(self, device_name): raise NotImplementedError + @abc.abstractmethod + def wait_for_valid_timestamp(self, task, timestamp_event, timeout): + raise NotImplementedError + @abc.abstractmethod def wait_until_task_done(self, task, time_to_wait): raise NotImplementedError diff --git a/generated/nidaqmx/_grpc_interpreter.py b/generated/nidaqmx/_grpc_interpreter.py index 937355e5..204f35e7 100644 --- a/generated/nidaqmx/_grpc_interpreter.py +++ b/generated/nidaqmx/_grpc_interpreter.py @@ -3254,6 +3254,14 @@ def unreserve_network_device(self, device_name): self._client.UnreserveNetworkDevice, grpc_types.UnreserveNetworkDeviceRequest(device_name=device_name)) + def wait_for_valid_timestamp(self, task, timestamp_event, timeout): + response = self._invoke( + self._client.WaitForValidTimestamp, + grpc_types.WaitForValidTimestampRequest( + task=task, timestamp_event_raw=timestamp_event, + timeout=timeout)) + return response.timestamp + def wait_until_task_done(self, task, time_to_wait): response = self._invoke( self._client.WaitUntilTaskDone, diff --git a/generated/nidaqmx/_library_interpreter.py b/generated/nidaqmx/_library_interpreter.py index 6b5b6259..6831cd68 100644 --- a/generated/nidaqmx/_library_interpreter.py +++ b/generated/nidaqmx/_library_interpreter.py @@ -5636,6 +5636,23 @@ def unreserve_network_device(self, device_name): device_name) self.check_for_error(error_code) + def wait_for_valid_timestamp(self, task, timestamp_event, timeout): + timestamp = _lib_time.AbsoluteTime() + + cfunc = lib_importer.windll.DAQmxWaitForValidTimestamp + if cfunc.argtypes is None: + with cfunc.arglock: + if cfunc.argtypes is None: + cfunc.argtypes = [ + lib_importer.task_handle, ctypes.c_int32, + ctypes.c_double, + ctypes.POINTER(_lib_time.AbsoluteTime)] + + error_code = cfunc( + task, timestamp_event, timeout, ctypes.byref(timestamp)) + self.check_for_error(error_code) + return timestamp.value + def wait_until_task_done(self, task, time_to_wait): cfunc = lib_importer.windll.DAQmxWaitUntilTaskDone if cfunc.argtypes is None: diff --git a/src/codegen/metadata/functions.py b/src/codegen/metadata/functions.py index 80f5d13a..c9b5fc25 100644 --- a/src/codegen/metadata/functions.py +++ b/src/codegen/metadata/functions.py @@ -23606,6 +23606,11 @@ }, 'WaitForValidTimestamp': { 'calling_convention': 'StdCall', + 'handle_parameter': { + 'ctypes_data_type': 'lib_importer.task_handle', + 'cvi_name': 'taskHandle', + 'python_accessor': 'self._handle' + }, 'parameters': [ { 'ctypes_data_type': 'ctypes.TaskHandle', @@ -23644,13 +23649,14 @@ 'direction': 'out', 'is_optional_in_python': False, 'name': 'timestamp', - 'python_data_type': 'DateTime', + 'python_data_type': 'datetime', 'python_description': 'Specifies the timestamp type to wait on.', - 'python_type_annotation': 'nidaqmx.constants.DateTime', + 'python_type_annotation': 'datetime', 'type': 'CVIAbsoluteTime' } ], - 'python_codegen_method': 'no', + 'python_class_name': 'Task', + 'python_codegen_method': 'CustomCode', 'python_description': 'DAQmx Wait for Valid Timestamp', 'returns': 'int32' }, diff --git a/src/codegen/utilities/function_helpers.py b/src/codegen/utilities/function_helpers.py index d75462d3..609068e6 100644 --- a/src/codegen/utilities/function_helpers.py +++ b/src/codegen/utilities/function_helpers.py @@ -203,11 +203,17 @@ def to_param_argtype(parameter): # argtype to convert from unicode to bytes. if parameter.ctypes_data_type == "ctypes.c_char_p": return "ctypes_byte_str" + elif parameter.python_data_type == "datetime": + return "_lib_time.AbsoluteTime" + elif parameter.python_data_type == "timestampEvent": + return "ctypes.c_int32" else: return parameter.ctypes_data_type or parameter.python_data_type else: if parameter.ctypes_data_type == "ctypes.c_char_p": return parameter.ctypes_data_type + elif parameter.python_data_type == "datetime": + return "ctypes.POINTER(_lib_time.AbsoluteTime)" else: return f"ctypes.POINTER({parameter.ctypes_data_type})" diff --git a/src/codegen/utilities/interpreter_helpers.py b/src/codegen/utilities/interpreter_helpers.py index c64bb92e..90d15db5 100644 --- a/src/codegen/utilities/interpreter_helpers.py +++ b/src/codegen/utilities/interpreter_helpers.py @@ -70,7 +70,7 @@ "SetSyncPulseTimeWhen", "SetTimingAttributeExTimestamp", "SetTimingAttributeTimestamp", - "WaitForValidTimestamp", + "SetTrigAttributeTimestamp", # Deprecated, not working "GetAnalogPowerUpStates", ] From 7472d14639c7dc966ea7f641513c02344cc8c1ee Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Thu, 8 Feb 2024 17:40:10 +0800 Subject: [PATCH 2/9] Fix rebase --- src/codegen/utilities/function_helpers.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/codegen/utilities/function_helpers.py b/src/codegen/utilities/function_helpers.py index 609068e6..8613717e 100644 --- a/src/codegen/utilities/function_helpers.py +++ b/src/codegen/utilities/function_helpers.py @@ -203,8 +203,6 @@ def to_param_argtype(parameter): # argtype to convert from unicode to bytes. if parameter.ctypes_data_type == "ctypes.c_char_p": return "ctypes_byte_str" - elif parameter.python_data_type == "datetime": - return "_lib_time.AbsoluteTime" elif parameter.python_data_type == "timestampEvent": return "ctypes.c_int32" else: @@ -212,8 +210,6 @@ def to_param_argtype(parameter): else: if parameter.ctypes_data_type == "ctypes.c_char_p": return parameter.ctypes_data_type - elif parameter.python_data_type == "datetime": - return "ctypes.POINTER(_lib_time.AbsoluteTime)" else: return f"ctypes.POINTER({parameter.ctypes_data_type})" From 5fef972196c09f5d66937dd592295e50ba7fd544 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Thu, 8 Feb 2024 17:41:30 +0800 Subject: [PATCH 3/9] Fix bad rebase --- src/codegen/utilities/interpreter_helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/codegen/utilities/interpreter_helpers.py b/src/codegen/utilities/interpreter_helpers.py index 90d15db5..b037f6c5 100644 --- a/src/codegen/utilities/interpreter_helpers.py +++ b/src/codegen/utilities/interpreter_helpers.py @@ -70,7 +70,6 @@ "SetSyncPulseTimeWhen", "SetTimingAttributeExTimestamp", "SetTimingAttributeTimestamp", - "SetTrigAttributeTimestamp", # Deprecated, not working "GetAnalogPowerUpStates", ] From 9a9cf265d5ebc987c3d4eb69a00d15e4d7e625de Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Fri, 16 Feb 2024 18:31:52 +0800 Subject: [PATCH 4/9] Address comments --- generated/nidaqmx/_library_interpreter.py | 9 ++++----- src/codegen/utilities/function_helpers.py | 5 ++++- src/codegen/utilities/interpreter_helpers.py | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/generated/nidaqmx/_library_interpreter.py b/generated/nidaqmx/_library_interpreter.py index 6831cd68..2a8286cd 100644 --- a/generated/nidaqmx/_library_interpreter.py +++ b/generated/nidaqmx/_library_interpreter.py @@ -3684,7 +3684,7 @@ def get_trig_attribute_timestamp(self, task, attribute): error_code = cfunc( task, attribute, ctypes.byref(value)) self.check_for_error(error_code) - return value + return value.to_datetime() def get_trig_attribute_uint32(self, task, attribute): value = ctypes.c_uint32() @@ -5637,7 +5637,7 @@ def unreserve_network_device(self, device_name): self.check_for_error(error_code) def wait_for_valid_timestamp(self, task, timestamp_event, timeout): - timestamp = _lib_time.AbsoluteTime() + timestamp = AbsoluteTime() cfunc = lib_importer.windll.DAQmxWaitForValidTimestamp if cfunc.argtypes is None: @@ -5645,13 +5645,12 @@ def wait_for_valid_timestamp(self, task, timestamp_event, timeout): if cfunc.argtypes is None: cfunc.argtypes = [ lib_importer.task_handle, ctypes.c_int32, - ctypes.c_double, - ctypes.POINTER(_lib_time.AbsoluteTime)] + ctypes.c_double, ctypes.POINTER(AbsoluteTime)] error_code = cfunc( task, timestamp_event, timeout, ctypes.byref(timestamp)) self.check_for_error(error_code) - return timestamp.value + return timestamp.to_datetime() def wait_until_task_done(self, task, time_to_wait): cfunc = lib_importer.windll.DAQmxWaitUntilTaskDone diff --git a/src/codegen/utilities/function_helpers.py b/src/codegen/utilities/function_helpers.py index 8613717e..e059a1db 100644 --- a/src/codegen/utilities/function_helpers.py +++ b/src/codegen/utilities/function_helpers.py @@ -197,7 +197,10 @@ def to_param_argtype(parameter): if parameter.ctypes_data_type == "ctypes.TaskHandle": return "lib_importer.task_handle" elif parameter.python_data_type == "datetime": - return "AbsoluteTime" + if parameter.direction == "in": + return "AbsoluteTime" + else: + return f"ctypes.POINTER(AbsoluteTime)" elif parameter.direction == "in": # If is string input parameter, use separate custom # argtype to convert from unicode to bytes. diff --git a/src/codegen/utilities/interpreter_helpers.py b/src/codegen/utilities/interpreter_helpers.py index b037f6c5..55b9c308 100644 --- a/src/codegen/utilities/interpreter_helpers.py +++ b/src/codegen/utilities/interpreter_helpers.py @@ -446,8 +446,10 @@ def get_return_values(func): return_values.append(param.parameter_name) else: return_values.append(f"{param.parameter_name}.tolist()") - elif param.type == "TaskHandle" or param.type == "CVIAbsoluteTime": + elif param.type == "TaskHandle": return_values.append(param.parameter_name) + elif param.type == "CVIAbsoluteTime": + return_values.append(f"{param.parameter_name}.to_datetime()") else: return_values.append(f"{param.parameter_name}.value") if func.is_init_method: From f4e0d1cc2cd2fa3cf10d87dee8826dc30d42bbf1 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Fri, 16 Feb 2024 18:35:08 +0800 Subject: [PATCH 5/9] Address comments 2 --- generated/nidaqmx/_grpc_interpreter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generated/nidaqmx/_grpc_interpreter.py b/generated/nidaqmx/_grpc_interpreter.py index 204f35e7..6c9ecfac 100644 --- a/generated/nidaqmx/_grpc_interpreter.py +++ b/generated/nidaqmx/_grpc_interpreter.py @@ -3260,7 +3260,7 @@ def wait_for_valid_timestamp(self, task, timestamp_event, timeout): grpc_types.WaitForValidTimestampRequest( task=task, timestamp_event_raw=timestamp_event, timeout=timeout)) - return response.timestamp + return convert_timestamp_to_time(response.timestamp) def wait_until_task_done(self, task, time_to_wait): response = self._invoke( From ddb6dc1b81f5dfcfc323f905c089a7cd9ff9f7b4 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Mon, 19 Feb 2024 10:24:21 +0800 Subject: [PATCH 6/9] Make it task based --- generated/nidaqmx/task.py | 18 ++++++++++++++++++ src/handwritten/task.py | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/generated/nidaqmx/task.py b/generated/nidaqmx/task.py index 4534e387..48dca10b 100644 --- a/generated/nidaqmx/task.py +++ b/generated/nidaqmx/task.py @@ -1019,6 +1019,24 @@ def stop(self): """ self._interpreter.stop_task(self._handle) + def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): + """ + Wait until the specified timestamp has a value. + + Use this VI to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. + + Args: + timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. + timeout (Optional[float]): Specifies the maximum amount of time in + seconds to wait for the measurement or generation to complete. + This method returns an error if the time elapses. The + default is 10. If you set timeout (sec) to + nidaqmx.WAIT_INFINITELY, the method waits indefinitely. If you + set timeout (sec) to 0, the method checks once and returns + an error if the measurement or generation is not done. + """ + self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event, timeout) + def wait_until_done(self, timeout=10.0): """ Waits for the measurement or generation to complete. diff --git a/src/handwritten/task.py b/src/handwritten/task.py index 4534e387..48dca10b 100644 --- a/src/handwritten/task.py +++ b/src/handwritten/task.py @@ -1019,6 +1019,24 @@ def stop(self): """ self._interpreter.stop_task(self._handle) + def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): + """ + Wait until the specified timestamp has a value. + + Use this VI to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. + + Args: + timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. + timeout (Optional[float]): Specifies the maximum amount of time in + seconds to wait for the measurement or generation to complete. + This method returns an error if the time elapses. The + default is 10. If you set timeout (sec) to + nidaqmx.WAIT_INFINITELY, the method waits indefinitely. If you + set timeout (sec) to 0, the method checks once and returns + an error if the measurement or generation is not done. + """ + self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event, timeout) + def wait_until_done(self, timeout=10.0): """ Waits for the measurement or generation to complete. From 0ae92d59e34dabd1a83d04fba7bab4fd1f370516 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 <74756143+DeborahOoi96@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:03:04 +0800 Subject: [PATCH 7/9] Update src/handwritten/task.py Co-authored-by: Brad Keryan --- src/handwritten/task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handwritten/task.py b/src/handwritten/task.py index 48dca10b..a66342bb 100644 --- a/src/handwritten/task.py +++ b/src/handwritten/task.py @@ -1023,7 +1023,7 @@ def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): """ Wait until the specified timestamp has a value. - Use this VI to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. + Use this method to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. Args: timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. From 238134c993a622d3ae254b02b57a047a799f244b Mon Sep 17 00:00:00 2001 From: DeborahOoi96 <74756143+DeborahOoi96@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:03:44 +0800 Subject: [PATCH 8/9] Update src/handwritten/task.py Co-authored-by: Brad Keryan --- src/handwritten/task.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/handwritten/task.py b/src/handwritten/task.py index a66342bb..d8ab1866 100644 --- a/src/handwritten/task.py +++ b/src/handwritten/task.py @@ -1028,12 +1028,10 @@ def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): Args: timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. timeout (Optional[float]): Specifies the maximum amount of time in - seconds to wait for the measurement or generation to complete. + seconds to wait for a valid timestamp. This method returns an error if the time elapses. The default is 10. If you set timeout (sec) to - nidaqmx.WAIT_INFINITELY, the method waits indefinitely. If you - set timeout (sec) to 0, the method checks once and returns - an error if the measurement or generation is not done. + nidaqmx.WAIT_INFINITELY, the method waits indefinitely. """ self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event, timeout) From d23dfbf9732bd93d2d4e3056a0ca1def7aec2df0 Mon Sep 17 00:00:00 2001 From: DeborahOoi96 Date: Tue, 20 Feb 2024 19:08:02 +0800 Subject: [PATCH 9/9] Address comments --- generated/nidaqmx/task.py | 12 +++++------- src/handwritten/task.py | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/generated/nidaqmx/task.py b/generated/nidaqmx/task.py index 48dca10b..fac23da8 100644 --- a/generated/nidaqmx/task.py +++ b/generated/nidaqmx/task.py @@ -1023,19 +1023,17 @@ def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): """ Wait until the specified timestamp has a value. - Use this VI to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. + Use this method to ensure the timestamp has a valid value to prevent an error when querying a timestamp value. Args: timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. - timeout (Optional[float]): Specifies the maximum amount of time in - seconds to wait for the measurement or generation to complete. + timeout (float): Specifies the maximum amount of time in + seconds to wait for a valid timestamp. This method returns an error if the time elapses. The default is 10. If you set timeout (sec) to - nidaqmx.WAIT_INFINITELY, the method waits indefinitely. If you - set timeout (sec) to 0, the method checks once and returns - an error if the measurement or generation is not done. + nidaqmx.WAIT_INFINITELY, the method waits indefinitely. """ - self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event, timeout) + self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event.value, timeout) def wait_until_done(self, timeout=10.0): """ diff --git a/src/handwritten/task.py b/src/handwritten/task.py index d8ab1866..fac23da8 100644 --- a/src/handwritten/task.py +++ b/src/handwritten/task.py @@ -1027,13 +1027,13 @@ def wait_for_valid_timestamp(self, timestamp_event, timeout=10.0): Args: timestamp_event(nidaqmx.constants.TimestampEvent): Specifies the timestamp type to wait on. - timeout (Optional[float]): Specifies the maximum amount of time in + timeout (float): Specifies the maximum amount of time in seconds to wait for a valid timestamp. This method returns an error if the time elapses. The default is 10. If you set timeout (sec) to nidaqmx.WAIT_INFINITELY, the method waits indefinitely. """ - self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event, timeout) + self._interpreter.wait_for_valid_timestamp(self._handle, timestamp_event.value, timeout) def wait_until_done(self, timeout=10.0): """