Skip to content

Commit

Permalink
Extended the labjack T7 support to include the T4, T7-Pro and T8.
Browse files Browse the repository at this point in the history
  • Loading branch information
canismarko committed Nov 21, 2023
1 parent fefb403 commit 626d98c
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 22 deletions.
74 changes: 52 additions & 22 deletions apstools/devices/labjack.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Ophyd definitions for Labjack T-series data acquisition devices.
Currently this is limited to the Labjack T7.
Currently this is limited to the Labjack T4, T7, T7-Pro, and T8.
These devices are based on the v3.0.0 EPICS module. The EPICS IOC
database changed significantly from v2 to v3 when the module was
Expand Down Expand Up @@ -185,26 +185,6 @@ class T7Digitizer(WaveformDigitizer):
offset_1 = Cpt(EpicsSignal, "WaveGenOffset1", kind=Kind.config) # config


class LabJackBase(Device):
"""A labjack T-series data acquisition unit (DAQ).
"""

model_name = Cpt(EpicsSignal, "ModelName", kind=Kind.config)
firmware_version = Cpt(EpicsSignal, "FirmwareVersion", kind=Kind.config)
serial_number = Cpt(EpicsSignal, "SerialNumber", kind=Kind.config)
device_temperature = Cpt(EpicsSignal, "DeviceTemperature", kind=Kind.config)
ljm_version = Cpt(EpicsSignal, "LJMVersion", kind=Kind.config)
driver_version = Cpt(EpicsSignal, "DriverVersion", kind=Kind.config)
last_error_message = Cpt(EpicsSignal, "LastErrorMessage", kind=Kind.config)
poll_sleep_ms = Cpt(EpicsSignal, "PollSleepMS", kind=Kind.config)
poll_time_ms = Cpt(EpicsSignal, "PollTimeMS", kind=Kind.omitted)
analog_in_settling_time_all = Cpt(EpicsSignal, "AiAllSettlingUS", kind=Kind.config)
analog_in_resolution_all = Cpt(EpicsSignal, "AiAllResolution", kind=Kind.config)
analog_in_sampling_rate = Cpt(EpicsSignal, "AiSamplingRate", kind=Kind.config)
device_reset = Cpt(EpicsSignal, "DeviceReset", kind=Kind.omitted)
waveform_generator = Cpt(WaveformGenerator, "")


def make_analog_inputs(num_ais: int):
"""Create a dictionary with analog input device definitions.
Expand Down Expand Up @@ -263,12 +243,62 @@ def make_digital_ios(num_dios: int):
return defn


class LabJackBase(Device):
"""A labjack T-series data acquisition unit (DAQ).
"""

model_name = Cpt(EpicsSignal, "ModelName", kind=Kind.config)
firmware_version = Cpt(EpicsSignal, "FirmwareVersion", kind=Kind.config)
serial_number = Cpt(EpicsSignal, "SerialNumber", kind=Kind.config)
device_temperature = Cpt(EpicsSignal, "DeviceTemperature", kind=Kind.config)
ljm_version = Cpt(EpicsSignal, "LJMVersion", kind=Kind.config)
driver_version = Cpt(EpicsSignal, "DriverVersion", kind=Kind.config)
last_error_message = Cpt(EpicsSignal, "LastErrorMessage", kind=Kind.config)
poll_sleep_ms = Cpt(EpicsSignal, "PollSleepMS", kind=Kind.config)
poll_time_ms = Cpt(EpicsSignal, "PollTimeMS", kind=Kind.omitted)
analog_in_settling_time_all = Cpt(EpicsSignal, "AiAllSettlingUS", kind=Kind.config)
analog_in_resolution_all = Cpt(EpicsSignal, "AiAllResolution", kind=Kind.config)
analog_in_sampling_rate = Cpt(EpicsSignal, "AiSamplingRate", kind=Kind.config)
device_reset = Cpt(EpicsSignal, "DeviceReset", kind=Kind.omitted)

# Common sub-devices (all labjacks have 2 analog outputs)
# NB: Analog inputs/digital I/Os are on a per-model basis
analog_outputs = DCpt(make_analog_outputs(2), kind=(Kind.config | Kind.normal))
waveform_generator = Cpt(WaveformGenerator, "")


class LabJackT4(LabJackBase):
class WaveformDigitizer(WaveformDigitizer):
waveforms = DCpt(make_digitizer_waveforms(12), kind="normal")

analog_inputs = DCpt(make_analog_inputs(12), kind=(Kind.config | Kind.normal))
digital_ios = DCpt(make_digital_ios(16), kind=(Kind.config | Kind.normal))
waveform_digitizer = Cpt(WaveformDigitizer, "")


class LabJackT7(LabJackBase):
class WaveformDigitizer(WaveformDigitizer):
waveforms = DCpt(make_digitizer_waveforms(14), kind="normal")

analog_inputs = DCpt(make_analog_inputs(14), kind=(Kind.config | Kind.normal))
analog_outputs = DCpt(make_analog_outputs(2), kind=(Kind.config | Kind.normal))
digital_ios = DCpt(make_digital_ios(23), kind=(Kind.config | Kind.normal))
waveform_digitizer = Cpt(WaveformDigitizer, "")

class LabJackT7Pro(LabJackBase):
class WaveformDigitizer(WaveformDigitizer):
waveforms = DCpt(make_digitizer_waveforms(14), kind="normal")

analog_inputs = DCpt(make_analog_inputs(14), kind=(Kind.config | Kind.normal))
digital_ios = DCpt(make_digital_ios(23), kind=(Kind.config | Kind.normal))
waveform_digitizer = Cpt(WaveformDigitizer, "")


class LabJackT8(LabJackBase):
class WaveformDigitizer(WaveformDigitizer):
waveforms = DCpt(make_digitizer_waveforms(8), kind="normal")

analog_inputs = DCpt(make_analog_inputs(8), kind=(Kind.config | Kind.normal))
digital_ios = DCpt(make_digital_ios(20), kind=(Kind.config | Kind.normal))
waveform_digitizer = Cpt(WaveformDigitizer, "")

52 changes: 52 additions & 0 deletions apstools/devices/tests/test_labjack.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,41 @@ def test_base_signals_device():
'waveform_generator.type_1',
'waveform_generator.user_waveform_0',
'waveform_generator.user_waveform_1',
'analog_outputs',
'analog_outputs.ao0',
'analog_outputs.ao0.alarm_severity',
'analog_outputs.ao0.alarm_status',
'analog_outputs.ao0.description',
'analog_outputs.ao0.desired_output_location',
'analog_outputs.ao0.device_type',
'analog_outputs.ao0.disable_alarm_severity',
'analog_outputs.ao0.disable_value',
'analog_outputs.ao0.forward_link',
'analog_outputs.ao0.new_alarm_severity',
'analog_outputs.ao0.new_alarm_status',
'analog_outputs.ao0.output_link',
'analog_outputs.ao0.output_mode_select',
'analog_outputs.ao0.raw_value',
'analog_outputs.ao0.scan_disable_input_link_value',
'analog_outputs.ao0.scan_disable_value_input_link',
'analog_outputs.ao0.scanning_rate',
'analog_outputs.ao1',
'analog_outputs.ao1.alarm_severity',
'analog_outputs.ao1.alarm_status',
'analog_outputs.ao1.description',
'analog_outputs.ao1.desired_output_location',
'analog_outputs.ao1.device_type',
'analog_outputs.ao1.disable_alarm_severity',
'analog_outputs.ao1.disable_value',
'analog_outputs.ao1.forward_link',
'analog_outputs.ao1.new_alarm_severity',
'analog_outputs.ao1.new_alarm_status',
'analog_outputs.ao1.output_link',
'analog_outputs.ao1.output_mode_select',
'analog_outputs.ao1.raw_value',
'analog_outputs.ao1.scan_disable_input_link_value',
'analog_outputs.ao1.scan_disable_value_input_link',
'analog_outputs.ao1.scanning_rate',
]
assert sorted(t7.configuration_attrs) == sorted(cfg_names)

Expand All @@ -66,7 +101,11 @@ def test_base_signals_device():


ai_params = [
# (model, number of analog inputs)
(labjack.LabJackT4, 12),
(labjack.LabJackT7, 14),
(labjack.LabJackT7Pro, 14),
(labjack.LabJackT8, 8),
]


Expand All @@ -81,6 +120,8 @@ def test_analog_inputs(LabJackDevice, num_ais):
assert hasattr(device.analog_inputs, f"ai{n}")
ai = getattr(device.analog_inputs, f"ai{n}")
assert isinstance(ai, labjack.AnalogInput)
# Make sure there aren't any extra analog inputs
assert not hasattr(device.analog_inputs, f"ai{num_ais}")
# Check read attrs
read_attrs = ["final_value"]
for n in range(num_ais):
Expand All @@ -96,10 +137,15 @@ def test_analog_inputs(LabJackDevice, num_ais):


ao_params = [
# (model, number of analog outputs)
(labjack.LabJackT4, 2),
(labjack.LabJackT7, 2),
(labjack.LabJackT7Pro, 2),
(labjack.LabJackT8, 2),
]



@pytest.mark.parametrize("LabJackDevice,num_aos", ao_params)
def test_analog_outputs(LabJackDevice, num_aos):
"""Test analog inputs for different device types."""
Expand Down Expand Up @@ -132,7 +178,11 @@ def test_analog_outputs(LabJackDevice, num_aos):


dio_params = [
# (model, number of digital I/Os)
(labjack.LabJackT4, 16),
(labjack.LabJackT7, 23),
(labjack.LabJackT7Pro, 23),
(labjack.LabJackT8, 20),
]


Expand Down Expand Up @@ -209,6 +259,8 @@ def test_waveform_digitizer_waveforms(LabJackDevice, num_ais):
for n in range(num_ais):
assert hasattr(digitizer.waveforms, f"wf{n}")
assert f"waveform_digitizer.waveforms.wf{n}" in device.read_attrs
# Check that no extra waveform signals were created
assert not hasattr(digitizer.waveforms, f"wf{num_ais}")


def test_waveform_generator():
Expand Down

0 comments on commit 626d98c

Please sign in to comment.