Coverage for C:\Users\hjanssen\HOME\pyCharmProjects\ethz_hvl\hvl_ccb\hvl_ccb\_dev\labjack.py: 87%

# Coverage for C:\Users\hjanssen\HOME\pyCharmProjects\ethz_hvl\hvl_ccb\hvl_ccb\_dev\labjack.py : 87%

## 61 statements

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1# Copyright (c) 2019-2020 ETH Zurich, SIS ID and HVL D-ITET

2#

3"""LabJack device utilities."""

4 from __future__ import annotations

5

6 import warnings

7 from typing import Dict, Iterable, List, Union

8

9 from aenum import EnumMeta

10 from labjack.ljm import constants

11

12 from ..utils.enum import AutoNumberNameEnum, NameEnum

13

14

15 class TSeriesDIOChannel(NameEnum):

16 """

17 Digital Input/Output (DIO) addresses for various LabJack devices from T-Series.

18

19 NOTE: not all DIO addresses are available on all devices. This is defined as

20 `dio` attribute of `LabJackDeviceType`.

21 """

22

23 FIO0 = 0

24 FIO1 = 1

25 FIO2 = 2

26 FIO3 = 3

27 FIO4 = 4

28 FIO5 = 5

29 FIO6 = 6

30 FIO7 = 7

31 EIO0 = 8

32 EIO1 = 9

33 EIO2 = 10

34 EIO3 = 11

35 EIO4 = 12

36 EIO5 = 13

37 EIO6 = 14

38 EIO7 = 15

39 CIO0 = 16

40 CIO1 = 17

41 CIO2 = 18

42 CIO3 = 19

43 MIO0 = 20

44 MIO1 = 21

45 MIO2 = 22

46

47

48 def _build_p_id_lookup_dict(

49 lab_jack_device_types: Iterable["DeviceType"],

50) -> Dict[int, List]:

51 """

52 Build lookup dictionary of `DeviceType` instances based on their `p_id`. Note:

53 `p_id` is not unique for each device type.

54

55 :param lab_jack_device_types: `DeviceType` instances to iterate over

56 :return: `int`-based lookup dictionary

57 """

58 ret: Dict[int, List] = dict()

59 for lab_jack_device_type in lab_jack_device_types:

60 if lab_jack_device_type.p_id not in ret:

61 ret[lab_jack_device_type.p_id] = list()

62 ret[lab_jack_device_type.p_id].append(lab_jack_device_type)

63 return ret

64

65

66# NOTE: super metaclass has to match metaclass of `super(DeviceType)`!

67 class DeviceTypeMeta(EnumMeta):

68 def __new__(metacls, clsname, bases, clsdict, **kwargs):

69 cls = EnumMeta.__new__(

70 metacls, clsname, bases, clsdict, **kwargs

71 )

72 cls._get_by_p_id = _build_p_id_lookup_dict(cls)

73 return cls

74

75

76 class AmbiguousProductIdWarning(UserWarning):

77 pass

78

79

80 class DeviceType(AutoNumberNameEnum, metaclass=DeviceTypeMeta):

81 """

82 LabJack device types.

83

84 Can be also looked up by ambigious Product ID (`p_id`) or by instance name:

85 ```python

86 LabJackDeviceType(4) is LabJackDeviceType('T4')

87 ```

88 """

89

90 _init_ = "value p_id type_str ain_max_resolution dio"

91 ANY = (), constants.dtANY, "ANY", 0, ()

92 T4 = (), constants.dtT4, "T4", 4, (

93 TSeriesDIOChannel.FIO4,

94 TSeriesDIOChannel.FIO5,

95 TSeriesDIOChannel.FIO6,

96 TSeriesDIOChannel.FIO7,

97 TSeriesDIOChannel.EIO0,

98 TSeriesDIOChannel.EIO1,

99 TSeriesDIOChannel.EIO2,

100 TSeriesDIOChannel.EIO3,

101 TSeriesDIOChannel.EIO4,

102 TSeriesDIOChannel.EIO5,

103 TSeriesDIOChannel.EIO6,

104 TSeriesDIOChannel.EIO7,

105 TSeriesDIOChannel.CIO0,

106 TSeriesDIOChannel.CIO1,

107 TSeriesDIOChannel.CIO2,

108 TSeriesDIOChannel.CIO3,

109 )

