To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit 7984da4f authored by mikolajr's avatar mikolajr
Browse files

In Labjack device: enable AInRange lookup w/ str repr of float and dual repr...

In Labjack device: enable AInRange lookup w/ str repr of float and dual repr input args for methods using either AInRange or DIOStatus
parent 723c5fa7
......@@ -15,15 +15,15 @@ from __future__ import annotations
import logging
from collections.abc import Sequence
from numbers import Real
from typing import Union, Tuple, Optional, List
from aenum import Enum, IntEnum
# from typing_extensions import Literal # in `typing` only since Py 3.8
from .._dev import labjack
from ..comm import LJMCommunication
from ..dev import SingleCommDevice
from ..utils.enum import NameEnum
from ..utils.enum import NameEnum, StrEnumBase
class LabJackError(Exception):
......@@ -119,11 +119,19 @@ class LabJack(SingleCommDevice):
return float(self.com.read_name(f"SBUS{number}_RH"))
class AInRange(Enum):
TEN = 10
ONE = 1
ONE_TENTH = 0.1
ONE_HUNDREDTH = 0.01
class AInRange(StrEnumBase):
_init_ = "value_str"
TEN = "10"
ONE = "1"
ONE_TENTH = "0.1"
ONE_HUNDREDTH = "0.01"
def __str__(self) -> str:
return self.value_str
@property
def value(self) -> float:
return float(self.value_str)
def get_ain(self, *channels: int) -> Union[float, Tuple[float, ...]]:
"""
......@@ -142,17 +150,15 @@ class LabJack(SingleCommDevice):
return tuple(float(val) for val in ret_val)
return float(ret_val)
def set_ain_range(self, channel: int, ain_range: AInRange) -> None:
def set_ain_range(self, channel: int, vrange: Union[Real, AInRange]) -> None:
"""
Set the range of an analog input port.
:param channel: is the AIN number (0..254)
:param ain_range: is the range specifier
:param vrange: is the voltage range to be set
"""
if not isinstance(ain_range, self.AInRange):
raise LabJackError(f"Not supported type: {ain_range}")
self.com.write_name(f"AIN{channel}_RANGE", ain_range.value)
vrange = self.AInRange(str(vrange))
self.com.write_name(f"AIN{channel}_RANGE", vrange.value)
def set_ain_resolution(self, channel: int, resolution: int) -> None:
"""
......@@ -242,7 +248,7 @@ class LabJack(SingleCommDevice):
cjc_type: Union[str, CjcType] = (
CjcType.internal # type: ignore
),
vrange: AInRange = (
vrange: Union[Real, AInRange] = (
AInRange.ONE_HUNDREDTH # type: ignore
),
resolution: int = 10,
......@@ -270,6 +276,10 @@ class LabJack(SingleCommDevice):
thermocouple = self.ThermocoupleType(thermocouple)
# validate separately from `set_ain_range` to fail before any write happens
# (in `set_ain_differential` first)
vrange = self.AInRange(str(vrange))
unit = self.TemperatureUnit(unit)
cjc_type = self.CjcType(cjc_type)
......@@ -306,21 +316,27 @@ class LabJack(SingleCommDevice):
return round(self.com.read_name(f"AIN{pos_channel}_EF_READ_A"), 2)
class DIOStatus(IntEnum):
"""
State of a digital I/O channel.
"""
LOW = 0
HIGH = 1
def set_digital_output(self, address: str, state: DIOStatus) -> None:
def set_digital_output(self, address: str, state: Union[int, DIOStatus]) -> None:
"""
Set the value of a digital output.
:param address: name of the output -> 'FIO0'
:param state: state of the output -> HIGH or LOW
:param address: name of the output -> `'FIO0'`
:param state: state of the output -> `DIOStatus` instance or corresponding `int`
value
"""
dt = self.get_product_type()
if address not in (
dt.dio # type: ignore
):
raise LabJackIdentifierDIOError
state = self.DIOStatus(state)
self.com.write_name(address, state)
DIOChannel = labjack.TSeriesDIOChannel
......@@ -345,10 +361,11 @@ class LabJack(SingleCommDevice):
raise LabJackIdentifierDIOError(
f"DIO {address.name} is not available for this device type: {dt_name}."
)
ret = int(self.com.read_name(address.name))
if ret == 0 or ret == 1:
try:
ret = int(self.com.read_name(address.name))
return self.DIOStatus(ret)
raise LabJackIdentifierDIOError(f"Expected 0 or 1 return value, got {ret}.")
except ValueError:
raise LabJackIdentifierDIOError(f"Expected 0 or 1 return value, got {ret}.")
class CalMicroAmpere(Enum):
"""
......@@ -432,8 +449,9 @@ class LabJack(SingleCommDevice):
"""
return self.get_product_type(force_query_id=force_query_id).name
def set_ain_resistance(self, channel: int, vrange: AInRange,
resolution: int) -> None:
def set_ain_resistance(
self, channel: int, vrange: Union[Real, AInRange], resolution: int
) -> None:
"""
Set the specified channel to resistance mode. It utilized the 200uA current
source of the LabJack.
......
......@@ -95,7 +95,7 @@ def test_set_ain_range(started_dev_comm):
lj.set_ain_range(0, lj.AInRange.ONE_TENTH)
assert com.get_written() == ("AIN0_RANGE", 0.1)
with pytest.raises(LabJackError):
with pytest.raises(ValueError):
lj.set_ain_range(0, 0.2)
assert com.get_written() is None
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment