From d34bbe8192cdbe3e4d1a9f7d9f77e4b8e8b84c6e Mon Sep 17 00:00:00 2001 From: Charity Loh <55676809+charitylxy@users.noreply.github.com> Date: Fri, 19 Jan 2024 01:02:58 +0800 Subject: [PATCH] Add Shunt Cal support in grpc-device (#1033) * update metadata * add generated files * add test cases * fix indent * fix test coverage * Address comments * minor edit * fix test names --- generated/nidaqmx/nidaqmx.proto | 74 ++++++- generated/nidaqmx/nidaqmx_client.cpp | 89 +++++++++ generated/nidaqmx/nidaqmx_client.h | 2 + .../nidaqmx/nidaqmx_compilation_test.cpp | 10 + generated/nidaqmx/nidaqmx_library.cpp | 18 ++ generated/nidaqmx/nidaqmx_library.h | 6 + generated/nidaqmx/nidaqmx_library_interface.h | 2 + generated/nidaqmx/nidaqmx_mock_library.h | 2 + generated/nidaqmx/nidaqmx_service.cpp | 149 ++++++++++++++ generated/nidaqmx/nidaqmx_service.h | 2 + source/codegen/metadata/nidaqmx/enums.py | 51 ++++- source/codegen/metadata/nidaqmx/functions.py | 182 ++++++++++++++++++ .../tests/system/nidaqmx_driver_api_tests.cpp | 101 ++++++++++ 13 files changed, 686 insertions(+), 2 deletions(-) diff --git a/generated/nidaqmx/nidaqmx.proto b/generated/nidaqmx/nidaqmx.proto index 9ca6b7d6c..032d01f0d 100644 --- a/generated/nidaqmx/nidaqmx.proto +++ b/generated/nidaqmx/nidaqmx.proto @@ -258,6 +258,8 @@ service NiDAQmx { rpc GetWriteAttributeUInt64(GetWriteAttributeUInt64Request) returns (GetWriteAttributeUInt64Response); rpc IsTaskDone(IsTaskDoneRequest) returns (IsTaskDoneResponse); rpc LoadTask(LoadTaskRequest) returns (LoadTaskResponse); + rpc PerformBridgeShuntCalEx(PerformBridgeShuntCalExRequest) returns (PerformBridgeShuntCalExResponse); + rpc PerformStrainShuntCalEx(PerformStrainShuntCalExRequest) returns (PerformStrainShuntCalExResponse); rpc ReadAnalogF64(ReadAnalogF64Request) returns (ReadAnalogF64Response); rpc ReadAnalogScalarF64(ReadAnalogScalarF64Request) returns (ReadAnalogScalarF64Response); rpc ReadBinaryI16(ReadBinaryI16Request) returns (ReadBinaryI16Response); @@ -3236,6 +3238,29 @@ enum SaveOptions { SAVE_OPTIONS_ALLOW_INTERACTIVE_DELETION = 4; } +enum ShuntCalSelect { + SHUNT_CAL_SELECT_UNSPECIFIED = 0; + SHUNT_CAL_SELECT_A = 12513; + SHUNT_CAL_SELECT_B = 12514; + SHUNT_CAL_SELECT_A_AND_B = 12515; +} + +enum ShuntCalSource { + SHUNT_CAL_SOURCE_UNSPECIFIED = 0; + SHUNT_CAL_SOURCE_DEFAULT = -1; + SHUNT_CAL_SOURCE_BUILT_IN = 10200; + SHUNT_CAL_SOURCE_USER_PROVIDED = 10167; +} + +enum ShuntElementLocation { + SHUNT_ELEMENT_LOCATION_UNSPECIFIED = 0; + SHUNT_ELEMENT_LOCATION_R1 = 12465; + SHUNT_ELEMENT_LOCATION_R2 = 12466; + SHUNT_ELEMENT_LOCATION_R3 = 12467; + SHUNT_ELEMENT_LOCATION_R4 = 14813; + SHUNT_ELEMENT_LOCATION_NONE = 10230; +} + enum Signal { SIGNAL_UNSPECIFIED = 0; SIGNAL_AI_CONVERT_CLOCK = 12484; @@ -3772,7 +3797,7 @@ enum ChannelInt32AttributeValues { CHANNEL_INT32_SENSOR_POWER_TYPE_BIPOLAR_DC = 16147; CHANNEL_INT32_SHUNT_CAL_SELECT_A = 12513; CHANNEL_INT32_SHUNT_CAL_SELECT_B = 12514; - CHANNEL_INT32_SHUNT_CAL_SELECT_AAND_B = 12515; + CHANNEL_INT32_SHUNT_CAL_SELECT_A_AND_B = 12515; CHANNEL_INT32_SOUND_PRESSURE_UNITS1_PASCALS = 10081; CHANNEL_INT32_SOUND_PRESSURE_UNITS1_FROM_CUSTOM_SCALE = 10065; CHANNEL_INT32_SOURCE_SELECTION_INTERNAL = 10200; @@ -8308,6 +8333,53 @@ message LoadTaskResponse { bool new_session_initialized = 3; } +message PerformBridgeShuntCalExRequest { + nidevice_grpc.Session task = 1; + string channel = 2; + double shunt_resistor_value = 3; + oneof shunt_resistor_location_enum { + ShuntElementLocation shunt_resistor_location = 4; + int32 shunt_resistor_location_raw = 5; + } + oneof shunt_resistor_select_enum { + ShuntCalSelect shunt_resistor_select = 6; + int32 shunt_resistor_select_raw = 7; + } + oneof shunt_resistor_source_enum { + ShuntCalSource shunt_resistor_source = 8; + int32 shunt_resistor_source_raw = 9; + } + double bridge_resistance = 10; + bool skip_unsupported_channels = 11; +} + +message PerformBridgeShuntCalExResponse { + int32 status = 1; +} + +message PerformStrainShuntCalExRequest { + nidevice_grpc.Session task = 1; + string channel = 2; + double shunt_resistor_value = 3; + oneof shunt_resistor_location_enum { + ShuntElementLocation shunt_resistor_location = 4; + int32 shunt_resistor_location_raw = 5; + } + oneof shunt_resistor_select_enum { + ShuntCalSelect shunt_resistor_select = 6; + int32 shunt_resistor_select_raw = 7; + } + oneof shunt_resistor_source_enum { + ShuntCalSource shunt_resistor_source = 8; + int32 shunt_resistor_source_raw = 9; + } + bool skip_unsupported_channels = 10; +} + +message PerformStrainShuntCalExResponse { + int32 status = 1; +} + message ReadAnalogF64Request { nidevice_grpc.Session task = 1; int32 num_samps_per_chan = 2; diff --git a/generated/nidaqmx/nidaqmx_client.cpp b/generated/nidaqmx/nidaqmx_client.cpp index 68972fb0c..f447b182f 100644 --- a/generated/nidaqmx/nidaqmx_client.cpp +++ b/generated/nidaqmx/nidaqmx_client.cpp @@ -7337,6 +7337,95 @@ load_task(const StubPtr& stub, const std::string& session_name, const nidevice_g return response; } +PerformBridgeShuntCalExResponse +perform_bridge_shunt_cal_ex(const StubPtr& stub, const nidevice_grpc::Session& task, const std::string& channel, const double& shunt_resistor_value, const simple_variant& shunt_resistor_location, const simple_variant& shunt_resistor_select, const simple_variant& shunt_resistor_source, const double& bridge_resistance, const bool& skip_unsupported_channels) +{ + ::grpc::ClientContext context; + + auto request = PerformBridgeShuntCalExRequest{}; + request.mutable_task()->CopyFrom(task); + request.set_channel(channel); + request.set_shunt_resistor_value(shunt_resistor_value); + const auto shunt_resistor_location_ptr = shunt_resistor_location.get_if(); + const auto shunt_resistor_location_raw_ptr = shunt_resistor_location.get_if(); + if (shunt_resistor_location_ptr) { + request.set_shunt_resistor_location(*shunt_resistor_location_ptr); + } + else if (shunt_resistor_location_raw_ptr) { + request.set_shunt_resistor_location_raw(*shunt_resistor_location_raw_ptr); + } + const auto shunt_resistor_select_ptr = shunt_resistor_select.get_if(); + const auto shunt_resistor_select_raw_ptr = shunt_resistor_select.get_if(); + if (shunt_resistor_select_ptr) { + request.set_shunt_resistor_select(*shunt_resistor_select_ptr); + } + else if (shunt_resistor_select_raw_ptr) { + request.set_shunt_resistor_select_raw(*shunt_resistor_select_raw_ptr); + } + const auto shunt_resistor_source_ptr = shunt_resistor_source.get_if(); + const auto shunt_resistor_source_raw_ptr = shunt_resistor_source.get_if(); + if (shunt_resistor_source_ptr) { + request.set_shunt_resistor_source(*shunt_resistor_source_ptr); + } + else if (shunt_resistor_source_raw_ptr) { + request.set_shunt_resistor_source_raw(*shunt_resistor_source_raw_ptr); + } + request.set_bridge_resistance(bridge_resistance); + request.set_skip_unsupported_channels(skip_unsupported_channels); + + auto response = PerformBridgeShuntCalExResponse{}; + + raise_if_error( + stub->PerformBridgeShuntCalEx(&context, request, &response), + context); + + return response; +} + +PerformStrainShuntCalExResponse +perform_strain_shunt_cal_ex(const StubPtr& stub, const nidevice_grpc::Session& task, const std::string& channel, const double& shunt_resistor_value, const simple_variant& shunt_resistor_location, const simple_variant& shunt_resistor_select, const simple_variant& shunt_resistor_source, const bool& skip_unsupported_channels) +{ + ::grpc::ClientContext context; + + auto request = PerformStrainShuntCalExRequest{}; + request.mutable_task()->CopyFrom(task); + request.set_channel(channel); + request.set_shunt_resistor_value(shunt_resistor_value); + const auto shunt_resistor_location_ptr = shunt_resistor_location.get_if(); + const auto shunt_resistor_location_raw_ptr = shunt_resistor_location.get_if(); + if (shunt_resistor_location_ptr) { + request.set_shunt_resistor_location(*shunt_resistor_location_ptr); + } + else if (shunt_resistor_location_raw_ptr) { + request.set_shunt_resistor_location_raw(*shunt_resistor_location_raw_ptr); + } + const auto shunt_resistor_select_ptr = shunt_resistor_select.get_if(); + const auto shunt_resistor_select_raw_ptr = shunt_resistor_select.get_if(); + if (shunt_resistor_select_ptr) { + request.set_shunt_resistor_select(*shunt_resistor_select_ptr); + } + else if (shunt_resistor_select_raw_ptr) { + request.set_shunt_resistor_select_raw(*shunt_resistor_select_raw_ptr); + } + const auto shunt_resistor_source_ptr = shunt_resistor_source.get_if(); + const auto shunt_resistor_source_raw_ptr = shunt_resistor_source.get_if(); + if (shunt_resistor_source_ptr) { + request.set_shunt_resistor_source(*shunt_resistor_source_ptr); + } + else if (shunt_resistor_source_raw_ptr) { + request.set_shunt_resistor_source_raw(*shunt_resistor_source_raw_ptr); + } + request.set_skip_unsupported_channels(skip_unsupported_channels); + + auto response = PerformStrainShuntCalExResponse{}; + + raise_if_error( + stub->PerformStrainShuntCalEx(&context, request, &response), + context); + + return response; +} + ReadAnalogF64Response read_analog_f64(const StubPtr& stub, const nidevice_grpc::Session& task, const pb::int32& num_samps_per_chan, const double& timeout, const simple_variant& fill_mode, const pb::uint32& array_size_in_samps) { diff --git a/generated/nidaqmx/nidaqmx_client.h b/generated/nidaqmx/nidaqmx_client.h index 79a71b698..787a3362c 100644 --- a/generated/nidaqmx/nidaqmx_client.h +++ b/generated/nidaqmx/nidaqmx_client.h @@ -263,6 +263,8 @@ GetWriteAttributeUInt32Response get_write_attribute_uint32(const StubPtr& stub, GetWriteAttributeUInt64Response get_write_attribute_uint64(const StubPtr& stub, const nidevice_grpc::Session& task, const simple_variant& attribute); IsTaskDoneResponse is_task_done(const StubPtr& stub, const nidevice_grpc::Session& task); LoadTaskResponse load_task(const StubPtr& stub, const std::string& session_name, const nidevice_grpc::SessionInitializationBehavior& initialization_behavior = nidevice_grpc::SESSION_INITIALIZATION_BEHAVIOR_UNSPECIFIED); +PerformBridgeShuntCalExResponse perform_bridge_shunt_cal_ex(const StubPtr& stub, const nidevice_grpc::Session& task, const std::string& channel, const double& shunt_resistor_value, const simple_variant& shunt_resistor_location, const simple_variant& shunt_resistor_select, const simple_variant& shunt_resistor_source, const double& bridge_resistance, const bool& skip_unsupported_channels); +PerformStrainShuntCalExResponse perform_strain_shunt_cal_ex(const StubPtr& stub, const nidevice_grpc::Session& task, const std::string& channel, const double& shunt_resistor_value, const simple_variant& shunt_resistor_location, const simple_variant& shunt_resistor_select, const simple_variant& shunt_resistor_source, const bool& skip_unsupported_channels); ReadAnalogF64Response read_analog_f64(const StubPtr& stub, const nidevice_grpc::Session& task, const pb::int32& num_samps_per_chan, const double& timeout, const simple_variant& fill_mode, const pb::uint32& array_size_in_samps); ReadAnalogScalarF64Response read_analog_scalar_f64(const StubPtr& stub, const nidevice_grpc::Session& task, const double& timeout); ReadBinaryI16Response read_binary_i16(const StubPtr& stub, const nidevice_grpc::Session& task, const pb::int32& num_samps_per_chan, const double& timeout, const simple_variant& fill_mode, const pb::uint32& array_size_in_samps); diff --git a/generated/nidaqmx/nidaqmx_compilation_test.cpp b/generated/nidaqmx/nidaqmx_compilation_test.cpp index 78c01fe66..1834bcfd7 100644 --- a/generated/nidaqmx/nidaqmx_compilation_test.cpp +++ b/generated/nidaqmx/nidaqmx_compilation_test.cpp @@ -1212,6 +1212,16 @@ int32 LoadTask(const char sessionName[], TaskHandle* task) return DAQmxLoadTask(sessionName, task); } +int32 PerformBridgeShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, float64 bridgeResistance, bool32 skipUnsupportedChannels) +{ + return DAQmxPerformBridgeShuntCalEx(task, channel, shuntResistorValue, shuntResistorLocation, shuntResistorSelect, shuntResistorSource, bridgeResistance, skipUnsupportedChannels); +} + +int32 PerformStrainShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, bool32 skipUnsupportedChannels) +{ + return DAQmxPerformStrainShuntCalEx(task, channel, shuntResistorValue, shuntResistorLocation, shuntResistorSelect, shuntResistorSource, skipUnsupportedChannels); +} + int32 ReadAnalogF64(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) { return DAQmxReadAnalogF64(task, numSampsPerChan, timeout, fillMode, readArray, arraySizeInSamps, sampsPerChanRead, reserved); diff --git a/generated/nidaqmx/nidaqmx_library.cpp b/generated/nidaqmx/nidaqmx_library.cpp index 59bd46350..1a3b17cdd 100644 --- a/generated/nidaqmx/nidaqmx_library.cpp +++ b/generated/nidaqmx/nidaqmx_library.cpp @@ -269,6 +269,8 @@ NiDAQmxLibrary::NiDAQmxLibrary(std::shared_ptr(shared_library_->get_function_pointer("DAQmxGetWriteAttribute")); function_pointers_.IsTaskDone = reinterpret_cast(shared_library_->get_function_pointer("DAQmxIsTaskDone")); function_pointers_.LoadTask = reinterpret_cast(shared_library_->get_function_pointer("DAQmxLoadTask")); + function_pointers_.PerformBridgeShuntCalEx = reinterpret_cast(shared_library_->get_function_pointer("DAQmxPerformBridgeShuntCalEx")); + function_pointers_.PerformStrainShuntCalEx = reinterpret_cast(shared_library_->get_function_pointer("DAQmxPerformStrainShuntCalEx")); function_pointers_.ReadAnalogF64 = reinterpret_cast(shared_library_->get_function_pointer("DAQmxReadAnalogF64")); function_pointers_.ReadAnalogScalarF64 = reinterpret_cast(shared_library_->get_function_pointer("DAQmxReadAnalogScalarF64")); function_pointers_.ReadBinaryI16 = reinterpret_cast(shared_library_->get_function_pointer("DAQmxReadBinaryI16")); @@ -2371,6 +2373,22 @@ int32 NiDAQmxLibrary::LoadTask(const char sessionName[], TaskHandle* task) return function_pointers_.LoadTask(sessionName, task); } +int32 NiDAQmxLibrary::PerformBridgeShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, float64 bridgeResistance, bool32 skipUnsupportedChannels) +{ + if (!function_pointers_.PerformBridgeShuntCalEx) { + throw nidevice_grpc::LibraryLoadException("Could not find DAQmxPerformBridgeShuntCalEx."); + } + return function_pointers_.PerformBridgeShuntCalEx(task, channel, shuntResistorValue, shuntResistorLocation, shuntResistorSelect, shuntResistorSource, bridgeResistance, skipUnsupportedChannels); +} + +int32 NiDAQmxLibrary::PerformStrainShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, bool32 skipUnsupportedChannels) +{ + if (!function_pointers_.PerformStrainShuntCalEx) { + throw nidevice_grpc::LibraryLoadException("Could not find DAQmxPerformStrainShuntCalEx."); + } + return function_pointers_.PerformStrainShuntCalEx(task, channel, shuntResistorValue, shuntResistorLocation, shuntResistorSelect, shuntResistorSource, skipUnsupportedChannels); +} + int32 NiDAQmxLibrary::ReadAnalogF64(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) { if (!function_pointers_.ReadAnalogF64) { diff --git a/generated/nidaqmx/nidaqmx_library.h b/generated/nidaqmx/nidaqmx_library.h index c4c1cd9ee..b83749757 100644 --- a/generated/nidaqmx/nidaqmx_library.h +++ b/generated/nidaqmx/nidaqmx_library.h @@ -263,6 +263,8 @@ class NiDAQmxLibrary : public nidaqmx_grpc::NiDAQmxLibraryInterface { int32 GetWriteAttributeUInt64(TaskHandle task, int32 attribute, uInt64* value) override; int32 IsTaskDone(TaskHandle task, bool32* isTaskDone) override; int32 LoadTask(const char sessionName[], TaskHandle* task) override; + int32 PerformBridgeShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, float64 bridgeResistance, bool32 skipUnsupportedChannels) override; + int32 PerformStrainShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, bool32 skipUnsupportedChannels) override; int32 ReadAnalogF64(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) override; int32 ReadAnalogScalarF64(TaskHandle task, float64 timeout, float64* value, bool32* reserved) override; int32 ReadBinaryI16(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, int16 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) override; @@ -660,6 +662,8 @@ class NiDAQmxLibrary : public nidaqmx_grpc::NiDAQmxLibraryInterface { using GetWriteAttributeUInt64Ptr = decltype(&DAQmxGetWriteAttribute); using IsTaskDonePtr = decltype(&DAQmxIsTaskDone); using LoadTaskPtr = decltype(&DAQmxLoadTask); + using PerformBridgeShuntCalExPtr = decltype(&DAQmxPerformBridgeShuntCalEx); + using PerformStrainShuntCalExPtr = decltype(&DAQmxPerformStrainShuntCalEx); using ReadAnalogF64Ptr = decltype(&DAQmxReadAnalogF64); using ReadAnalogScalarF64Ptr = decltype(&DAQmxReadAnalogScalarF64); using ReadBinaryI16Ptr = decltype(&DAQmxReadBinaryI16); @@ -1057,6 +1061,8 @@ class NiDAQmxLibrary : public nidaqmx_grpc::NiDAQmxLibraryInterface { GetWriteAttributeUInt64Ptr GetWriteAttributeUInt64; IsTaskDonePtr IsTaskDone; LoadTaskPtr LoadTask; + PerformBridgeShuntCalExPtr PerformBridgeShuntCalEx; + PerformStrainShuntCalExPtr PerformStrainShuntCalEx; ReadAnalogF64Ptr ReadAnalogF64; ReadAnalogScalarF64Ptr ReadAnalogScalarF64; ReadBinaryI16Ptr ReadBinaryI16; diff --git a/generated/nidaqmx/nidaqmx_library_interface.h b/generated/nidaqmx/nidaqmx_library_interface.h index aa642c56c..5ef9923de 100644 --- a/generated/nidaqmx/nidaqmx_library_interface.h +++ b/generated/nidaqmx/nidaqmx_library_interface.h @@ -253,6 +253,8 @@ class NiDAQmxLibraryInterface { virtual int32 GetWriteAttributeUInt64(TaskHandle task, int32 attribute, uInt64* value) = 0; virtual int32 IsTaskDone(TaskHandle task, bool32* isTaskDone) = 0; virtual int32 LoadTask(const char sessionName[], TaskHandle* task) = 0; + virtual int32 PerformBridgeShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, float64 bridgeResistance, bool32 skipUnsupportedChannels) = 0; + virtual int32 PerformStrainShuntCalEx(TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, bool32 skipUnsupportedChannels) = 0; virtual int32 ReadAnalogF64(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) = 0; virtual int32 ReadAnalogScalarF64(TaskHandle task, float64 timeout, float64* value, bool32* reserved) = 0; virtual int32 ReadBinaryI16(TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, int16 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved) = 0; diff --git a/generated/nidaqmx/nidaqmx_mock_library.h b/generated/nidaqmx/nidaqmx_mock_library.h index e2a86d0fc..59636d58b 100644 --- a/generated/nidaqmx/nidaqmx_mock_library.h +++ b/generated/nidaqmx/nidaqmx_mock_library.h @@ -255,6 +255,8 @@ class NiDAQmxMockLibrary : public nidaqmx_grpc::NiDAQmxLibraryInterface { MOCK_METHOD(int32, GetWriteAttributeUInt64, (TaskHandle task, int32 attribute, uInt64* value), (override)); MOCK_METHOD(int32, IsTaskDone, (TaskHandle task, bool32* isTaskDone), (override)); MOCK_METHOD(int32, LoadTask, (const char sessionName[], TaskHandle* task), (override)); + MOCK_METHOD(int32, PerformBridgeShuntCalEx, (TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, float64 bridgeResistance, bool32 skipUnsupportedChannels), (override)); + MOCK_METHOD(int32, PerformStrainShuntCalEx, (TaskHandle task, const char channel[], float64 shuntResistorValue, int32 shuntResistorLocation, int32 shuntResistorSelect, int32 shuntResistorSource, bool32 skipUnsupportedChannels), (override)); MOCK_METHOD(int32, ReadAnalogF64, (TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved), (override)); MOCK_METHOD(int32, ReadAnalogScalarF64, (TaskHandle task, float64 timeout, float64* value, bool32* reserved), (override)); MOCK_METHOD(int32, ReadBinaryI16, (TaskHandle task, int32 numSampsPerChan, float64 timeout, int32 fillMode, int16 readArray[], uInt32 arraySizeInSamps, int32* sampsPerChanRead, bool32* reserved), (override)); diff --git a/generated/nidaqmx/nidaqmx_service.cpp b/generated/nidaqmx/nidaqmx_service.cpp index 22114022d..9060bb0b9 100644 --- a/generated/nidaqmx/nidaqmx_service.cpp +++ b/generated/nidaqmx/nidaqmx_service.cpp @@ -12937,6 +12937,155 @@ namespace nidaqmx_grpc { } } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + ::grpc::Status NiDAQmxService::PerformBridgeShuntCalEx(::grpc::ServerContext* context, const PerformBridgeShuntCalExRequest* request, PerformBridgeShuntCalExResponse* response) + { + if (context->IsCancelled()) { + return ::grpc::Status::CANCELLED; + } + try { + auto task_grpc_session = request->task(); + TaskHandle task = session_repository_->access_session(task_grpc_session.name()); + auto channel_mbcs = convert_from_grpc(request->channel()); + auto channel = channel_mbcs.c_str(); + float64 shunt_resistor_value = request->shunt_resistor_value(); + int32 shunt_resistor_location; + switch (request->shunt_resistor_location_enum_case()) { + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorLocationEnumCase::kShuntResistorLocation: { + shunt_resistor_location = static_cast(request->shunt_resistor_location()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorLocationEnumCase::kShuntResistorLocationRaw: { + shunt_resistor_location = static_cast(request->shunt_resistor_location_raw()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorLocationEnumCase::SHUNT_RESISTOR_LOCATION_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_location was not specified or out of range"); + break; + } + } + + int32 shunt_resistor_select; + switch (request->shunt_resistor_select_enum_case()) { + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSelectEnumCase::kShuntResistorSelect: { + shunt_resistor_select = static_cast(request->shunt_resistor_select()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSelectEnumCase::kShuntResistorSelectRaw: { + shunt_resistor_select = static_cast(request->shunt_resistor_select_raw()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSelectEnumCase::SHUNT_RESISTOR_SELECT_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_select was not specified or out of range"); + break; + } + } + + int32 shunt_resistor_source; + switch (request->shunt_resistor_source_enum_case()) { + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSourceEnumCase::kShuntResistorSource: { + shunt_resistor_source = static_cast(request->shunt_resistor_source()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSourceEnumCase::kShuntResistorSourceRaw: { + shunt_resistor_source = static_cast(request->shunt_resistor_source_raw()); + break; + } + case nidaqmx_grpc::PerformBridgeShuntCalExRequest::ShuntResistorSourceEnumCase::SHUNT_RESISTOR_SOURCE_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_source was not specified or out of range"); + break; + } + } + + float64 bridge_resistance = request->bridge_resistance(); + bool32 skip_unsupported_channels = request->skip_unsupported_channels(); + auto status = library_->PerformBridgeShuntCalEx(task, channel, shunt_resistor_value, shunt_resistor_location, shunt_resistor_select, shunt_resistor_source, bridge_resistance, skip_unsupported_channels); + if (!status_ok(status)) { + return ConvertApiErrorStatusForTaskHandle(context, status, task); + } + response->set_status(status); + return ::grpc::Status::OK; + } + catch (nidevice_grpc::NonDriverException& ex) { + return ex.GetStatus(); + } + } + + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + ::grpc::Status NiDAQmxService::PerformStrainShuntCalEx(::grpc::ServerContext* context, const PerformStrainShuntCalExRequest* request, PerformStrainShuntCalExResponse* response) + { + if (context->IsCancelled()) { + return ::grpc::Status::CANCELLED; + } + try { + auto task_grpc_session = request->task(); + TaskHandle task = session_repository_->access_session(task_grpc_session.name()); + auto channel_mbcs = convert_from_grpc(request->channel()); + auto channel = channel_mbcs.c_str(); + float64 shunt_resistor_value = request->shunt_resistor_value(); + int32 shunt_resistor_location; + switch (request->shunt_resistor_location_enum_case()) { + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorLocationEnumCase::kShuntResistorLocation: { + shunt_resistor_location = static_cast(request->shunt_resistor_location()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorLocationEnumCase::kShuntResistorLocationRaw: { + shunt_resistor_location = static_cast(request->shunt_resistor_location_raw()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorLocationEnumCase::SHUNT_RESISTOR_LOCATION_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_location was not specified or out of range"); + break; + } + } + + int32 shunt_resistor_select; + switch (request->shunt_resistor_select_enum_case()) { + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSelectEnumCase::kShuntResistorSelect: { + shunt_resistor_select = static_cast(request->shunt_resistor_select()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSelectEnumCase::kShuntResistorSelectRaw: { + shunt_resistor_select = static_cast(request->shunt_resistor_select_raw()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSelectEnumCase::SHUNT_RESISTOR_SELECT_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_select was not specified or out of range"); + break; + } + } + + int32 shunt_resistor_source; + switch (request->shunt_resistor_source_enum_case()) { + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSourceEnumCase::kShuntResistorSource: { + shunt_resistor_source = static_cast(request->shunt_resistor_source()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSourceEnumCase::kShuntResistorSourceRaw: { + shunt_resistor_source = static_cast(request->shunt_resistor_source_raw()); + break; + } + case nidaqmx_grpc::PerformStrainShuntCalExRequest::ShuntResistorSourceEnumCase::SHUNT_RESISTOR_SOURCE_ENUM_NOT_SET: { + return ::grpc::Status(::grpc::INVALID_ARGUMENT, "The value for shunt_resistor_source was not specified or out of range"); + break; + } + } + + bool32 skip_unsupported_channels = request->skip_unsupported_channels(); + auto status = library_->PerformStrainShuntCalEx(task, channel, shunt_resistor_value, shunt_resistor_location, shunt_resistor_select, shunt_resistor_source, skip_unsupported_channels); + if (!status_ok(status)) { + return ConvertApiErrorStatusForTaskHandle(context, status, task); + } + response->set_status(status); + return ::grpc::Status::OK; + } + catch (nidevice_grpc::NonDriverException& ex) { + return ex.GetStatus(); + } + } + //--------------------------------------------------------------------- //--------------------------------------------------------------------- ::grpc::Status NiDAQmxService::ReadAnalogF64(::grpc::ServerContext* context, const ReadAnalogF64Request* request, ReadAnalogF64Response* response) diff --git a/generated/nidaqmx/nidaqmx_service.h b/generated/nidaqmx/nidaqmx_service.h index 6ed7181ab..50daaa9e9 100644 --- a/generated/nidaqmx/nidaqmx_service.h +++ b/generated/nidaqmx/nidaqmx_service.h @@ -284,6 +284,8 @@ class NiDAQmxService final : public NiDAQmx::WithCallbackMethod_RegisterSignalEv ::grpc::Status GetWriteAttributeUInt64(::grpc::ServerContext* context, const GetWriteAttributeUInt64Request* request, GetWriteAttributeUInt64Response* response) override; ::grpc::Status IsTaskDone(::grpc::ServerContext* context, const IsTaskDoneRequest* request, IsTaskDoneResponse* response) override; ::grpc::Status LoadTask(::grpc::ServerContext* context, const LoadTaskRequest* request, LoadTaskResponse* response) override; + ::grpc::Status PerformBridgeShuntCalEx(::grpc::ServerContext* context, const PerformBridgeShuntCalExRequest* request, PerformBridgeShuntCalExResponse* response) override; + ::grpc::Status PerformStrainShuntCalEx(::grpc::ServerContext* context, const PerformStrainShuntCalExRequest* request, PerformStrainShuntCalExResponse* response) override; ::grpc::Status ReadAnalogF64(::grpc::ServerContext* context, const ReadAnalogF64Request* request, ReadAnalogF64Response* response) override; ::grpc::Status ReadAnalogScalarF64(::grpc::ServerContext* context, const ReadAnalogScalarF64Request* request, ReadAnalogScalarF64Response* response) override; ::grpc::Status ReadBinaryI16(::grpc::ServerContext* context, const ReadBinaryI16Request* request, ReadBinaryI16Response* response) override; diff --git a/source/codegen/metadata/nidaqmx/enums.py b/source/codegen/metadata/nidaqmx/enums.py index 4484a1a9f..8ba43d648 100644 --- a/source/codegen/metadata/nidaqmx/enums.py +++ b/source/codegen/metadata/nidaqmx/enums.py @@ -17129,11 +17129,60 @@ 'documentation': { 'description': 'Switches A and B.' }, - 'name': 'AAND_B', + 'name': 'A_AND_B', 'value': 12515 } ] }, + 'ShuntCalSource': { + 'values': [ + { + 'documentation': { + 'description': 'Default' + }, + 'name': 'DEFAULT', + 'value': -1 + }, + { + 'documentation': { + 'description': 'Built-In' + }, + 'name': 'BUILT_IN', + 'value': 10200 + }, + { + 'documentation': { + 'description': 'User Provided' + }, + 'name': 'USER_PROVIDED', + 'value': 10167 + } + ] + }, + 'ShuntElementLocation': { + 'values': [ + { + 'name': 'R1', + 'value': 12465 + }, + { + 'name': 'R2', + 'value': 12466 + }, + { + 'name': 'R3', + 'value': 12467 + }, + { + 'name': 'R4', + 'value': 14813 + }, + { + 'name': 'NONE', + 'value': 10230 + } + ] + }, 'Signal': { 'values': [ { diff --git a/source/codegen/metadata/nidaqmx/functions.py b/source/codegen/metadata/nidaqmx/functions.py index 436196746..23ead391d 100644 --- a/source/codegen/metadata/nidaqmx/functions.py +++ b/source/codegen/metadata/nidaqmx/functions.py @@ -17179,6 +17179,188 @@ 'python_codegen_method': 'CustomCode', 'returns': 'int32' }, + 'PerformBridgeShuntCalEx': { + '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', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'task', + 'python_data_type': 'TaskHandle', + 'python_description': '', + 'python_type_annotation': 'TaskHandle', + 'type': 'TaskHandle' + }, + { + 'ctypes_data_type': 'ctypes.c_char_p', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'channel', + 'python_data_type': 'str', + 'python_description': '', + 'python_type_annotation': 'str', + 'type': 'const char[]' + }, + { + 'ctypes_data_type': 'ctypes.c_double', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'shuntResistorValue', + 'python_data_type': 'float', + 'python_description': '', + 'python_type_annotation': 'float', + 'type': 'float64' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntElementLocation', + 'is_optional_in_python': False, + 'name': 'shuntResistorLocation', + 'python_data_type': 'ShuntElementLocation', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntElementLocation', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntCalSelect', + 'is_optional_in_python': False, + 'name': 'shuntResistorSelect', + 'python_data_type': 'ShuntCalSelect', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntCalSelect', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntCalSource', + 'is_optional_in_python': False, + 'name': 'shuntResistorSource', + 'python_data_type': 'ShuntCalSource', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntCalSource', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'ctypes.c_double', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'bridgeResistance', + 'python_data_type': 'float', + 'python_description': '', + 'python_type_annotation': 'float', + 'type': 'float64' + }, + { + 'ctypes_data_type': 'c_bool32', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'skipUnsupportedChannels', + 'python_data_type': 'bool', + 'python_description': '', + 'python_type_annotation': 'bool', + 'type': 'bool32' + } + ], + 'python_class_name': 'Task', + 'python_codegen_method': 'CustomCode', + 'returns': 'int32' + }, + 'PerformStrainShuntCalEx': { + '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', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'task', + 'python_data_type': 'TaskHandle', + 'python_description': '', + 'python_type_annotation': 'TaskHandle', + 'type': 'TaskHandle' + }, + { + 'ctypes_data_type': 'ctypes.c_char_p', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'channel', + 'python_data_type': 'str', + 'python_description': '', + 'python_type_annotation': 'str', + 'type': 'const char[]' + }, + { + 'ctypes_data_type': 'ctypes.c_double', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'shuntResistorValue', + 'python_data_type': 'float', + 'python_description': '', + 'python_type_annotation': 'float', + 'type': 'float64' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntElementLocation', + 'is_optional_in_python': False, + 'name': 'shuntResistorLocation', + 'python_data_type': 'ShuntElementLocation', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntElementLocation', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntCalSelect', + 'is_optional_in_python': False, + 'name': 'shuntResistorSelect', + 'python_data_type': 'ShuntCalSelect', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntCalSelect', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'ctypes.c_int', + 'direction': 'in', + 'enum': 'ShuntCalSource', + 'is_optional_in_python': False, + 'name': 'shuntResistorSource', + 'python_data_type': 'ShuntCalSource', + 'python_description': '', + 'python_type_annotation': 'nidaqmx.constants.ShuntCalSource', + 'type': 'int32' + }, + { + 'ctypes_data_type': 'c_bool32', + 'direction': 'in', + 'is_optional_in_python': False, + 'name': 'skipUnsupportedChannels', + 'python_data_type': 'bool', + 'python_description': '', + 'python_type_annotation': 'bool', + 'type': 'bool32' + } + ], + 'python_class_name': 'Task', + 'python_codegen_method': 'CustomCode', + 'returns': 'int32' + }, 'ReadAnalogF64': { 'calling_convention': 'StdCall', 'parameters': [ diff --git a/source/tests/system/nidaqmx_driver_api_tests.cpp b/source/tests/system/nidaqmx_driver_api_tests.cpp index 6f065e80d..26ce8fdd5 100644 --- a/source/tests/system/nidaqmx_driver_api_tests.cpp +++ b/source/tests/system/nidaqmx_driver_api_tests.cpp @@ -46,6 +46,8 @@ constexpr auto DEVICE_DOES_NOT_SUPPORT_CDAQ_SYNC_CONNECTIONS_ERROR = -201450; constexpr auto EVERY_N_SAMPLES_EVENT_NOT_SUPPORTED_FOR_NON_BUFFERED_TASKS = -200848; constexpr auto EVERY_N_SAMPS_TRANSFERRED_FROM_BUFFER_EVENT_NOT_SUPPORTED_BY_DEVICE_ERROR = -200980; constexpr auto CANNOT_UNREGISTER_DAQMX_SOFTWARE_EVENT_WHILE_TASK_IS_RUNNING_ERROR = -200986; +constexpr auto STRAIN_SHUNT_CAL_NOT_SUPPORTED_ERROR = -201203; +constexpr auto BRIDGE_SHUNT_CAL_NOT_SUPPORTED_ERROR = -201204; // Creates a static TResponse instance that can be used as a default/in-line value (because it's not a temporary). template @@ -175,6 +177,46 @@ class NiDAQmxDriverApiTests : public Test { return create_ai_voltage_chan(request, response); } + CreateAIStrainGageChanRequest create_ai_strain_gage_request(double min_val, double max_val, const std::string& custom_scale_name = "") + { + CreateAIStrainGageChanRequest request; + set_request_session_name(request); + request.set_physical_channel("gRPCSystemTestDAQ/ai0"); + request.set_name_to_assign_to_channel("ai0"); + request.set_min_val(min_val); + request.set_max_val(max_val); + if (custom_scale_name.empty()) { + request.set_units(StrainUnits1::STRAIN_UNITS1_STRAIN); + } + else { + request.set_custom_scale_name(custom_scale_name); + request.set_units(StrainUnits1::STRAIN_UNITS1_FROM_CUSTOM_SCALE); + } + request.set_strain_config(StrainGageBridgeType1::STRAIN_GAGE_BRIDGE_TYPE1_FULL_BRIDGE_I); + request.set_initial_bridge_voltage(0.00); + request.set_lead_wire_resistance(0.00); + request.set_voltage_excit_source(ExcitationSource::EXCITATION_SOURCE_EXTERNAL); + request.set_voltage_excit_val(2.50); + request.set_gage_factor(2.00); + request.set_poisson_ratio(0.30); + request.set_nominal_gage_resistance(350.00); + return request; + } + + ::grpc::Status create_ai_strain_gage_chan(const CreateAIStrainGageChanRequest& request, CreateAIStrainGageChanResponse& response = ThrowawayResponse::response()) + { + ::grpc::ClientContext context; + auto status = stub()->CreateAIStrainGageChan(&context, request, &response); + client::raise_if_error(status, context); + return status; + } + + ::grpc::Status create_ai_strain_gage_chan(double min_val, double max_val, CreateAIStrainGageChanResponse& response = ThrowawayResponse::response()) + { + auto request = create_ai_strain_gage_request(min_val, max_val); + return create_ai_strain_gage_chan(request, response); + } + CreateAOVoltageChanRequest create_ao_voltage_chan_request(double min_val, double max_val, const std::string& name = "ao0") { CreateAOVoltageChanRequest request; @@ -887,6 +929,39 @@ class NiDAQmxDriverApiTests : public Test { return status; } + ::grpc::Status perform_bridge_shunt_cal_ex(PerformBridgeShuntCalExResponse & response) + { + ::grpc::ClientContext context; + PerformBridgeShuntCalExRequest request; + set_request_session_name(request); + request.set_channel(""); + request.set_shunt_resistor_value(100000); + request.set_shunt_resistor_location(ShuntElementLocation::SHUNT_ELEMENT_LOCATION_R3); + request.set_shunt_resistor_select(ShuntCalSelect::SHUNT_CAL_SELECT_A); + request.set_shunt_resistor_source(ShuntCalSource::SHUNT_CAL_SOURCE_DEFAULT); + request.set_bridge_resistance(120); + request.set_skip_unsupported_channels(false); + auto status = stub()->PerformBridgeShuntCalEx(&context, request, &response); + client::raise_if_error(status, context); + return status; + } + + ::grpc::Status perform_strain_shunt_cal_ex(PerformStrainShuntCalExResponse& response) + { + ::grpc::ClientContext context; + PerformStrainShuntCalExRequest request; + set_request_session_name(request); + request.set_channel(""); + request.set_shunt_resistor_value(100000); + request.set_shunt_resistor_location(ShuntElementLocation::SHUNT_ELEMENT_LOCATION_R3); + request.set_shunt_resistor_select(ShuntCalSelect::SHUNT_CAL_SELECT_A); + request.set_shunt_resistor_source(ShuntCalSource::SHUNT_CAL_SOURCE_DEFAULT); + request.set_skip_unsupported_channels(false); + auto status = stub()->PerformStrainShuntCalEx(&context, request, &response); + client::raise_if_error(status, context); + return status; + } + ::grpc::Status self_cal(SelfCalResponse& response) { ::grpc::ClientContext context; @@ -2065,6 +2140,32 @@ TEST_F(NiDAQmxDriverApiTests, LoadedVoltageTask_ReadAIData_ReturnsDataInExpected EXPECT_DATA_IN_RANGE(read_response.read_array(), AI_MIN, AI_MAX); } +// AI Voltage Channel doesn't support Bridge Shunt Calibration +TEST_F(NiDAQmxDriverApiTests, UnsupportedChannelType_PerformBridgeShuntCalEx_ReturnsError) +{ + const auto AI_MIN = -5; + const auto AI_MAX = 5; + create_ai_voltage_chan(AI_MIN, AI_MAX); + + EXPECT_THROW_DRIVER_ERROR({ + auto response = PerformBridgeShuntCalExResponse{}; + auto status = perform_bridge_shunt_cal_ex(response); + }, BRIDGE_SHUNT_CAL_NOT_SUPPORTED_ERROR); +} + +// X Series doesn't support Strain Shunt Calibration +TEST_F(NiDAQmxDriverApiTests, UnsupportedDevice_PerformStrainShuntCalEx_ReturnsError) +{ + const auto AI_MIN = -0.001; + const auto AI_MAX = 0.001; + create_ai_strain_gage_chan(AI_MIN, AI_MAX); + + EXPECT_THROW_DRIVER_ERROR({ + auto response = PerformStrainShuntCalExResponse{}; + auto status = perform_strain_shunt_cal_ex(response); + }, STRAIN_SHUNT_CAL_NOT_SUPPORTED_ERROR); +} + TEST_F(NiDAQmxDriverApiTests, SelfCal_Succeeds) { auto response = SelfCalResponse{};