From 03d7e685c46136fc33db02ad1bfbd1661cceff4e Mon Sep 17 00:00:00 2001 From: Zach Hindes Date: Wed, 31 Jan 2024 16:54:51 -0600 Subject: [PATCH 1/5] first pass ai --- .../channels/test_ai_channels.py | 240 ++++++++++++++++++ tests/conftest.py | 51 ++++ tests/max_config/nidaqmxMaxConfig.ini | 135 ++++++---- 3 files changed, 374 insertions(+), 52 deletions(-) create mode 100644 tests/component/_task_modules/channels/test_ai_channels.py diff --git a/tests/component/_task_modules/channels/test_ai_channels.py b/tests/component/_task_modules/channels/test_ai_channels.py new file mode 100644 index 00000000..fcbe55e9 --- /dev/null +++ b/tests/component/_task_modules/channels/test_ai_channels.py @@ -0,0 +1,240 @@ +import pytest + +from nidaqmx import Task +from nidaqmx._task_modules.channels.ai_channel import AIChannel +from nidaqmx.constants import ( + BridgeConfiguration, + ExcitationSource, + StrainGageRosetteType, + StrainGageRosetteMeasurementType, + TerminalConfiguration, + UsageTypeAI, + VoltageUnits, +) + +def test___ai_channel_collection___add_ai_voltage_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_voltage_chan( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE + +@pytest.mark.parametrize("desired_term_config, expected_term_cfg", + [(TerminalConfiguration.DEFAULT, TerminalConfiguration.DIFF), + (TerminalConfiguration.DIFF, TerminalConfiguration.DIFF), + (TerminalConfiguration.RSE, TerminalConfiguration.RSE),] +) +def test___ai_channel_collection___add_ai_voltage_chan___sets_term_cfg(task, sim_x_series_device, desired_term_config, expected_term_cfg): + chan = task.ai_channels.add_ai_voltage_chan( + sim_x_series_device.ai_physical_chans[0].name, + terminal_config=desired_term_config) + assert chan.ai_term_cfg == expected_term_cfg + +def test___ai_channel_collection___add_ai_voltage_chan___sets_min_max(task, sim_x_series_device): + # ranges are more varied per device, but +/- 10V is consistent and different from the default + chan = task.ai_channels.add_ai_voltage_chan( + sim_x_series_device.ai_physical_chans[0].name, + min_val=-10.0, max_val=10.0) + assert chan.ai_max == 10 + assert chan.ai_min == -10 + +@pytest.mark.parametrize("units, custom_scale_name", + [(VoltageUnits.VOLTS, ""), + (VoltageUnits.FROM_CUSTOM_SCALE, "no_scaling_scale")] +) +def test___ai_channel_collection___add_ai_voltage_chan___sets_units(task, sim_x_series_device, units, custom_scale_name): + chan = task.ai_channels.add_ai_voltage_chan( + sim_x_series_device.ai_physical_chans[0].name, + units=units, custom_scale_name=custom_scale_name) + assert chan.ai_voltage_units == units + assert chan.ai_custom_scale.name == custom_scale_name + +# Note: From here on out, we do not test ranges or custom scales. Scaling from native device +# ranges to sensor units can be complex, and, similarly, creating a custom scale for each scenario +# is an untenable matrix. Given that the underlying Python implementation is code-generated and the +# underlying C API implementation is well unit-tested, this is defensible. + +def test___ai_channel_collection___add_ai_accel_4_wire_dc_voltage_chan___sets_meas_type(task, sim_charge_device): + chan = task.ai_channels.add_ai_accel_4_wire_dc_voltage_chan( + sim_charge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_4_WIRE_DC_VOLTAGE + +def test___ai_channel_collection___add_ai_accel_chan___sets_meas_type(task, sim_dsa_device): + chan = task.ai_channels.add_ai_accel_chan( + sim_dsa_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_ACCELEROMETER_CURRENT_INPUT + +def test___ai_channel_collection___add_ai_accel_charge_chan___sets_meas_type(task, sim_charge_device): + chan = task.ai_channels.add_ai_accel_charge_chan( + sim_charge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_CHARGE + +def test___ai_channel_collection___add_ai_bridge_chan___sets_meas_type(task, sim_bridge_device): + chan = task.ai_channels.add_ai_bridge_chan( + sim_bridge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.BRIDGE + +def test___ai_channel_collection___add_ai_charge_chan___sets_meas_type(task, sim_charge_device): + chan = task.ai_channels.add_ai_charge_chan( + sim_charge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.CHARGE + +def test___ai_channel_collection___add_ai_current_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_current_chan( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.CURRENT + +def test___ai_channel_collection___add_ai_current_rms_chan___sets_meas_type(task, sim_dmm_device): + chan = task.ai_channels.add_ai_current_rms_chan( + f"{sim_dmm_device.name}/dmm", + min_val=0.0, max_val=1.0) + assert chan.ai_meas_type == UsageTypeAI.CURRENT_ACRMS + +def test___ai_channel_collection___add_ai_force_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): + # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_force_bridge_polynomial_chan( + sim_bridge_device.ai_physical_chans[0].name, + forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE + +def test___ai_channel_collection___add_ai_force_bridge_table_chan___sets_meas_type(task, sim_bridge_device): + # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_force_bridge_table_chan( + sim_bridge_device.ai_physical_chans[0].name, + electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE + +def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + chan = task.ai_channels.add_ai_force_bridge_two_point_lin_chan( + sim_bridge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE + +def test___ai_channel_collection___add_ai_force_iepe_chan___sets_meas_type(task, sim_dsa_device): + chan = task.ai_channels.add_ai_force_iepe_chan( + sim_dsa_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.FORCE_IEPE_SENSOR + +# No active DAQmx devices support add_ai_freq_voltage_chan + +def test___ai_channel_collection___add_ai_microphone_chan___sets_meas_type(task, sim_dsa_device): + chan = task.ai_channels.add_ai_microphone_chan( + sim_dsa_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.SOUND_PRESSURE_MICROPHONE + +def test___ai_channel_collection___add_ai_pos_eddy_curr_prox_probe_chan___sets_meas_type(task, sim_dsa_device): + chan = task.ai_channels.add_ai_pos_eddy_curr_prox_probe_chan( + sim_dsa_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.POSITION_EDDY_CURRENT_PROX_PROBE + +def test___ai_channel_collection___add_ai_pos_lvdt_chan___sets_meas_type(task, sim_position_device): + chan = task.ai_channels.add_ai_pos_lvdt_chan( + sim_position_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.POSITION_LINEAR_LVDT + +def test___ai_channel_collection___add_ai_pos_rvdt_chan___sets_meas_type(task, sim_position_device): + chan = task.ai_channels.add_ai_pos_rvdt_chan( + sim_position_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.POSITION_ANGULAR_RVDT + +def test___ai_channel_collection___add_ai_power_chan___sets_meas_type(task, sim_ts_power_device): + chan = task.ai_channels.add_ai_power_chan( + f"{sim_ts_power_device.name}/power", + voltage_setpoint=0.0, current_setpoint=30e-3, output_enable=False) + assert chan.ai_meas_type == UsageTypeAI.POWER + +def test___ai_channel_collection___add_ai_pressure_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): + # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_pressure_bridge_polynomial_chan( + sim_bridge_device.ai_physical_chans[0].name, + forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE + +def test___ai_channel_collection___add_ai_pressure_bridge_table_chan___sets_meas_type(task, sim_bridge_device): + # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_pressure_bridge_table_chan( + sim_bridge_device.ai_physical_chans[0].name, + electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE + +def test___ai_channel_collection___add_ai_pressure_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + chan = task.ai_channels.add_ai_pressure_bridge_two_point_lin_chan( + sim_bridge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE + +def test___ai_channel_collection___add_ai_resistance_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_resistance_chan( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.RESISTANCE + +def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_meas_type(task, sim_bridge_device): + # TODO: rosette_meas_types input expects an array of ints, but it should be enums + task.ai_channels.add_ai_rosette_strain_gage_chan( + ",".join(sim_bridge_device.ai_physical_chans.channel_names[0:2]), + StrainGageRosetteType.TEE, 0.0, + [StrainGageRosetteMeasurementType.PRINCIPAL_STRAIN_1.value]) + chan = task.ai_channels["rosette0_principalStrain1"] + assert chan.ai_meas_type == UsageTypeAI.ROSETTE_STRAIN_GAGE + +def test___ai_channel_collection___add_ai_rtd_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_rtd_chan( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_RTD + +def test___ai_channel_collection___add_ai_strain_gage_chan___sets_meas_type(task, sim_bridge_device): + chan = task.ai_channels.add_ai_strain_gage_chan( + sim_bridge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.STRAIN_STRAIN_GAGE + +def test___ai_channel_collection___add_ai_temp_built_in_sensor_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_temp_built_in_sensor_chan( + f"{sim_x_series_device.name}/_boardTempSensor_vs_aignd") + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_BUILT_IN_SENSOR + +def test___ai_channel_collection___add_ai_thrmcpl_chan___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_thrmcpl_chan( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMOCOUPLE + +def test___ai_channel_collection___add_ai_thrmstr_chan_iex___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_thrmstr_chan_iex( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR + +def test___ai_channel_collection___add_ai_thrmstr_chan_vex___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_thrmstr_chan_vex( + sim_x_series_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR + +def test___ai_channel_collection___add_ai_torque_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): + # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_torque_bridge_polynomial_chan( + sim_bridge_device.ai_physical_chans[0].name, + forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE + +def test___ai_channel_collection___add_ai_torque_bridge_table_chan___sets_meas_type(task, sim_bridge_device): + # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + chan = task.ai_channels.add_ai_torque_bridge_table_chan( + sim_bridge_device.ai_physical_chans[0].name, + electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE + +def test___ai_channel_collection___add_ai_torque_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + chan = task.ai_channels.add_ai_torque_bridge_two_point_lin_chan( + sim_bridge_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE + +def test___ai_channel_collection___add_ai_velocity_iepe_chan___sets_meas_type(task, sim_dsa_device): + chan = task.ai_channels.add_ai_velocity_iepe_chan( + sim_dsa_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.VELOCITY_IEPE_SENSOR + +def test___ai_channel_collection___add_ai_voltage_chan_with_excit___sets_meas_type(task, sim_x_series_device): + chan = task.ai_channels.add_ai_voltage_chan_with_excit( + sim_x_series_device.ai_physical_chans[0].name, + voltage_excit_source=ExcitationSource.EXTERNAL, voltage_excit_val=3.3) + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_CUSTOM_WITH_EXCITATION + +def test___ai_channel_collection___add_ai_voltage_rms_chan___sets_meas_type(task, sim_dmm_device): + chan = task.ai_channels.add_ai_voltage_rms_chan( + f"{sim_dmm_device.name}/dmm", + min_val=0.0, max_val=1.0) + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_ACRMS diff --git a/tests/conftest.py b/tests/conftest.py index 6643fb44..eb53bfdd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -113,6 +113,27 @@ def _x_series_device(device_type, system): return None +def _device_by_name(product_type, device_type, system): + for device in system.devices: + device_type_match = ( + device_type == DeviceType.ANY + or (device_type == DeviceType.REAL and not device.is_simulated) + or (device_type == DeviceType.SIMULATED and device.is_simulated) + ) + if ( + device_type_match + and device.product_type == product_type + ): + return device + + pytest.skip( + f"Could not detect a {product_type} device that meets the requirements to be of type " + f"{device_type}. Cannot proceed to run tests. Import the NI MAX configuration file located " + "at nidaqmx\\tests\\max_config\\nidaqmxMaxConfig.ini to create these devices." + ) + return None + + @pytest.fixture(scope="function") def any_x_series_device(system): """Gets any x series device information.""" @@ -211,6 +232,36 @@ def sim_ts_power_devices(sim_ts_chassis): return None +@pytest.fixture(scope="function") +def sim_charge_device(system): + """Gets a simulated 4480.""" + return _device_by_name("PXIe-4480", DeviceType.SIMULATED, system) + + +@pytest.fixture(scope="function") +def sim_dsa_device(system): + """Gets a simulated 4466.""" + return _device_by_name("PXIe-4466", DeviceType.SIMULATED, system) + + +@pytest.fixture(scope="function") +def sim_dmm_device(system): + """Gets a simulated myDAQ.""" + return _device_by_name("NI myDAQ", DeviceType.SIMULATED, system) + + +@pytest.fixture(scope="function") +def sim_bridge_device(system): + """Gets a simulated 4431.""" + return _device_by_name("PXIe-4331", DeviceType.SIMULATED, system) + + +@pytest.fixture(scope="function") +def sim_position_device(system): + """Gets a simulated 4340.""" + return _device_by_name("PXIe-4340", DeviceType.SIMULATED, system) + + @pytest.fixture(scope="function") def multi_threading_test_devices(system): """Gets multi threading test devices information.""" diff --git a/tests/max_config/nidaqmxMaxConfig.ini b/tests/max_config/nidaqmxMaxConfig.ini index 825a4e92..61c67958 100644 --- a/tests/max_config/nidaqmxMaxConfig.ini +++ b/tests/max_config/nidaqmxMaxConfig.ini @@ -2,6 +2,28 @@ MajorVersion = 21 MinorVersion = 8 +[DAQmxChannel VoltageTesterChannel] +AI.MeasType = Voltage +AI.Voltage.Units = Volts +AI.TermCfg = Differential +AI.Max = 10 +AI.Min = -10 +ChanType = Analog Input +PhysicalChanName = tsVoltageTester1/ai0 +Descr = +Author = Test Author + +[DAQmxChannel VoltageTesterChannel2] +AI.MeasType = Voltage +AI.Voltage.Units = Volts +AI.TermCfg = Differential +AI.Max = 5 +AI.Min = -5 +ChanType = Analog Input +PhysicalChanName = tsVoltageTester1/ai1 +Descr = Another channel +Author = Another Test Author + [DAQmxChannel AOTesterTask/VoltageOut_0] AO.OutputType = Voltage AO.Voltage.Units = Volts @@ -29,40 +51,6 @@ ChanType = Analog Output AO.TermCfg = Differential PhysicalChanName = aoTester/ao2 -[DAQmxTask AOTesterTask] -Channels = AOTesterTask/VoltageOut_0, AOTesterTask/VoltageOut_1, AOTesterTask/VoltageOut_2 -SampQuant.SampMode = Finite Samples -SampClk.ActiveEdge = Rising -SampQuant.SampPerChan = 100 -SampClk.Rate = 1000 -SampTimingType = Sample Clock -RegenMode = Allow Regeneration -SampClk.Src = - -[DAQmxChannel VoltageTesterChannel] -AI.MeasType = Voltage -AI.Voltage.Units = Volts -AI.TermCfg = Differential -AI.Max = 10 -AI.Min = -10 -ChanType = Analog Input -PhysicalChanName = tsVoltageTester1/ai0 -Descr = -Author = "Test Author" -AllowInteractiveEditing = True - -[DAQmxChannel VoltageTesterChannel2] -AI.MeasType = Voltage -AI.Voltage.Units = Volts -AI.TermCfg = Differential -AI.Max = 5 -AI.Min = -5 -ChanType = Analog Input -PhysicalChanName = tsVoltageTester1/ai1 -Descr = "Another channel" -Author = "Another Test Author" -AllowInteractiveEditing = True - [DAQmxChannel VoltageTesterTask/Voltage_0] AI.MeasType = Voltage AI.Voltage.Units = Volts @@ -72,6 +60,16 @@ AI.Min = -10 ChanType = Analog Input PhysicalChanName = tsVoltageTester1/ai0 +[DAQmxTask AOTesterTask] +Channels = AOTesterTask/VoltageOut_0, AOTesterTask/VoltageOut_1, AOTesterTask/VoltageOut_2 +SampQuant.SampMode = Finite Samples +SampClk.ActiveEdge = Rising +SampQuant.SampPerChan = 100 +SampClk.Rate = 1000 +SampTimingType = Sample Clock +RegenMode = Allow Regeneration +SampClk.Src = + [DAQmxTask VoltageTesterTask] Channels = VoltageTesterTask/Voltage_0 SampQuant.SampMode = Finite Samples @@ -81,17 +79,15 @@ SampClk.Rate = 1000 SampTimingType = Sample Clock SampClk.Src = Author = Test Author -AllowInteractiveEditing = True [DAQmxScale double_gain_scale] +Descr = Twice the gain Lin.Slope = 2 Lin.YIntercept = 0 PreScaledUnits = Volts ScaledUnits = ScaleType = Linear Author = Test Author -AllowInteractiveEditing = True -Descr = Twice the gain [DAQmxScale no_scaling_scale] Lin.Slope = 1 @@ -107,6 +103,15 @@ PreScaledUnits = Volts ScaledUnits = ScaleType = Polynomial +[DAQmxDevice aoTester] +ProductType = PXIe-4322 +DevSerialNum = 0x0 +DevIsSimulated = 1 +ProductNum = 0x76ABC4C4 +BusType = PXIe +PXI.ChassisNum = 1 +PXI.SlotNum = 3 + [DAQmxDevice bridgeTester] ProductType = PXIe-4331 DevSerialNum = 0x0 @@ -116,7 +121,30 @@ BusType = PXIe PXI.ChassisNum = 1 PXI.SlotNum = 2 -[DAQmxAccessory RM-24999_A/bridgeTester/0] +[DAQmxDevice chargeTester] +ProductType = PXIe-4480 +DevSerialNum = 0x0 +DevIsSimulated = 1 +ProductNum = 0x7844C4C4 +BusType = PXIe +PXI.ChassisNum = 1 +PXI.SlotNum = 4 + +[DAQmxDevice dmmTester] +ProductType = NI myDAQ +DevSerialNum = 0x0 +DevIsSimulated = 1 +ProductNum = 0x755B +BusType = USB + +[DAQmxDevice dsaTester] +ProductType = PXIe-4466 +DevSerialNum = 0x0 +DevIsSimulated = 1 +ProductNum = 0x7A8DC4C4 +BusType = PXIe +PXI.ChassisNum = 1 +PXI.SlotNum = 5 [DAQmxDevice nidaqmxMultithreadingTester1] ProductType = PCIe-6363 @@ -154,14 +182,27 @@ BusType = PCIe PCI.BusNum = 0x0 PCI.DevNum = 0x0 -[DAQmxDevice aoTester] -ProductType = PXIe-4322 +[DAQmxDevice positionTester] +ProductType = PXIe-4340 DevSerialNum = 0x0 DevIsSimulated = 1 -ProductNum = 0x76ABC4C4 +ProductNum = 0x7829C4C4 BusType = PXIe PXI.ChassisNum = 1 -PXI.SlotNum = 3 +PXI.SlotNum = 6 + +[DAQmxAccessory RM-24999_A/bridgeTester/0] + +[DAQmxCDAQChassis cdaqChassisTester] +ProductType = cDAQ-9185 +DevSerialNum = 0x0 +DevIsSimulated = 1 +BusType = TCP/IP +TCPIP.Hostname = +TCPIP.EthernetIP = 0.0.0.0 +TCPIP.EthernetMAC = 00:00:00:00:00:00 +TCPIP.EthernetMDNSServiceInstance = +TCPIP.DevIsReserved = 0 [DAQmxCDAQChassis tsChassisTester] ProductType = TS-15000 @@ -189,13 +230,3 @@ DevIsSimulated = 1 CompactDAQ.ChassisDevName = tsChassisTester CompactDAQ.SlotNum = 3 -[DAQmxCDAQChassis cdaqChassisTester] -ProductType = cDAQ-9185 -DevSerialNum = 0x0 -DevIsSimulated = 1 -BusType = TCP/IP -TCPIP.Hostname = -TCPIP.EthernetIP = 0.0.0.0 -TCPIP.EthernetMAC = 00:00:00:00:00:00 -TCPIP.EthernetMDNSServiceInstance = -TCPIP.DevIsReserved = 0 \ No newline at end of file From 7bd57b4970fd0059bc5147507d3f92eb49c08b54 Mon Sep 17 00:00:00 2001 From: Zach Hindes Date: Fri, 2 Feb 2024 13:57:39 -0600 Subject: [PATCH 2/5] ai done --- .../channels/test_ai_channels.py | 718 +++++++++++++++--- tests/conftest.py | 23 +- tests/max_config/nidaqmxMaxConfig.ini | 15 +- 3 files changed, 628 insertions(+), 128 deletions(-) diff --git a/tests/component/_task_modules/channels/test_ai_channels.py b/tests/component/_task_modules/channels/test_ai_channels.py index fcbe55e9..cfe65424 100644 --- a/tests/component/_task_modules/channels/test_ai_channels.py +++ b/tests/component/_task_modules/channels/test_ai_channels.py @@ -3,238 +3,720 @@ from nidaqmx import Task from nidaqmx._task_modules.channels.ai_channel import AIChannel from nidaqmx.constants import ( + AccelChargeSensitivityUnits, + AccelSensitivityUnits, + AccelUnits, + ACExcitWireMode, BridgeConfiguration, + BridgeUnits, + ChargeUnits, + CJCSource, + CurrentShuntResistorLocation, + EddyCurrentProxProbeSensitivityUnits, ExcitationSource, - StrainGageRosetteType, + ForceIEPESensorSensitivityUnits, + ForceUnits, + LVDTSensitivityUnits, + ResistanceConfiguration, + RTDType, + StrainGageBridgeType, StrainGageRosetteMeasurementType, + StrainGageRosetteType, + TemperatureUnits, TerminalConfiguration, + ThermocoupleType, UsageTypeAI, VoltageUnits, ) -def test___ai_channel_collection___add_ai_voltage_chan___sets_meas_type(task, sim_x_series_device): - chan = task.ai_channels.add_ai_voltage_chan( - sim_x_series_device.ai_physical_chans[0].name) - assert chan.ai_meas_type == UsageTypeAI.VOLTAGE -@pytest.mark.parametrize("desired_term_config, expected_term_cfg", - [(TerminalConfiguration.DEFAULT, TerminalConfiguration.DIFF), - (TerminalConfiguration.DIFF, TerminalConfiguration.DIFF), - (TerminalConfiguration.RSE, TerminalConfiguration.RSE),] +# Note: Tests for other channel types will be less complete given that the underlying Python +# implementation is code-generated and the underlying C API implementation is well unit-tested. +@pytest.mark.parametrize( + "desired_term_config, expected_term_cfg", + [ + (TerminalConfiguration.DEFAULT, TerminalConfiguration.DIFF), + (TerminalConfiguration.DIFF, TerminalConfiguration.DIFF), + (TerminalConfiguration.RSE, TerminalConfiguration.RSE), + ], ) -def test___ai_channel_collection___add_ai_voltage_chan___sets_term_cfg(task, sim_x_series_device, desired_term_config, expected_term_cfg): - chan = task.ai_channels.add_ai_voltage_chan( - sim_x_series_device.ai_physical_chans[0].name, - terminal_config=desired_term_config) - assert chan.ai_term_cfg == expected_term_cfg - -def test___ai_channel_collection___add_ai_voltage_chan___sets_min_max(task, sim_x_series_device): - # ranges are more varied per device, but +/- 10V is consistent and different from the default - chan = task.ai_channels.add_ai_voltage_chan( - sim_x_series_device.ai_physical_chans[0].name, - min_val=-10.0, max_val=10.0) - assert chan.ai_max == 10 - assert chan.ai_min == -10 - -@pytest.mark.parametrize("units, custom_scale_name", - [(VoltageUnits.VOLTS, ""), - (VoltageUnits.FROM_CUSTOM_SCALE, "no_scaling_scale")] +@pytest.mark.parametrize("min_val, max_val", [(-10, 10), (-5, 5)]) +@pytest.mark.parametrize( + "units, custom_scale_name", + [(VoltageUnits.VOLTS, ""), (VoltageUnits.FROM_CUSTOM_SCALE, "no_scaling_scale")], ) -def test___ai_channel_collection___add_ai_voltage_chan___sets_units(task, sim_x_series_device, units, custom_scale_name): +def test___ai_channel_collection___add_ai_voltage_chan___sets_channel_attributes( + task, + sim_6363_device, + desired_term_config, + expected_term_cfg, + min_val, + max_val, + units, + custom_scale_name, +): chan = task.ai_channels.add_ai_voltage_chan( - sim_x_series_device.ai_physical_chans[0].name, - units=units, custom_scale_name=custom_scale_name) + sim_6363_device.ai_physical_chans[0].name, + terminal_config=desired_term_config, + min_val=min_val, + max_val=max_val, + units=units, + custom_scale_name=custom_scale_name, + ) + + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE + assert chan.ai_term_cfg == expected_term_cfg + assert chan.ai_min == min_val + assert chan.ai_max == max_val assert chan.ai_voltage_units == units assert chan.ai_custom_scale.name == custom_scale_name -# Note: From here on out, we do not test ranges or custom scales. Scaling from native device -# ranges to sensor units can be complex, and, similarly, creating a custom scale for each scenario -# is an untenable matrix. Given that the underlying Python implementation is code-generated and the -# underlying C API implementation is well unit-tested, this is defensible. -def test___ai_channel_collection___add_ai_accel_4_wire_dc_voltage_chan___sets_meas_type(task, sim_charge_device): +@pytest.mark.parametrize( + "units, sensitivity, sensitivity_units", + [ + (AccelUnits.G, 1000.0, AccelSensitivityUnits.MILLIVOLTS_PER_G), + (AccelUnits.METERS_PER_SECOND_SQUARED, 0.5, AccelSensitivityUnits.VOLTS_PER_G), + ], +) +def test___ai_channel_collection___add_ai_accel_4_wire_dc_voltage_chan___sets_channel_attributes( + task, sim_charge_device, units, sensitivity, sensitivity_units +): chan = task.ai_channels.add_ai_accel_4_wire_dc_voltage_chan( - sim_charge_device.ai_physical_chans[0].name) + sim_charge_device.ai_physical_chans[0].name, + units=units, + sensitivity=sensitivity, + sensitivity_units=sensitivity_units, + ) assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_4_WIRE_DC_VOLTAGE + assert chan.ai_accel_units == units + assert chan.ai_accel_4_wire_dc_voltage_sensitivity == sensitivity + assert chan.ai_accel_4_wire_dc_voltage_sensitivity_units == sensitivity_units -def test___ai_channel_collection___add_ai_accel_chan___sets_meas_type(task, sim_dsa_device): + +@pytest.mark.parametrize( + "units, sensitivity, sensitivity_units", + [ + (AccelUnits.G, 1000.0, AccelSensitivityUnits.MILLIVOLTS_PER_G), + (AccelUnits.METERS_PER_SECOND_SQUARED, 0.5, AccelSensitivityUnits.VOLTS_PER_G), + ], +) +def test___ai_channel_collection___add_ai_accel_chan___sets_channel_attributes( + task, sim_dsa_device, units, sensitivity, sensitivity_units +): chan = task.ai_channels.add_ai_accel_chan( - sim_dsa_device.ai_physical_chans[0].name) - assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_ACCELEROMETER_CURRENT_INPUT + sim_dsa_device.ai_physical_chans[0].name, + units=units, + sensitivity=sensitivity, + sensitivity_units=sensitivity_units, + ) -def test___ai_channel_collection___add_ai_accel_charge_chan___sets_meas_type(task, sim_charge_device): + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_ACCELEROMETER_CURRENT_INPUT + assert chan.ai_accel_units == units + assert chan.ai_accel_sensitivity == sensitivity + assert chan.ai_accel_sensitivity_units == sensitivity_units + + +@pytest.mark.parametrize( + "units, sensitivity, sensitivity_units", + [ + (AccelUnits.G, 100.0, AccelChargeSensitivityUnits.PICO_COULOMBS_PER_G), + ( + AccelUnits.METERS_PER_SECOND_SQUARED, + 0.5, + AccelChargeSensitivityUnits.PICO_COULOMBS_PER_METERS_PER_SECOND_SQUARED, + ), + ], +) +def test___ai_channel_collection___add_ai_accel_charge_chan___sets_channel_attributes( + task, sim_charge_device, units, sensitivity, sensitivity_units +): chan = task.ai_channels.add_ai_accel_charge_chan( - sim_charge_device.ai_physical_chans[0].name) + sim_charge_device.ai_physical_chans[0].name, + units=units, + sensitivity=sensitivity, + sensitivity_units=sensitivity_units, + ) + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_CHARGE + assert chan.ai_accel_units == units + assert chan.ai_accel_charge_sensitivity == sensitivity + assert chan.ai_accel_charge_sensitivity_units == sensitivity_units + -def test___ai_channel_collection___add_ai_bridge_chan___sets_meas_type(task, sim_bridge_device): +@pytest.mark.parametrize( + "units, bridge_config, nominal_bridge_resistance", + [ + (BridgeUnits.VOLTS_PER_VOLT, BridgeConfiguration.FULL_BRIDGE, 350.0), + (BridgeUnits.MILLIVOLTS_PER_VOLT, BridgeConfiguration.QUARTER_BRIDGE, 120.0), + ], +) +def test___ai_channel_collection___add_ai_bridge_chan___sets_channel_attributes( + task, sim_bridge_device, units, bridge_config, nominal_bridge_resistance +): chan = task.ai_channels.add_ai_bridge_chan( - sim_bridge_device.ai_physical_chans[0].name) + sim_bridge_device.ai_physical_chans[0].name, + units=units, + bridge_config=bridge_config, + nominal_bridge_resistance=nominal_bridge_resistance, + ) + assert chan.ai_meas_type == UsageTypeAI.BRIDGE + assert chan.ai_bridge_units == units + assert chan.ai_bridge_cfg == bridge_config + assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance -def test___ai_channel_collection___add_ai_charge_chan___sets_meas_type(task, sim_charge_device): + +@pytest.mark.parametrize("units", [ChargeUnits.COULOMBS, ChargeUnits.PICO_COULOMBS]) +def test___ai_channel_collection___add_ai_charge_chan___sets_channel_attributes( + task, sim_charge_device, units +): chan = task.ai_channels.add_ai_charge_chan( - sim_charge_device.ai_physical_chans[0].name) - assert chan.ai_meas_type == UsageTypeAI.CHARGE + sim_charge_device.ai_physical_chans[0].name, units=units + ) -def test___ai_channel_collection___add_ai_current_chan___sets_meas_type(task, sim_x_series_device): + assert chan.ai_meas_type == UsageTypeAI.CHARGE + assert chan.ai_charge_units == units + + +@pytest.mark.parametrize( + "shunt_resistor_loc, expected_shunt_resistor_loc, ext_shunt_resistor_val", + [ + ( + CurrentShuntResistorLocation.LET_DRIVER_CHOOSE, + CurrentShuntResistorLocation.EXTERNAL, + 249.0, + ), + (CurrentShuntResistorLocation.EXTERNAL, CurrentShuntResistorLocation.EXTERNAL, 99.0), + ], +) +def test___ai_channel_collection___add_ai_current_chan___sets_channel_attributes( + task, sim_6363_device, shunt_resistor_loc, expected_shunt_resistor_loc, ext_shunt_resistor_val +): chan = task.ai_channels.add_ai_current_chan( - sim_x_series_device.ai_physical_chans[0].name) + sim_6363_device.ai_physical_chans[0].name, + shunt_resistor_loc=shunt_resistor_loc, + ext_shunt_resistor_val=ext_shunt_resistor_val, + ) + assert chan.ai_meas_type == UsageTypeAI.CURRENT + assert chan.ai_current_shunt_loc == expected_shunt_resistor_loc + assert chan.ai_current_shunt_resistance == ext_shunt_resistor_val -def test___ai_channel_collection___add_ai_current_rms_chan___sets_meas_type(task, sim_dmm_device): + +@pytest.mark.parametrize( + "shunt_resistor_loc, expected_shunt_resistor_loc", + [ + (CurrentShuntResistorLocation.LET_DRIVER_CHOOSE, CurrentShuntResistorLocation.INTERNAL), + (CurrentShuntResistorLocation.INTERNAL, CurrentShuntResistorLocation.INTERNAL), + ], +) +def test___ai_channel_collection___add_ai_current_rms_chan___sets_channel_attributes( + task, sim_dmm_device, shunt_resistor_loc, expected_shunt_resistor_loc +): chan = task.ai_channels.add_ai_current_rms_chan( f"{sim_dmm_device.name}/dmm", - min_val=0.0, max_val=1.0) + # dmm is unipolar, defaults don't work + min_val=0.0, + max_val=1.0, + shunt_resistor_loc=shunt_resistor_loc, + ) assert chan.ai_meas_type == UsageTypeAI.CURRENT_ACRMS + assert chan.ai_current_shunt_loc == expected_shunt_resistor_loc -def test___ai_channel_collection___add_ai_force_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): - # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. + +@pytest.mark.parametrize( + "bridge_config, nominal_bridge_resistance, forward_coeffs, reverse_coeffs", + [ + (BridgeConfiguration.FULL_BRIDGE, 350.0, [0.0, 1.0], [0.0, 1.0]), + (BridgeConfiguration.QUARTER_BRIDGE, 120.0, [1.0, 2.0], [-0.5, 0.5]), + ], +) +def test___ai_channel_collection___add_ai_force_bridge_polynomial_chan___sets_channel_attributes( + task, + sim_bridge_device, + bridge_config, + nominal_bridge_resistance, + forward_coeffs, + reverse_coeffs, +): chan = task.ai_channels.add_ai_force_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, - forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + bridge_config=bridge_config, + nominal_bridge_resistance=nominal_bridge_resistance, + forward_coeffs=forward_coeffs, + reverse_coeffs=reverse_coeffs, + ) assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE - -def test___ai_channel_collection___add_ai_force_bridge_table_chan___sets_meas_type(task, sim_bridge_device): - # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + assert chan.ai_bridge_cfg == bridge_config + assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance + assert chan.ai_bridge_poly_forward_coeff == forward_coeffs + assert chan.ai_bridge_poly_reverse_coeff == reverse_coeffs + + +@pytest.mark.parametrize( + "bridge_config, nominal_bridge_resistance, electrical_vals, physical_vals", + [ + (BridgeConfiguration.FULL_BRIDGE, 350.0, [-1.0, 0.0, 1.0], [-100.0, 0.0, 100.0]), + (BridgeConfiguration.QUARTER_BRIDGE, 120.0, [-2.0, 0.0, 2.0], [-200.0, 0.0, 200.0]), + ], +) +def test___ai_channel_collection___add_ai_force_bridge_table_chan___sets_channel_attributes( + task, + sim_bridge_device, + bridge_config, + nominal_bridge_resistance, + electrical_vals, + physical_vals, +): chan = task.ai_channels.add_ai_force_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, - electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + bridge_config=bridge_config, + nominal_bridge_resistance=nominal_bridge_resistance, + electrical_vals=electrical_vals, + physical_vals=physical_vals, + ) assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE - -def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + assert chan.ai_bridge_cfg == bridge_config + assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance + assert chan.ai_bridge_table_electrical_vals == electrical_vals + assert chan.ai_bridge_table_physical_vals == physical_vals + + +@pytest.mark.parametrize( + "bridge_config, nominal_bridge_resistance, first_electrical_val, second_electrical_val, first_physical_val, second_physical_val", + [ + (BridgeConfiguration.FULL_BRIDGE, 350.0, 0.0, 2.0, 0.0, 100.0), + (BridgeConfiguration.QUARTER_BRIDGE, 120.0, 0.0, 4.0, 0.0, 200.0), + ], +) +def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets_channel_attributes( + task, + sim_bridge_device, + bridge_config, + nominal_bridge_resistance, + first_electrical_val, + second_electrical_val, + first_physical_val, + second_physical_val, +): chan = task.ai_channels.add_ai_force_bridge_two_point_lin_chan( - sim_bridge_device.ai_physical_chans[0].name) + sim_bridge_device.ai_physical_chans[0].name, + bridge_config=bridge_config, + nominal_bridge_resistance=nominal_bridge_resistance, + first_electrical_val=first_electrical_val, + second_electrical_val=second_electrical_val, + first_physical_val=first_physical_val, + second_physical_val=second_physical_val, + ) assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE - -def test___ai_channel_collection___add_ai_force_iepe_chan___sets_meas_type(task, sim_dsa_device): + assert chan.ai_bridge_cfg == bridge_config + assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance + assert chan.ai_bridge_two_point_lin_first_electrical_val == first_electrical_val + assert chan.ai_bridge_two_point_lin_second_electrical_val == second_electrical_val + assert chan.ai_bridge_two_point_lin_first_physical_val == first_physical_val + assert chan.ai_bridge_two_point_lin_second_physical_val == second_physical_val + + +@pytest.mark.parametrize( + "units, sensitivity, sensitivity_units", + [ + (ForceUnits.NEWTONS, 2.25, ForceIEPESensorSensitivityUnits.MILLIVOLTS_PER_NEWTON), + (ForceUnits.POUNDS, 1.25, ForceIEPESensorSensitivityUnits.MILLIVOLTS_PER_POUND), + ], +) +def test___ai_channel_collection___add_ai_force_iepe_chan___sets_channel_attributes( + task, sim_dsa_device, units, sensitivity, sensitivity_units +): chan = task.ai_channels.add_ai_force_iepe_chan( - sim_dsa_device.ai_physical_chans[0].name) + sim_dsa_device.ai_physical_chans[0].name, + units=units, + sensitivity=sensitivity, + sensitivity_units=sensitivity_units, + ) assert chan.ai_meas_type == UsageTypeAI.FORCE_IEPE_SENSOR + assert chan.ai_force_units == units + assert chan.ai_force_iepe_sensor_sensitivity == sensitivity + assert chan.ai_force_iepe_sensor_sensitivity_units == sensitivity_units + # No active DAQmx devices support add_ai_freq_voltage_chan -def test___ai_channel_collection___add_ai_microphone_chan___sets_meas_type(task, sim_dsa_device): + +@pytest.mark.parametrize( + "mic_sensitivity, max_snd_press_level", + [ + (5.0, 50.0), + (10.0, 100.0), + ], +) +def test___ai_channel_collection___add_ai_microphone_chan___sets_channel_attributes( + task, sim_dsa_device, mic_sensitivity, max_snd_press_level +): chan = task.ai_channels.add_ai_microphone_chan( - sim_dsa_device.ai_physical_chans[0].name) + sim_dsa_device.ai_physical_chans[0].name, + mic_sensitivity=mic_sensitivity, + max_snd_press_level=max_snd_press_level, + ) + assert chan.ai_meas_type == UsageTypeAI.SOUND_PRESSURE_MICROPHONE + assert chan.ai_microphone_sensitivity == mic_sensitivity + assert chan.ai_sound_pressure_max_sound_pressure_lvl == max_snd_press_level + -def test___ai_channel_collection___add_ai_pos_eddy_curr_prox_probe_chan___sets_meas_type(task, sim_dsa_device): +@pytest.mark.parametrize( + "sensitivity_units, sensitivity", + [ + (EddyCurrentProxProbeSensitivityUnits.MILLIVOLTS_PER_MIL, 200.0), + (EddyCurrentProxProbeSensitivityUnits.VOLTS_PER_MIL, 0.2), + ], +) +def test___ai_channel_collection___add_ai_pos_eddy_curr_prox_probe_chan___sets_channel_attributes( + task, sim_dsa_device, sensitivity_units, sensitivity +): chan = task.ai_channels.add_ai_pos_eddy_curr_prox_probe_chan( - sim_dsa_device.ai_physical_chans[0].name) + sim_dsa_device.ai_physical_chans[0].name, + sensitivity_units=sensitivity_units, + sensitivity=sensitivity, + ) assert chan.ai_meas_type == UsageTypeAI.POSITION_EDDY_CURRENT_PROX_PROBE + assert chan.ai_eddy_current_prox_sensitivity_units == sensitivity_units + assert chan.ai_eddy_current_prox_sensitivity == sensitivity + -def test___ai_channel_collection___add_ai_pos_lvdt_chan___sets_meas_type(task, sim_position_device): +@pytest.mark.parametrize( + "sensitivity_units, sensitivity", + [ + (LVDTSensitivityUnits.MILLIVOLTS_PER_VOLT_PER_MILLIMETER, 50.0), + (LVDTSensitivityUnits.MILLIVOLTS_PER_VOLT_PER_MILLI_INCH, 0.5), + ], +) +@pytest.mark.parametrize( + "ac_excit_wire_mode, voltage_excit_val, voltage_excit_freq", + [(ACExcitWireMode.FOUR_WIRE, 1.0, 2500.0), (ACExcitWireMode.FIVE_WIRE, 1.5, 2000.0)], +) +def test___ai_channel_collection___add_ai_pos_lvdt_chan___sets_channel_attributes( + task, + sim_position_device, + sensitivity_units, + sensitivity, + ac_excit_wire_mode, + voltage_excit_val, + voltage_excit_freq, +): chan = task.ai_channels.add_ai_pos_lvdt_chan( - sim_position_device.ai_physical_chans[0].name) - assert chan.ai_meas_type == UsageTypeAI.POSITION_LINEAR_LVDT + sim_position_device.ai_physical_chans[0].name, + sensitivity_units=sensitivity_units, + sensitivity=sensitivity, + ac_excit_wire_mode=ac_excit_wire_mode, + voltage_excit_val=voltage_excit_val, + voltage_excit_freq=voltage_excit_freq, + ) -def test___ai_channel_collection___add_ai_pos_rvdt_chan___sets_meas_type(task, sim_position_device): - chan = task.ai_channels.add_ai_pos_rvdt_chan( - sim_position_device.ai_physical_chans[0].name) + assert chan.ai_meas_type == UsageTypeAI.POSITION_LINEAR_LVDT + assert chan.ai_lvdt_sensitivity_units == sensitivity_units + assert chan.ai_lvdt_sensitivity == sensitivity + assert chan.ai_ac_excit_wire_mode == ac_excit_wire_mode + assert chan.ai_excit_val == voltage_excit_val + assert chan.ai_ac_excit_freq == voltage_excit_freq + + +# Nothing novel here vs. lvdt channels. +def test___ai_channel_collection___add_ai_pos_rvdt_chan___sets_channel_attributes( + task, sim_position_device +): + chan = task.ai_channels.add_ai_pos_rvdt_chan(sim_position_device.ai_physical_chans[0].name) assert chan.ai_meas_type == UsageTypeAI.POSITION_ANGULAR_RVDT -def test___ai_channel_collection___add_ai_power_chan___sets_meas_type(task, sim_ts_power_device): + +@pytest.mark.parametrize( + "voltage_setpoint, current_setpoint, output_enable", + [ + (0.0, 0.5, False), + (2.5, 1.0, True), + ], +) +def test___ai_channel_collection___add_ai_power_chan___sets_channel_attributes( + task, sim_ts_power_device, voltage_setpoint, current_setpoint, output_enable +): chan = task.ai_channels.add_ai_power_chan( f"{sim_ts_power_device.name}/power", - voltage_setpoint=0.0, current_setpoint=30e-3, output_enable=False) + voltage_setpoint=voltage_setpoint, + current_setpoint=current_setpoint, + output_enable=output_enable, + ) assert chan.ai_meas_type == UsageTypeAI.POWER + assert chan.pwr_voltage_setpoint == voltage_setpoint + assert chan.pwr_current_setpoint == current_setpoint + assert chan.pwr_output_enable == output_enable -def test___ai_channel_collection___add_ai_pressure_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): - # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. + +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_pressure_bridge_polynomial_chan___sets_channel_attributes( + task, sim_bridge_device +): + # #482: Default argument values for bridge create channel functions are unusable chan = task.ai_channels.add_ai_pressure_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, - forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + forward_coeffs=[0.0, 1.0], + reverse_coeffs=[0.0, 1.0], + ) assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE -def test___ai_channel_collection___add_ai_pressure_bridge_table_chan___sets_meas_type(task, sim_bridge_device): - # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_pressure_bridge_table_chan___sets_channel_attributes( + task, sim_bridge_device +): + # #482: Default argument values for bridge create channel functions are unusable chan = task.ai_channels.add_ai_pressure_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, - electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + electrical_vals=[-1.0, 0.0, 1.0], + physical_vals=[-100.0, 0.0, 100.0], + ) assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE -def test___ai_channel_collection___add_ai_pressure_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_pressure_bridge_two_point_lin_chan___sets_channel_attributes( + task, sim_bridge_device +): chan = task.ai_channels.add_ai_pressure_bridge_two_point_lin_chan( - sim_bridge_device.ai_physical_chans[0].name) + sim_bridge_device.ai_physical_chans[0].name + ) assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE -def test___ai_channel_collection___add_ai_resistance_chan___sets_meas_type(task, sim_x_series_device): + +@pytest.mark.parametrize( + "resistance_config", + [ + (ResistanceConfiguration.TWO_WIRE), + (ResistanceConfiguration.THREE_WIRE), + ], +) +def test___ai_channel_collection___add_ai_resistance_chan___sets_channel_attributes( + task, sim_6363_device, resistance_config +): chan = task.ai_channels.add_ai_resistance_chan( - sim_x_series_device.ai_physical_chans[0].name) + sim_6363_device.ai_physical_chans[0].name, resistance_config=resistance_config + ) assert chan.ai_meas_type == UsageTypeAI.RESISTANCE + assert chan.ai_resistance_cfg == resistance_config -def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_meas_type(task, sim_bridge_device): - # TODO: rosette_meas_types input expects an array of ints, but it should be enums + +# Rosette is very complicated, so I'm not parametrizing this test. +def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_channel_attributes( + task, sim_bridge_device +): + # #483: add_ai_rosette_strain_gage_chan parameter rosette_meas_types has the wrong type task.ai_channels.add_ai_rosette_strain_gage_chan( ",".join(sim_bridge_device.ai_physical_chans.channel_names[0:2]), - StrainGageRosetteType.TEE, 0.0, - [StrainGageRosetteMeasurementType.PRINCIPAL_STRAIN_1.value]) + StrainGageRosetteType.TEE, + 0.0, + [StrainGageRosetteMeasurementType.PRINCIPAL_STRAIN_1.value], + ) chan = task.ai_channels["rosette0_principalStrain1"] assert chan.ai_meas_type == UsageTypeAI.ROSETTE_STRAIN_GAGE -def test___ai_channel_collection___add_ai_rtd_chan___sets_meas_type(task, sim_x_series_device): + +@pytest.mark.parametrize( + "rtd_type, resistance_config", + [ + (RTDType.PT_3750, ResistanceConfiguration.TWO_WIRE), + (RTDType.PT_3851, ResistanceConfiguration.THREE_WIRE), + ], +) +def test___ai_channel_collection___add_ai_rtd_chan___sets_channel_attributes( + task, sim_6363_device, rtd_type, resistance_config +): chan = task.ai_channels.add_ai_rtd_chan( - sim_x_series_device.ai_physical_chans[0].name) + sim_6363_device.ai_physical_chans[0].name, + rtd_type=rtd_type, + resistance_config=resistance_config, + ) assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_RTD + assert chan.ai_rtd_type == rtd_type + assert chan.ai_resistance_cfg == resistance_config + -def test___ai_channel_collection___add_ai_strain_gage_chan___sets_meas_type(task, sim_bridge_device): +@pytest.mark.parametrize( + "strain_config, gage_factor, nominal_gage_resistance", + [ + (StrainGageBridgeType.FULL_BRIDGE_I, 2.1, 350.0), + (StrainGageBridgeType.QUARTER_BRIDGE_I, 1.1, 120.0), + ], +) +def test___ai_channel_collection___add_ai_strain_gage_chan___sets_channel_attributes( + task, sim_bridge_device, strain_config, gage_factor, nominal_gage_resistance +): chan = task.ai_channels.add_ai_strain_gage_chan( - sim_bridge_device.ai_physical_chans[0].name) + sim_bridge_device.ai_physical_chans[0].name, + strain_config=strain_config, + gage_factor=gage_factor, + nominal_gage_resistance=nominal_gage_resistance, + ) assert chan.ai_meas_type == UsageTypeAI.STRAIN_STRAIN_GAGE + assert chan.ai_strain_gage_cfg == strain_config + assert chan.ai_strain_gage_gage_factor == gage_factor + assert chan.ai_bridge_nom_resistance == nominal_gage_resistance + -def test___ai_channel_collection___add_ai_temp_built_in_sensor_chan___sets_meas_type(task, sim_x_series_device): +def test___ai_channel_collection___add_ai_temp_built_in_sensor_chan___sets_channel_attributes( + task, sim_6363_device +): chan = task.ai_channels.add_ai_temp_built_in_sensor_chan( - f"{sim_x_series_device.name}/_boardTempSensor_vs_aignd") + f"{sim_6363_device.name}/_boardTempSensor_vs_aignd" + ) assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_BUILT_IN_SENSOR -def test___ai_channel_collection___add_ai_thrmcpl_chan___sets_meas_type(task, sim_x_series_device): + +@pytest.mark.parametrize( + "thermocouple_type, cjc_source, cjc_val", + [ + (ThermocoupleType.J, CJCSource.CONSTANT_USER_VALUE, 25.0), + (ThermocoupleType.K, CJCSource.BUILT_IN, 0.0), + ], +) +def test___ai_channel_collection___add_ai_thrmcpl_chan___sets_channel_attributes( + task, sim_temperature_device, thermocouple_type, cjc_source, cjc_val +): chan = task.ai_channels.add_ai_thrmcpl_chan( - sim_x_series_device.ai_physical_chans[0].name) + sim_temperature_device.ai_physical_chans[0].name, + thermocouple_type=thermocouple_type, + cjc_source=cjc_source, + cjc_val=cjc_val, + ) assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMOCOUPLE + assert chan.ai_thrmcpl_type == thermocouple_type + assert chan.ai_thrmcpl_cjc_src == cjc_source + assert chan.ai_thrmcpl_cjc_val == cjc_val + -def test___ai_channel_collection___add_ai_thrmstr_chan_iex___sets_meas_type(task, sim_x_series_device): +@pytest.mark.parametrize( + "resistance_config, a, b, c", + [ + (ResistanceConfiguration.TWO_WIRE, 0.1, 0.2, 0.3), + (ResistanceConfiguration.FOUR_WIRE, 0.2, 0.3, 0.4), + ], +) +def test___ai_channel_collection___add_ai_thrmstr_chan_iex___sets_channel_attributes( + task, sim_6363_device, resistance_config, a, b, c +): chan = task.ai_channels.add_ai_thrmstr_chan_iex( - sim_x_series_device.ai_physical_chans[0].name) + sim_6363_device.ai_physical_chans[0].name, + resistance_config=resistance_config, + a=a, + b=b, + c=c, + ) assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR - -def test___ai_channel_collection___add_ai_thrmstr_chan_vex___sets_meas_type(task, sim_x_series_device): + assert chan.ai_resistance_cfg == resistance_config + assert chan.ai_thrmstr_a == a + assert chan.ai_thrmstr_b == b + assert chan.ai_thrmstr_c == c + + +@pytest.mark.parametrize( + "units, resistance_config", + [ + (TemperatureUnits.DEG_C, ResistanceConfiguration.THREE_WIRE), + (TemperatureUnits.DEG_F, ResistanceConfiguration.FOUR_WIRE), + ], +) +def test___ai_channel_collection___add_ai_thrmstr_chan_vex___sets_channel_attributes( + task, sim_6363_device, units, resistance_config +): chan = task.ai_channels.add_ai_thrmstr_chan_vex( - sim_x_series_device.ai_physical_chans[0].name) + sim_6363_device.ai_physical_chans[0].name, units=units, resistance_config=resistance_config + ) assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR + assert chan.ai_temp_units == units + assert chan.ai_resistance_cfg == resistance_config + -def test___ai_channel_collection___add_ai_torque_bridge_polynomial_chan___sets_meas_type(task, sim_bridge_device): - # TODO: forward_coeffs and reverse_coeffs are actually required, but optional with default=None. Fun. +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_torque_bridge_polynomial_chan___sets_channel_attributes( + task, sim_bridge_device +): + # #482: Default argument values for bridge create channel functions are unusable chan = task.ai_channels.add_ai_torque_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, - forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0]) + forward_coeffs=[0.0, 1.0], + reverse_coeffs=[0.0, 1.0], + ) assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE -def test___ai_channel_collection___add_ai_torque_bridge_table_chan___sets_meas_type(task, sim_bridge_device): - # TODO: electrical_vals and physical_vals are actually required, but optional with default=None. Fun. + +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_torque_bridge_table_chan___sets_channel_attributes( + task, sim_bridge_device +): + # #482: Default argument values for bridge create channel functions are unusable chan = task.ai_channels.add_ai_torque_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, - electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0]) + electrical_vals=[-1.0, 0.0, 1.0], + physical_vals=[-100.0, 0.0, 100.0], + ) assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE -def test___ai_channel_collection___add_ai_torque_bridge_two_point_lin_chan___sets_meas_type(task, sim_bridge_device): + +# Nothing novel here vs. other bridge-based channels. +def test___ai_channel_collection___add_ai_torque_bridge_two_point_lin_chan___sets_channel_attributes( + task, sim_bridge_device +): chan = task.ai_channels.add_ai_torque_bridge_two_point_lin_chan( - sim_bridge_device.ai_physical_chans[0].name) + sim_bridge_device.ai_physical_chans[0].name + ) assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE -def test___ai_channel_collection___add_ai_velocity_iepe_chan___sets_meas_type(task, sim_dsa_device): - chan = task.ai_channels.add_ai_velocity_iepe_chan( - sim_dsa_device.ai_physical_chans[0].name) + +# Nothing novel here vs. other iepe channels. +def test___ai_channel_collection___add_ai_velocity_iepe_chan___sets_channel_attributes( + task, sim_dsa_device +): + chan = task.ai_channels.add_ai_velocity_iepe_chan(sim_dsa_device.ai_physical_chans[0].name) assert chan.ai_meas_type == UsageTypeAI.VELOCITY_IEPE_SENSOR -def test___ai_channel_collection___add_ai_voltage_chan_with_excit___sets_meas_type(task, sim_x_series_device): + +@pytest.mark.parametrize( + "min_val, max_val, bridge_config, voltage_exict_source, voltage_excit_val, use_excit_for_scaling", + [ + (-10.0, 10.0, BridgeConfiguration.FULL_BRIDGE, ExcitationSource.EXTERNAL, 5.0, False), + (-2.0, 2.0, BridgeConfiguration.HALF_BRIDGE, ExcitationSource.EXTERNAL, 5.0, True), + ], +) +def test___ai_channel_collection___add_ai_voltage_chan_with_excit___sets_channel_attributes( + task, + sim_6363_device, + min_val, + max_val, + bridge_config, + voltage_exict_source, + voltage_excit_val, + use_excit_for_scaling, +): chan = task.ai_channels.add_ai_voltage_chan_with_excit( - sim_x_series_device.ai_physical_chans[0].name, - voltage_excit_source=ExcitationSource.EXTERNAL, voltage_excit_val=3.3) + sim_6363_device.ai_physical_chans[0].name, + min_val=min_val, + max_val=max_val, + bridge_config=bridge_config, + voltage_excit_source=voltage_exict_source, + voltage_excit_val=voltage_excit_val, + use_excit_for_scaling=use_excit_for_scaling, + ) assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_CUSTOM_WITH_EXCITATION + assert chan.ai_min == min_val + assert chan.ai_max == max_val + assert chan.ai_bridge_cfg == bridge_config + assert chan.ai_excit_src == voltage_exict_source + assert chan.ai_excit_val == voltage_excit_val + assert chan.ai_excit_use_for_scaling == use_excit_for_scaling -def test___ai_channel_collection___add_ai_voltage_rms_chan___sets_meas_type(task, sim_dmm_device): + +def test___ai_channel_collection___add_ai_voltage_rms_chan___sets_channel_attributes( + task, sim_dmm_device +): chan = task.ai_channels.add_ai_voltage_rms_chan( - f"{sim_dmm_device.name}/dmm", - min_val=0.0, max_val=1.0) + f"{sim_dmm_device.name}/dmm", min_val=0.0, max_val=1.0 + ) assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_ACRMS diff --git a/tests/conftest.py b/tests/conftest.py index eb53bfdd..c8dcae09 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -120,10 +120,7 @@ def _device_by_name(product_type, device_type, system): or (device_type == DeviceType.REAL and not device.is_simulated) or (device_type == DeviceType.SIMULATED and device.is_simulated) ) - if ( - device_type_match - and device.product_type == product_type - ): + if device_type_match and device.product_type == product_type: return device pytest.skip( @@ -136,22 +133,28 @@ def _device_by_name(product_type, device_type, system): @pytest.fixture(scope="function") def any_x_series_device(system): - """Gets any x series device information.""" + """Gets any X Series device information.""" return _x_series_device(DeviceType.ANY, system) @pytest.fixture(scope="function") def real_x_series_device(system): - """Gets the real x series device information.""" + """Gets real X Series device information.""" return _x_series_device(DeviceType.REAL, system) @pytest.fixture(scope="function") def sim_x_series_device(system): - """Gets simulated x series device information.""" + """Gets simulated X Series device information.""" return _x_series_device(DeviceType.SIMULATED, system) +@pytest.fixture(scope="function") +def sim_6363_device(system): + """Gets a simulated 6363.""" + return _device_by_name("PCIe-6363", DeviceType.SIMULATED, system) + + @pytest.fixture(scope="function") def sim_ts_chassis(system): """Gets simulated TestScale chassis information.""" @@ -262,6 +265,12 @@ def sim_position_device(system): return _device_by_name("PXIe-4340", DeviceType.SIMULATED, system) +@pytest.fixture(scope="function") +def sim_temperature_device(system): + """Gets a simulated 4353.""" + return _device_by_name("PXIe-4353", DeviceType.SIMULATED, system) + + @pytest.fixture(scope="function") def multi_threading_test_devices(system): """Gets multi threading test devices information.""" diff --git a/tests/max_config/nidaqmxMaxConfig.ini b/tests/max_config/nidaqmxMaxConfig.ini index 61c67958..e9c55666 100644 --- a/tests/max_config/nidaqmxMaxConfig.ini +++ b/tests/max_config/nidaqmxMaxConfig.ini @@ -128,7 +128,7 @@ DevIsSimulated = 1 ProductNum = 0x7844C4C4 BusType = PXIe PXI.ChassisNum = 1 -PXI.SlotNum = 4 +PXI.SlotNum = 5 [DAQmxDevice dmmTester] ProductType = NI myDAQ @@ -144,7 +144,7 @@ DevIsSimulated = 1 ProductNum = 0x7A8DC4C4 BusType = PXIe PXI.ChassisNum = 1 -PXI.SlotNum = 5 +PXI.SlotNum = 6 [DAQmxDevice nidaqmxMultithreadingTester1] ProductType = PCIe-6363 @@ -188,8 +188,17 @@ DevSerialNum = 0x0 DevIsSimulated = 1 ProductNum = 0x7829C4C4 BusType = PXIe +PXI.ChassisNum = 4294967295 +PXI.SlotNum = 4294967295 + +[DAQmxDevice tempTester] +ProductType = PXIe-4353 +DevSerialNum = 0x0 +DevIsSimulated = 1 +ProductNum = 0x74B2C4C4 +BusType = PXIe PXI.ChassisNum = 1 -PXI.SlotNum = 6 +PXI.SlotNum = 7 [DAQmxAccessory RM-24999_A/bridgeTester/0] From 8245781b48cf7b1c0eebd86e05da99428ce22617 Mon Sep 17 00:00:00 2001 From: Zach Hindes Date: Fri, 2 Feb 2024 14:04:48 -0600 Subject: [PATCH 3/5] rename --- tests/conftest.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c8dcae09..37b898ef 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -113,7 +113,7 @@ def _x_series_device(device_type, system): return None -def _device_by_name(product_type, device_type, system): +def _device_by_product_type(product_type, device_type, system): for device in system.devices: device_type_match = ( device_type == DeviceType.ANY @@ -152,7 +152,7 @@ def sim_x_series_device(system): @pytest.fixture(scope="function") def sim_6363_device(system): """Gets a simulated 6363.""" - return _device_by_name("PCIe-6363", DeviceType.SIMULATED, system) + return _device_by_product_type("PCIe-6363", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") @@ -238,37 +238,37 @@ def sim_ts_power_devices(sim_ts_chassis): @pytest.fixture(scope="function") def sim_charge_device(system): """Gets a simulated 4480.""" - return _device_by_name("PXIe-4480", DeviceType.SIMULATED, system) + return _device_by_product_type("PXIe-4480", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") def sim_dsa_device(system): """Gets a simulated 4466.""" - return _device_by_name("PXIe-4466", DeviceType.SIMULATED, system) + return _device_by_product_type("PXIe-4466", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") def sim_dmm_device(system): """Gets a simulated myDAQ.""" - return _device_by_name("NI myDAQ", DeviceType.SIMULATED, system) + return _device_by_product_type("NI myDAQ", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") def sim_bridge_device(system): """Gets a simulated 4431.""" - return _device_by_name("PXIe-4331", DeviceType.SIMULATED, system) + return _device_by_product_type("PXIe-4331", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") def sim_position_device(system): """Gets a simulated 4340.""" - return _device_by_name("PXIe-4340", DeviceType.SIMULATED, system) + return _device_by_product_type("PXIe-4340", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") def sim_temperature_device(system): """Gets a simulated 4353.""" - return _device_by_name("PXIe-4353", DeviceType.SIMULATED, system) + return _device_by_product_type("PXIe-4353", DeviceType.SIMULATED, system) @pytest.fixture(scope="function") From cda341098a5a1924b38006690a02187254e3fdbe Mon Sep 17 00:00:00 2001 From: Zach Hindes Date: Fri, 2 Feb 2024 15:13:03 -0600 Subject: [PATCH 4/5] lint --- tests/component/_task_modules/channels/test_ai_channels.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/component/_task_modules/channels/test_ai_channels.py b/tests/component/_task_modules/channels/test_ai_channels.py index cfe65424..ad470b94 100644 --- a/tests/component/_task_modules/channels/test_ai_channels.py +++ b/tests/component/_task_modules/channels/test_ai_channels.py @@ -1,7 +1,5 @@ import pytest -from nidaqmx import Task -from nidaqmx._task_modules.channels.ai_channel import AIChannel from nidaqmx.constants import ( AccelChargeSensitivityUnits, AccelSensitivityUnits, From c536f53627e62a1f1a63074188514900f7fec7ad Mon Sep 17 00:00:00 2001 From: Zach Hindes Date: Fri, 2 Feb 2024 16:19:31 -0600 Subject: [PATCH 5/5] code review --- ...test_ai_channels.py => test_ai_channel.py} | 262 ++++++++++-------- tests/max_config/nidaqmxMaxConfig.ini | 96 ++++--- 2 files changed, 196 insertions(+), 162 deletions(-) rename tests/component/_task_modules/channels/{test_ai_channels.py => test_ai_channel.py} (73%) diff --git a/tests/component/_task_modules/channels/test_ai_channels.py b/tests/component/_task_modules/channels/test_ai_channel.py similarity index 73% rename from tests/component/_task_modules/channels/test_ai_channels.py rename to tests/component/_task_modules/channels/test_ai_channel.py index ad470b94..7ac08125 100644 --- a/tests/component/_task_modules/channels/test_ai_channels.py +++ b/tests/component/_task_modules/channels/test_ai_channel.py @@ -1,5 +1,7 @@ import pytest +from nidaqmx import Task +from nidaqmx._task_modules.channels import AIChannel from nidaqmx.constants import ( AccelChargeSensitivityUnits, AccelSensitivityUnits, @@ -26,6 +28,7 @@ UsageTypeAI, VoltageUnits, ) +from nidaqmx.system import Device # Note: Tests for other channel types will be less complete given that the underlying Python @@ -43,9 +46,9 @@ "units, custom_scale_name", [(VoltageUnits.VOLTS, ""), (VoltageUnits.FROM_CUSTOM_SCALE, "no_scaling_scale")], ) -def test___ai_channel_collection___add_ai_voltage_chan___sets_channel_attributes( - task, - sim_6363_device, +def test___task__add_ai_voltage_chan___sets_channel_attributes( + task: Task, + sim_6363_device: Device, desired_term_config, expected_term_cfg, min_val, @@ -53,7 +56,7 @@ def test___ai_channel_collection___add_ai_voltage_chan___sets_channel_attributes units, custom_scale_name, ): - chan = task.ai_channels.add_ai_voltage_chan( + chan: AIChannel = task.ai_channels.add_ai_voltage_chan( sim_6363_device.ai_physical_chans[0].name, terminal_config=desired_term_config, min_val=min_val, @@ -77,15 +80,16 @@ def test___ai_channel_collection___add_ai_voltage_chan___sets_channel_attributes (AccelUnits.METERS_PER_SECOND_SQUARED, 0.5, AccelSensitivityUnits.VOLTS_PER_G), ], ) -def test___ai_channel_collection___add_ai_accel_4_wire_dc_voltage_chan___sets_channel_attributes( - task, sim_charge_device, units, sensitivity, sensitivity_units +def test___task__add_ai_accel_4_wire_dc_voltage_chan___sets_channel_attributes( + task: Task, sim_charge_device: Device, units, sensitivity, sensitivity_units ): - chan = task.ai_channels.add_ai_accel_4_wire_dc_voltage_chan( + chan: AIChannel = task.ai_channels.add_ai_accel_4_wire_dc_voltage_chan( sim_charge_device.ai_physical_chans[0].name, units=units, sensitivity=sensitivity, sensitivity_units=sensitivity_units, ) + assert chan.ai_meas_type == UsageTypeAI.ACCELERATION_4_WIRE_DC_VOLTAGE assert chan.ai_accel_units == units assert chan.ai_accel_4_wire_dc_voltage_sensitivity == sensitivity @@ -99,10 +103,10 @@ def test___ai_channel_collection___add_ai_accel_4_wire_dc_voltage_chan___sets_ch (AccelUnits.METERS_PER_SECOND_SQUARED, 0.5, AccelSensitivityUnits.VOLTS_PER_G), ], ) -def test___ai_channel_collection___add_ai_accel_chan___sets_channel_attributes( - task, sim_dsa_device, units, sensitivity, sensitivity_units +def test___task__add_ai_accel_chan___sets_channel_attributes( + task: Task, sim_dsa_device: Device, units, sensitivity, sensitivity_units ): - chan = task.ai_channels.add_ai_accel_chan( + chan: AIChannel = task.ai_channels.add_ai_accel_chan( sim_dsa_device.ai_physical_chans[0].name, units=units, sensitivity=sensitivity, @@ -126,10 +130,10 @@ def test___ai_channel_collection___add_ai_accel_chan___sets_channel_attributes( ), ], ) -def test___ai_channel_collection___add_ai_accel_charge_chan___sets_channel_attributes( - task, sim_charge_device, units, sensitivity, sensitivity_units +def test___task__add_ai_accel_charge_chan___sets_channel_attributes( + task: Task, sim_charge_device: Device, units, sensitivity, sensitivity_units ): - chan = task.ai_channels.add_ai_accel_charge_chan( + chan: AIChannel = task.ai_channels.add_ai_accel_charge_chan( sim_charge_device.ai_physical_chans[0].name, units=units, sensitivity=sensitivity, @@ -149,10 +153,10 @@ def test___ai_channel_collection___add_ai_accel_charge_chan___sets_channel_attri (BridgeUnits.MILLIVOLTS_PER_VOLT, BridgeConfiguration.QUARTER_BRIDGE, 120.0), ], ) -def test___ai_channel_collection___add_ai_bridge_chan___sets_channel_attributes( - task, sim_bridge_device, units, bridge_config, nominal_bridge_resistance +def test___task__add_ai_bridge_chan___sets_channel_attributes( + task: Task, sim_bridge_device: Device, units, bridge_config, nominal_bridge_resistance ): - chan = task.ai_channels.add_ai_bridge_chan( + chan: AIChannel = task.ai_channels.add_ai_bridge_chan( sim_bridge_device.ai_physical_chans[0].name, units=units, bridge_config=bridge_config, @@ -166,10 +170,10 @@ def test___ai_channel_collection___add_ai_bridge_chan___sets_channel_attributes( @pytest.mark.parametrize("units", [ChargeUnits.COULOMBS, ChargeUnits.PICO_COULOMBS]) -def test___ai_channel_collection___add_ai_charge_chan___sets_channel_attributes( - task, sim_charge_device, units +def test___task__add_ai_charge_chan___sets_channel_attributes( + task: Task, sim_charge_device: Device, units ): - chan = task.ai_channels.add_ai_charge_chan( + chan: AIChannel = task.ai_channels.add_ai_charge_chan( sim_charge_device.ai_physical_chans[0].name, units=units ) @@ -188,10 +192,14 @@ def test___ai_channel_collection___add_ai_charge_chan___sets_channel_attributes( (CurrentShuntResistorLocation.EXTERNAL, CurrentShuntResistorLocation.EXTERNAL, 99.0), ], ) -def test___ai_channel_collection___add_ai_current_chan___sets_channel_attributes( - task, sim_6363_device, shunt_resistor_loc, expected_shunt_resistor_loc, ext_shunt_resistor_val -): - chan = task.ai_channels.add_ai_current_chan( +def test___task__add_ai_current_chan___sets_channel_attributes( + task: Task, + sim_6363_device: Device, + shunt_resistor_loc, + expected_shunt_resistor_loc, + ext_shunt_resistor_val, +): + chan: AIChannel = task.ai_channels.add_ai_current_chan( sim_6363_device.ai_physical_chans[0].name, shunt_resistor_loc=shunt_resistor_loc, ext_shunt_resistor_val=ext_shunt_resistor_val, @@ -209,16 +217,17 @@ def test___ai_channel_collection___add_ai_current_chan___sets_channel_attributes (CurrentShuntResistorLocation.INTERNAL, CurrentShuntResistorLocation.INTERNAL), ], ) -def test___ai_channel_collection___add_ai_current_rms_chan___sets_channel_attributes( - task, sim_dmm_device, shunt_resistor_loc, expected_shunt_resistor_loc +def test___task__add_ai_current_rms_chan___sets_channel_attributes( + task: Task, sim_dmm_device: Device, shunt_resistor_loc, expected_shunt_resistor_loc ): - chan = task.ai_channels.add_ai_current_rms_chan( + chan: AIChannel = task.ai_channels.add_ai_current_rms_chan( f"{sim_dmm_device.name}/dmm", # dmm is unipolar, defaults don't work min_val=0.0, max_val=1.0, shunt_resistor_loc=shunt_resistor_loc, ) + assert chan.ai_meas_type == UsageTypeAI.CURRENT_ACRMS assert chan.ai_current_shunt_loc == expected_shunt_resistor_loc @@ -230,21 +239,22 @@ def test___ai_channel_collection___add_ai_current_rms_chan___sets_channel_attrib (BridgeConfiguration.QUARTER_BRIDGE, 120.0, [1.0, 2.0], [-0.5, 0.5]), ], ) -def test___ai_channel_collection___add_ai_force_bridge_polynomial_chan___sets_channel_attributes( - task, - sim_bridge_device, +def test___task__add_ai_force_bridge_polynomial_chan___sets_channel_attributes( + task: Task, + sim_bridge_device: Device, bridge_config, nominal_bridge_resistance, forward_coeffs, reverse_coeffs, ): - chan = task.ai_channels.add_ai_force_bridge_polynomial_chan( + chan: AIChannel = task.ai_channels.add_ai_force_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, bridge_config=bridge_config, nominal_bridge_resistance=nominal_bridge_resistance, forward_coeffs=forward_coeffs, reverse_coeffs=reverse_coeffs, ) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE assert chan.ai_bridge_cfg == bridge_config assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance @@ -259,21 +269,22 @@ def test___ai_channel_collection___add_ai_force_bridge_polynomial_chan___sets_ch (BridgeConfiguration.QUARTER_BRIDGE, 120.0, [-2.0, 0.0, 2.0], [-200.0, 0.0, 200.0]), ], ) -def test___ai_channel_collection___add_ai_force_bridge_table_chan___sets_channel_attributes( - task, - sim_bridge_device, +def test___task__add_ai_force_bridge_table_chan___sets_channel_attributes( + task: Task, + sim_bridge_device: Device, bridge_config, nominal_bridge_resistance, electrical_vals, physical_vals, ): - chan = task.ai_channels.add_ai_force_bridge_table_chan( + chan: AIChannel = task.ai_channels.add_ai_force_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, bridge_config=bridge_config, nominal_bridge_resistance=nominal_bridge_resistance, electrical_vals=electrical_vals, physical_vals=physical_vals, ) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE assert chan.ai_bridge_cfg == bridge_config assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance @@ -288,9 +299,9 @@ def test___ai_channel_collection___add_ai_force_bridge_table_chan___sets_channel (BridgeConfiguration.QUARTER_BRIDGE, 120.0, 0.0, 4.0, 0.0, 200.0), ], ) -def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets_channel_attributes( - task, - sim_bridge_device, +def test___task__add_ai_force_bridge_two_point_lin_chan___sets_channel_attributes( + task: Task, + sim_bridge_device: Device, bridge_config, nominal_bridge_resistance, first_electrical_val, @@ -298,7 +309,7 @@ def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets first_physical_val, second_physical_val, ): - chan = task.ai_channels.add_ai_force_bridge_two_point_lin_chan( + chan: AIChannel = task.ai_channels.add_ai_force_bridge_two_point_lin_chan( sim_bridge_device.ai_physical_chans[0].name, bridge_config=bridge_config, nominal_bridge_resistance=nominal_bridge_resistance, @@ -307,6 +318,7 @@ def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets first_physical_val=first_physical_val, second_physical_val=second_physical_val, ) + assert chan.ai_meas_type == UsageTypeAI.FORCE_BRIDGE assert chan.ai_bridge_cfg == bridge_config assert chan.ai_bridge_nom_resistance == nominal_bridge_resistance @@ -323,15 +335,16 @@ def test___ai_channel_collection___add_ai_force_bridge_two_point_lin_chan___sets (ForceUnits.POUNDS, 1.25, ForceIEPESensorSensitivityUnits.MILLIVOLTS_PER_POUND), ], ) -def test___ai_channel_collection___add_ai_force_iepe_chan___sets_channel_attributes( - task, sim_dsa_device, units, sensitivity, sensitivity_units +def test___task__add_ai_force_iepe_chan___sets_channel_attributes( + task: Task, sim_dsa_device: Device, units, sensitivity, sensitivity_units ): - chan = task.ai_channels.add_ai_force_iepe_chan( + chan: AIChannel = task.ai_channels.add_ai_force_iepe_chan( sim_dsa_device.ai_physical_chans[0].name, units=units, sensitivity=sensitivity, sensitivity_units=sensitivity_units, ) + assert chan.ai_meas_type == UsageTypeAI.FORCE_IEPE_SENSOR assert chan.ai_force_units == units assert chan.ai_force_iepe_sensor_sensitivity == sensitivity @@ -348,10 +361,10 @@ def test___ai_channel_collection___add_ai_force_iepe_chan___sets_channel_attribu (10.0, 100.0), ], ) -def test___ai_channel_collection___add_ai_microphone_chan___sets_channel_attributes( - task, sim_dsa_device, mic_sensitivity, max_snd_press_level +def test___task__add_ai_microphone_chan___sets_channel_attributes( + task: Task, sim_dsa_device: Device, mic_sensitivity, max_snd_press_level ): - chan = task.ai_channels.add_ai_microphone_chan( + chan: AIChannel = task.ai_channels.add_ai_microphone_chan( sim_dsa_device.ai_physical_chans[0].name, mic_sensitivity=mic_sensitivity, max_snd_press_level=max_snd_press_level, @@ -369,14 +382,15 @@ def test___ai_channel_collection___add_ai_microphone_chan___sets_channel_attribu (EddyCurrentProxProbeSensitivityUnits.VOLTS_PER_MIL, 0.2), ], ) -def test___ai_channel_collection___add_ai_pos_eddy_curr_prox_probe_chan___sets_channel_attributes( - task, sim_dsa_device, sensitivity_units, sensitivity +def test___task__add_ai_pos_eddy_curr_prox_probe_chan___sets_channel_attributes( + task: Task, sim_dsa_device: Device, sensitivity_units, sensitivity ): - chan = task.ai_channels.add_ai_pos_eddy_curr_prox_probe_chan( + chan: AIChannel = task.ai_channels.add_ai_pos_eddy_curr_prox_probe_chan( sim_dsa_device.ai_physical_chans[0].name, sensitivity_units=sensitivity_units, sensitivity=sensitivity, ) + assert chan.ai_meas_type == UsageTypeAI.POSITION_EDDY_CURRENT_PROX_PROBE assert chan.ai_eddy_current_prox_sensitivity_units == sensitivity_units assert chan.ai_eddy_current_prox_sensitivity == sensitivity @@ -393,16 +407,16 @@ def test___ai_channel_collection___add_ai_pos_eddy_curr_prox_probe_chan___sets_c "ac_excit_wire_mode, voltage_excit_val, voltage_excit_freq", [(ACExcitWireMode.FOUR_WIRE, 1.0, 2500.0), (ACExcitWireMode.FIVE_WIRE, 1.5, 2000.0)], ) -def test___ai_channel_collection___add_ai_pos_lvdt_chan___sets_channel_attributes( - task, - sim_position_device, +def test___task__add_ai_pos_lvdt_chan___sets_channel_attributes( + task: Task, + sim_position_device: Device, sensitivity_units, sensitivity, ac_excit_wire_mode, voltage_excit_val, voltage_excit_freq, ): - chan = task.ai_channels.add_ai_pos_lvdt_chan( + chan: AIChannel = task.ai_channels.add_ai_pos_lvdt_chan( sim_position_device.ai_physical_chans[0].name, sensitivity_units=sensitivity_units, sensitivity=sensitivity, @@ -420,10 +434,11 @@ def test___ai_channel_collection___add_ai_pos_lvdt_chan___sets_channel_attribute # Nothing novel here vs. lvdt channels. -def test___ai_channel_collection___add_ai_pos_rvdt_chan___sets_channel_attributes( - task, sim_position_device -): - chan = task.ai_channels.add_ai_pos_rvdt_chan(sim_position_device.ai_physical_chans[0].name) +def test___task__add_ai_pos_rvdt_chan___sets_channel_attributes(task: Task, sim_position_device): + chan: AIChannel = task.ai_channels.add_ai_pos_rvdt_chan( + sim_position_device.ai_physical_chans[0].name + ) + assert chan.ai_meas_type == UsageTypeAI.POSITION_ANGULAR_RVDT @@ -434,15 +449,16 @@ def test___ai_channel_collection___add_ai_pos_rvdt_chan___sets_channel_attribute (2.5, 1.0, True), ], ) -def test___ai_channel_collection___add_ai_power_chan___sets_channel_attributes( - task, sim_ts_power_device, voltage_setpoint, current_setpoint, output_enable +def test___task__add_ai_power_chan___sets_channel_attributes( + task: Task, sim_ts_power_device: Device, voltage_setpoint, current_setpoint, output_enable ): - chan = task.ai_channels.add_ai_power_chan( + chan: AIChannel = task.ai_channels.add_ai_power_chan( f"{sim_ts_power_device.name}/power", voltage_setpoint=voltage_setpoint, current_setpoint=current_setpoint, output_enable=output_enable, ) + assert chan.ai_meas_type == UsageTypeAI.POWER assert chan.pwr_voltage_setpoint == voltage_setpoint assert chan.pwr_current_setpoint == current_setpoint @@ -450,38 +466,41 @@ def test___ai_channel_collection___add_ai_power_chan___sets_channel_attributes( # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_pressure_bridge_polynomial_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_pressure_bridge_polynomial_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): # #482: Default argument values for bridge create channel functions are unusable - chan = task.ai_channels.add_ai_pressure_bridge_polynomial_chan( + chan: AIChannel = task.ai_channels.add_ai_pressure_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0], ) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_pressure_bridge_table_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_pressure_bridge_table_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): # #482: Default argument values for bridge create channel functions are unusable - chan = task.ai_channels.add_ai_pressure_bridge_table_chan( + chan: AIChannel = task.ai_channels.add_ai_pressure_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0], ) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_pressure_bridge_two_point_lin_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_pressure_bridge_two_point_lin_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): - chan = task.ai_channels.add_ai_pressure_bridge_two_point_lin_chan( + chan: AIChannel = task.ai_channels.add_ai_pressure_bridge_two_point_lin_chan( sim_bridge_device.ai_physical_chans[0].name ) + assert chan.ai_meas_type == UsageTypeAI.PRESSURE_BRIDGE @@ -492,19 +511,20 @@ def test___ai_channel_collection___add_ai_pressure_bridge_two_point_lin_chan___s (ResistanceConfiguration.THREE_WIRE), ], ) -def test___ai_channel_collection___add_ai_resistance_chan___sets_channel_attributes( - task, sim_6363_device, resistance_config +def test___task__add_ai_resistance_chan___sets_channel_attributes( + task: Task, sim_6363_device: Device, resistance_config ): - chan = task.ai_channels.add_ai_resistance_chan( + chan: AIChannel = task.ai_channels.add_ai_resistance_chan( sim_6363_device.ai_physical_chans[0].name, resistance_config=resistance_config ) + assert chan.ai_meas_type == UsageTypeAI.RESISTANCE assert chan.ai_resistance_cfg == resistance_config # Rosette is very complicated, so I'm not parametrizing this test. -def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_rosette_strain_gage_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): # #483: add_ai_rosette_strain_gage_chan parameter rosette_meas_types has the wrong type task.ai_channels.add_ai_rosette_strain_gage_chan( @@ -513,7 +533,7 @@ def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_channe 0.0, [StrainGageRosetteMeasurementType.PRINCIPAL_STRAIN_1.value], ) - chan = task.ai_channels["rosette0_principalStrain1"] + chan: AIChannel = task.ai_channels["rosette0_principalStrain1"] assert chan.ai_meas_type == UsageTypeAI.ROSETTE_STRAIN_GAGE @@ -524,14 +544,15 @@ def test___ai_channel_collection___add_ai_rosette_strain_gage_chan___sets_channe (RTDType.PT_3851, ResistanceConfiguration.THREE_WIRE), ], ) -def test___ai_channel_collection___add_ai_rtd_chan___sets_channel_attributes( - task, sim_6363_device, rtd_type, resistance_config +def test___task__add_ai_rtd_chan___sets_channel_attributes( + task: Task, sim_6363_device: Device, rtd_type, resistance_config ): - chan = task.ai_channels.add_ai_rtd_chan( + chan: AIChannel = task.ai_channels.add_ai_rtd_chan( sim_6363_device.ai_physical_chans[0].name, rtd_type=rtd_type, resistance_config=resistance_config, ) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_RTD assert chan.ai_rtd_type == rtd_type assert chan.ai_resistance_cfg == resistance_config @@ -544,27 +565,29 @@ def test___ai_channel_collection___add_ai_rtd_chan___sets_channel_attributes( (StrainGageBridgeType.QUARTER_BRIDGE_I, 1.1, 120.0), ], ) -def test___ai_channel_collection___add_ai_strain_gage_chan___sets_channel_attributes( - task, sim_bridge_device, strain_config, gage_factor, nominal_gage_resistance +def test___task__add_ai_strain_gage_chan___sets_channel_attributes( + task: Task, sim_bridge_device: Device, strain_config, gage_factor, nominal_gage_resistance ): - chan = task.ai_channels.add_ai_strain_gage_chan( + chan: AIChannel = task.ai_channels.add_ai_strain_gage_chan( sim_bridge_device.ai_physical_chans[0].name, strain_config=strain_config, gage_factor=gage_factor, nominal_gage_resistance=nominal_gage_resistance, ) + assert chan.ai_meas_type == UsageTypeAI.STRAIN_STRAIN_GAGE assert chan.ai_strain_gage_cfg == strain_config assert chan.ai_strain_gage_gage_factor == gage_factor assert chan.ai_bridge_nom_resistance == nominal_gage_resistance -def test___ai_channel_collection___add_ai_temp_built_in_sensor_chan___sets_channel_attributes( - task, sim_6363_device +def test___task__add_ai_temp_built_in_sensor_chan___sets_channel_attributes( + task: Task, sim_6363_device ): - chan = task.ai_channels.add_ai_temp_built_in_sensor_chan( + chan: AIChannel = task.ai_channels.add_ai_temp_built_in_sensor_chan( f"{sim_6363_device.name}/_boardTempSensor_vs_aignd" ) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_BUILT_IN_SENSOR @@ -575,15 +598,16 @@ def test___ai_channel_collection___add_ai_temp_built_in_sensor_chan___sets_chann (ThermocoupleType.K, CJCSource.BUILT_IN, 0.0), ], ) -def test___ai_channel_collection___add_ai_thrmcpl_chan___sets_channel_attributes( - task, sim_temperature_device, thermocouple_type, cjc_source, cjc_val +def test___task__add_ai_thrmcpl_chan___sets_channel_attributes( + task: Task, sim_temperature_device: Device, thermocouple_type, cjc_source, cjc_val ): - chan = task.ai_channels.add_ai_thrmcpl_chan( + chan: AIChannel = task.ai_channels.add_ai_thrmcpl_chan( sim_temperature_device.ai_physical_chans[0].name, thermocouple_type=thermocouple_type, cjc_source=cjc_source, cjc_val=cjc_val, ) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMOCOUPLE assert chan.ai_thrmcpl_type == thermocouple_type assert chan.ai_thrmcpl_cjc_src == cjc_source @@ -597,16 +621,17 @@ def test___ai_channel_collection___add_ai_thrmcpl_chan___sets_channel_attributes (ResistanceConfiguration.FOUR_WIRE, 0.2, 0.3, 0.4), ], ) -def test___ai_channel_collection___add_ai_thrmstr_chan_iex___sets_channel_attributes( - task, sim_6363_device, resistance_config, a, b, c +def test___task__add_ai_thrmstr_chan_iex___sets_channel_attributes( + task: Task, sim_6363_device: Device, resistance_config, a, b, c ): - chan = task.ai_channels.add_ai_thrmstr_chan_iex( + chan: AIChannel = task.ai_channels.add_ai_thrmstr_chan_iex( sim_6363_device.ai_physical_chans[0].name, resistance_config=resistance_config, a=a, b=b, c=c, ) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR assert chan.ai_resistance_cfg == resistance_config assert chan.ai_thrmstr_a == a @@ -621,100 +646,105 @@ def test___ai_channel_collection___add_ai_thrmstr_chan_iex___sets_channel_attrib (TemperatureUnits.DEG_F, ResistanceConfiguration.FOUR_WIRE), ], ) -def test___ai_channel_collection___add_ai_thrmstr_chan_vex___sets_channel_attributes( - task, sim_6363_device, units, resistance_config +def test___task__add_ai_thrmstr_chan_vex___sets_channel_attributes( + task: Task, sim_6363_device: Device, units, resistance_config ): - chan = task.ai_channels.add_ai_thrmstr_chan_vex( + chan: AIChannel = task.ai_channels.add_ai_thrmstr_chan_vex( sim_6363_device.ai_physical_chans[0].name, units=units, resistance_config=resistance_config ) + assert chan.ai_meas_type == UsageTypeAI.TEMPERATURE_THERMISTOR assert chan.ai_temp_units == units assert chan.ai_resistance_cfg == resistance_config # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_torque_bridge_polynomial_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_torque_bridge_polynomial_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): # #482: Default argument values for bridge create channel functions are unusable - chan = task.ai_channels.add_ai_torque_bridge_polynomial_chan( + chan: AIChannel = task.ai_channels.add_ai_torque_bridge_polynomial_chan( sim_bridge_device.ai_physical_chans[0].name, forward_coeffs=[0.0, 1.0], reverse_coeffs=[0.0, 1.0], ) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_torque_bridge_table_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_torque_bridge_table_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): # #482: Default argument values for bridge create channel functions are unusable - chan = task.ai_channels.add_ai_torque_bridge_table_chan( + chan: AIChannel = task.ai_channels.add_ai_torque_bridge_table_chan( sim_bridge_device.ai_physical_chans[0].name, electrical_vals=[-1.0, 0.0, 1.0], physical_vals=[-100.0, 0.0, 100.0], ) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE # Nothing novel here vs. other bridge-based channels. -def test___ai_channel_collection___add_ai_torque_bridge_two_point_lin_chan___sets_channel_attributes( - task, sim_bridge_device +def test___task__add_ai_torque_bridge_two_point_lin_chan___sets_channel_attributes( + task: Task, sim_bridge_device ): - chan = task.ai_channels.add_ai_torque_bridge_two_point_lin_chan( + chan: AIChannel = task.ai_channels.add_ai_torque_bridge_two_point_lin_chan( sim_bridge_device.ai_physical_chans[0].name ) + assert chan.ai_meas_type == UsageTypeAI.TORQUE_BRIDGE # Nothing novel here vs. other iepe channels. -def test___ai_channel_collection___add_ai_velocity_iepe_chan___sets_channel_attributes( - task, sim_dsa_device -): - chan = task.ai_channels.add_ai_velocity_iepe_chan(sim_dsa_device.ai_physical_chans[0].name) +def test___task__add_ai_velocity_iepe_chan___sets_channel_attributes(task: Task, sim_dsa_device): + chan: AIChannel = task.ai_channels.add_ai_velocity_iepe_chan( + sim_dsa_device.ai_physical_chans[0].name + ) + assert chan.ai_meas_type == UsageTypeAI.VELOCITY_IEPE_SENSOR @pytest.mark.parametrize( - "min_val, max_val, bridge_config, voltage_exict_source, voltage_excit_val, use_excit_for_scaling", + "min_val, max_val, bridge_config, voltage_excit_source, voltage_excit_val, use_excit_for_scaling", [ (-10.0, 10.0, BridgeConfiguration.FULL_BRIDGE, ExcitationSource.EXTERNAL, 5.0, False), (-2.0, 2.0, BridgeConfiguration.HALF_BRIDGE, ExcitationSource.EXTERNAL, 5.0, True), ], ) -def test___ai_channel_collection___add_ai_voltage_chan_with_excit___sets_channel_attributes( - task, - sim_6363_device, +def test___task__add_ai_voltage_chan_with_excit___sets_channel_attributes( + task: Task, + sim_6363_device: Device, min_val, max_val, bridge_config, - voltage_exict_source, + voltage_excit_source, voltage_excit_val, use_excit_for_scaling, ): - chan = task.ai_channels.add_ai_voltage_chan_with_excit( + chan: AIChannel = task.ai_channels.add_ai_voltage_chan_with_excit( sim_6363_device.ai_physical_chans[0].name, min_val=min_val, max_val=max_val, bridge_config=bridge_config, - voltage_excit_source=voltage_exict_source, + voltage_excit_source=voltage_excit_source, voltage_excit_val=voltage_excit_val, use_excit_for_scaling=use_excit_for_scaling, ) + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_CUSTOM_WITH_EXCITATION assert chan.ai_min == min_val assert chan.ai_max == max_val assert chan.ai_bridge_cfg == bridge_config - assert chan.ai_excit_src == voltage_exict_source + assert chan.ai_excit_src == voltage_excit_source assert chan.ai_excit_val == voltage_excit_val assert chan.ai_excit_use_for_scaling == use_excit_for_scaling -def test___ai_channel_collection___add_ai_voltage_rms_chan___sets_channel_attributes( - task, sim_dmm_device -): - chan = task.ai_channels.add_ai_voltage_rms_chan( +def test___task__add_ai_voltage_rms_chan___sets_channel_attributes(task: Task, sim_dmm_device): + chan: AIChannel = task.ai_channels.add_ai_voltage_rms_chan( f"{sim_dmm_device.name}/dmm", min_val=0.0, max_val=1.0 ) + assert chan.ai_meas_type == UsageTypeAI.VOLTAGE_ACRMS diff --git a/tests/max_config/nidaqmxMaxConfig.ini b/tests/max_config/nidaqmxMaxConfig.ini index e9c55666..3f94bc30 100644 --- a/tests/max_config/nidaqmxMaxConfig.ini +++ b/tests/max_config/nidaqmxMaxConfig.ini @@ -2,28 +2,6 @@ MajorVersion = 21 MinorVersion = 8 -[DAQmxChannel VoltageTesterChannel] -AI.MeasType = Voltage -AI.Voltage.Units = Volts -AI.TermCfg = Differential -AI.Max = 10 -AI.Min = -10 -ChanType = Analog Input -PhysicalChanName = tsVoltageTester1/ai0 -Descr = -Author = Test Author - -[DAQmxChannel VoltageTesterChannel2] -AI.MeasType = Voltage -AI.Voltage.Units = Volts -AI.TermCfg = Differential -AI.Max = 5 -AI.Min = -5 -ChanType = Analog Input -PhysicalChanName = tsVoltageTester1/ai1 -Descr = Another channel -Author = Another Test Author - [DAQmxChannel AOTesterTask/VoltageOut_0] AO.OutputType = Voltage AO.Voltage.Units = Volts @@ -51,15 +29,6 @@ ChanType = Analog Output AO.TermCfg = Differential PhysicalChanName = aoTester/ao2 -[DAQmxChannel VoltageTesterTask/Voltage_0] -AI.MeasType = Voltage -AI.Voltage.Units = Volts -AI.TermCfg = Differential -AI.Max = 10 -AI.Min = -10 -ChanType = Analog Input -PhysicalChanName = tsVoltageTester1/ai0 - [DAQmxTask AOTesterTask] Channels = AOTesterTask/VoltageOut_0, AOTesterTask/VoltageOut_1, AOTesterTask/VoltageOut_2 SampQuant.SampMode = Finite Samples @@ -68,7 +37,40 @@ SampQuant.SampPerChan = 100 SampClk.Rate = 1000 SampTimingType = Sample Clock RegenMode = Allow Regeneration -SampClk.Src = +SampClk.Src = + +[DAQmxChannel VoltageTesterChannel] +AI.MeasType = Voltage +AI.Voltage.Units = Volts +AI.TermCfg = Differential +AI.Max = 10 +AI.Min = -10 +ChanType = Analog Input +PhysicalChanName = tsVoltageTester1/ai0 +Descr = +Author = "Test Author" +AllowInteractiveEditing = True + +[DAQmxChannel VoltageTesterChannel2] +AI.MeasType = Voltage +AI.Voltage.Units = Volts +AI.TermCfg = Differential +AI.Max = 5 +AI.Min = -5 +ChanType = Analog Input +PhysicalChanName = tsVoltageTester1/ai1 +Descr = "Another channel" +Author = "Another Test Author" +AllowInteractiveEditing = True + +[DAQmxChannel VoltageTesterTask/Voltage_0] +AI.MeasType = Voltage +AI.Voltage.Units = Volts +AI.TermCfg = Differential +AI.Max = 10 +AI.Min = -10 +ChanType = Analog Input +PhysicalChanName = tsVoltageTester1/ai0 [DAQmxTask VoltageTesterTask] Channels = VoltageTesterTask/Voltage_0 @@ -79,15 +81,17 @@ SampClk.Rate = 1000 SampTimingType = Sample Clock SampClk.Src = Author = Test Author +AllowInteractiveEditing = True [DAQmxScale double_gain_scale] -Descr = Twice the gain Lin.Slope = 2 Lin.YIntercept = 0 PreScaledUnits = Volts ScaledUnits = ScaleType = Linear Author = Test Author +AllowInteractiveEditing = True +Descr = Twice the gain [DAQmxScale no_scaling_scale] Lin.Slope = 1 @@ -121,6 +125,8 @@ BusType = PXIe PXI.ChassisNum = 1 PXI.SlotNum = 2 +[DAQmxAccessory RM-24999_A/bridgeTester/0] + [DAQmxDevice chargeTester] ProductType = PXIe-4480 DevSerialNum = 0x0 @@ -200,19 +206,6 @@ BusType = PXIe PXI.ChassisNum = 1 PXI.SlotNum = 7 -[DAQmxAccessory RM-24999_A/bridgeTester/0] - -[DAQmxCDAQChassis cdaqChassisTester] -ProductType = cDAQ-9185 -DevSerialNum = 0x0 -DevIsSimulated = 1 -BusType = TCP/IP -TCPIP.Hostname = -TCPIP.EthernetIP = 0.0.0.0 -TCPIP.EthernetMAC = 00:00:00:00:00:00 -TCPIP.EthernetMDNSServiceInstance = -TCPIP.DevIsReserved = 0 - [DAQmxCDAQChassis tsChassisTester] ProductType = TS-15000 DevSerialNum = 0x0 @@ -239,3 +232,14 @@ DevIsSimulated = 1 CompactDAQ.ChassisDevName = tsChassisTester CompactDAQ.SlotNum = 3 +[DAQmxCDAQChassis cdaqChassisTester] +ProductType = cDAQ-9185 +DevSerialNum = 0x0 +DevIsSimulated = 1 +BusType = TCP/IP +TCPIP.Hostname = +TCPIP.EthernetIP = 0.0.0.0 +TCPIP.EthernetMAC = 00:00:00:00:00:00 +TCPIP.EthernetMDNSServiceInstance = +TCPIP.DevIsReserved = 0 +