Hide keyboard shortcuts

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.""" 

4from __future__ import annotations 

5 

6import warnings 

7from typing import Dict, Iterable, List, Union 

8 

9from aenum import EnumMeta 

10from labjack.ljm import constants 

11 

12from ..utils.enum import AutoNumberNameEnum, NameEnum 

13 

14 

15class 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 

48def _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)`! 

67class 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 

76class AmbiguousProductIdWarning(UserWarning): 

77 pass 

78 

79 

80class 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