110 T7 = (), constants.dtT7, "T7", 8, (

111 TSeriesDIOChannel.FIO0,

112 TSeriesDIOChannel.FIO1,

113 TSeriesDIOChannel.FIO2,

114 TSeriesDIOChannel.FIO3,

115 TSeriesDIOChannel.FIO4,

116 TSeriesDIOChannel.FIO5,

117 TSeriesDIOChannel.FIO6,

118 TSeriesDIOChannel.FIO7,

119 TSeriesDIOChannel.EIO0,

120 TSeriesDIOChannel.EIO1,

121 TSeriesDIOChannel.EIO2,

122 TSeriesDIOChannel.EIO3,

123 TSeriesDIOChannel.EIO4,

124 TSeriesDIOChannel.EIO5,

125 TSeriesDIOChannel.EIO6,

126 TSeriesDIOChannel.EIO7,

127 TSeriesDIOChannel.CIO0,

128 TSeriesDIOChannel.CIO1,

129 TSeriesDIOChannel.CIO2,

130 TSeriesDIOChannel.CIO3,

131 TSeriesDIOChannel.MIO0,

132 TSeriesDIOChannel.MIO1,

133 TSeriesDIOChannel.MIO2,

134 )

135 T7_PRO = (), constants.dtT7, "T7", 12, (

136 TSeriesDIOChannel.FIO0,

137 TSeriesDIOChannel.FIO1,

138 TSeriesDIOChannel.FIO2,

139 TSeriesDIOChannel.FIO3,

140 TSeriesDIOChannel.FIO4,

141 TSeriesDIOChannel.FIO5,

142 TSeriesDIOChannel.FIO6,

143 TSeriesDIOChannel.FIO7,

144 TSeriesDIOChannel.EIO0,

145 TSeriesDIOChannel.EIO1,

146 TSeriesDIOChannel.EIO2,

147 TSeriesDIOChannel.EIO3,

148 TSeriesDIOChannel.EIO4,

149 TSeriesDIOChannel.EIO5,

150 TSeriesDIOChannel.EIO6,

151 TSeriesDIOChannel.EIO7,

152 TSeriesDIOChannel.CIO0,

153 TSeriesDIOChannel.CIO1,

154 TSeriesDIOChannel.CIO2,

155 TSeriesDIOChannel.CIO3,

156 TSeriesDIOChannel.MIO0,

157 TSeriesDIOChannel.MIO1,

158 TSeriesDIOChannel.MIO2,

159 )

160 # DIGIT = (), constants.dtDIGIT, 'DIGIT', 0, ()

161 # SERIES = (), constants.dtTSERIES, 'SERIES', 0, ()

162

163 @classmethod

164 def get_by_p_id(cls, p_id: int) -> Union[DeviceType, List[DeviceType]]:

165 """

166 Get LabJack device type instance via LabJack product ID.

167

168 Note: Product ID is not unambiguous for LabJack devices.

169

170 :param p_id: Product ID of a LabJack device

171 :return: Instance or list of instances of `LabJackDeviceType`

172 :raises ValueError: when Product ID is unknown

173 """

174 instances_list = cls._get_by_p_id.get(p_id)

175 if instances_list is None:

176 raise ValueError(f"Unknown LabJack Product ID: {p_id}")

177 if len(instances_list) > 1:

178 warnings.warn(

179 f"Product ID {p_id} matches multiple device types: "

180 f"{', '.join(instance.name for instance in instances_list)}.",

181 AmbiguousProductIdWarning,

182 )

183 ret = instances_list

184 else:

185 ret = instances_list[0]

186 return ret