tinkerforge-async 1.5.0__py3-none-any.whl → 1.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
1
  # pylint: disable=missing-module-docstring
2
- __version__ = "1.5.0"
2
+ __version__ = "1.5.2"
@@ -33,6 +33,8 @@ class CallbackID(Enum):
33
33
  SENSOR_CONNECTED = 24
34
34
 
35
35
 
36
+ # We need the alias for MyPy type hinting
37
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
36
38
  _CallbackID = CallbackID
37
39
 
38
40
 
@@ -73,13 +75,15 @@ class LineFilter(Enum):
73
75
  FREQUENCY_60HZ = 1
74
76
 
75
77
 
76
- _LineFilter = LineFilter # We need the alias for MyPy type hinting
78
+ # We need the alias for MyPy type hinting
79
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
80
+ _LineFilter = LineFilter
77
81
 
78
82
 
79
83
  @unique
80
84
  class WireMode(Enum):
81
85
  """
82
- Select the measurement setup. Use 3 or wires to eliminate most/all of the
86
+ Select the measurement setup. Use 3 or 4 wires to eliminate most/all the
83
87
  resistance of the wire. Use 3 or 4 wire setups when using PT100 and long
84
88
  cables.
85
89
  """
@@ -89,7 +93,9 @@ class WireMode(Enum):
89
93
  WIRE_4 = 4
90
94
 
91
95
 
92
- _WireMode = WireMode # We need the alias for MyPy type hinting
96
+ # We need the alias for MyPy type hinting
97
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
98
+ _WireMode = WireMode
93
99
 
94
100
 
95
101
  @unique
@@ -102,6 +108,8 @@ class SensorType(Enum):
102
108
  PT_1000 = 1
103
109
 
104
110
 
111
+ # We need the alias for MyPy type hinting
112
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
105
113
  _SensorType = SensorType
106
114
 
107
115
 
@@ -30,6 +30,8 @@ class CallbackID(Enum):
30
30
  SENSOR_CONNECTED = 18
31
31
 
32
32
 
33
+ # We need the alias for MyPy type hinting
34
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
33
35
  _CallbackID = CallbackID
34
36
 
35
37
 
@@ -67,7 +69,9 @@ class LineFilter(Enum):
67
69
  FREQUENCY_60HZ = 1
68
70
 
69
71
 
70
- _LineFilter = LineFilter # We need the alias for MyPy type hinting
72
+ # We need the alias for MyPy type hinting
73
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
74
+ _LineFilter = LineFilter
71
75
 
72
76
 
73
77
  @unique
@@ -82,6 +86,8 @@ class WireMode(Enum):
82
86
  WIRE_4 = 4
83
87
 
84
88
 
89
+ # We need the alias for MyPy type hinting
90
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
85
91
  _WireMode = WireMode # We need the alias for MyPy type hinting
86
92
 
87
93
 
@@ -95,7 +101,9 @@ class SensorType(Enum):
95
101
  PT_1000 = 1
96
102
 
97
103
 
98
- _SensorType = SensorType # We need the alias for MyPy type hinting
104
+ # We need the alias for MyPy type hinting
105
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
106
+ _SensorType = SensorType
99
107
 
100
108
 
101
109
  class GetMovingAverageConfiguration(NamedTuple):
@@ -0,0 +1,419 @@
1
+ """
2
+ Module for the Tinkerforge Thermocouple Bricklet 2.0
3
+ (https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermocouple_V2.html) implemented using Python asyncio. It does
4
+ the low-level communication with the Tinkerforge ip connection and also handles conversion of raw units to SI units.
5
+ """
6
+ # pylint: disable=duplicate-code # Many sensors of different generations have a similar API
7
+ from __future__ import annotations
8
+
9
+ from decimal import Decimal
10
+ from enum import Enum, unique
11
+ from typing import TYPE_CHECKING, AsyncGenerator, NamedTuple
12
+
13
+ from .devices import AdvancedCallbackConfiguration, BrickletWithMCU, DeviceIdentifier, Event
14
+ from .devices import ThresholdOption as Threshold
15
+ from .devices import _FunctionID
16
+ from .ip_connection_helper import pack_payload, unpack_payload
17
+
18
+ if TYPE_CHECKING:
19
+ from .ip_connection import IPConnectionAsync
20
+
21
+
22
+ @unique
23
+ class CallbackID(Enum):
24
+ """
25
+ The callbacks available to this bricklet
26
+ """
27
+
28
+ TEMPERATURE = 4
29
+ ERROR_STATE = 8
30
+
31
+
32
+ # We need the alias for MyPy type hinting
33
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
34
+ _CallbackID = CallbackID
35
+
36
+
37
+ @unique
38
+ class FunctionID(_FunctionID):
39
+ """
40
+ The function calls available to this bricklet
41
+ """
42
+
43
+ GET_TEMPERATURE = 1
44
+ SET_TEMPERATURE_CALLBACK_CONFIGURATION = 2
45
+ GET_TEMPERATURE_CALLBACK_CONFIGURATION = 3
46
+ SET_CONFIGURATION = 5
47
+ GET_CONFIGURATION = 6
48
+ GET_ERROR_STATE = 7
49
+
50
+
51
+ @unique
52
+ class Averaging(Enum):
53
+ """
54
+ The number of values averaged before returning the measurement result.
55
+ """
56
+
57
+ AVERAGING_1 = 1
58
+ AVERAGING_2 = 2
59
+ AVERAGING_4 = 4
60
+ AVERAGING_8 = 8
61
+ AVERAGING_16 = 16
62
+
63
+
64
+ # We need the alias for MyPy type hinting
65
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
66
+ _Averaging = Averaging
67
+
68
+
69
+ @unique
70
+ class SensorType(Enum):
71
+ """
72
+ The type of thermocouple connected to the bricklet.
73
+ """
74
+
75
+ TYPE_B = 0
76
+ TYPE_E = 1
77
+ TYPE_J = 2
78
+ TYPE_K = 3
79
+ TYPE_N = 4
80
+ TYPE_R = 5
81
+ TYPE_S = 6
82
+ TYPE_T = 7
83
+ TYPE_G8 = 8
84
+ TYPE_G32 = 9
85
+
86
+
87
+ # We need the alias for MyPy type hinting
88
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
89
+ _SensorType = SensorType
90
+
91
+
92
+ class LineFilter(Enum):
93
+ """
94
+ Selects the notch filter to filter out the mains frequency hum
95
+ """
96
+
97
+ FREQUENCY_50HZ = 0
98
+ FREQUENCY_60HZ = 1
99
+
100
+
101
+ # We need the alias for MyPy type hinting
102
+ # See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
103
+ _LineFilter = LineFilter
104
+
105
+
106
+ class GetConfiguration(NamedTuple):
107
+ averaging: Averaging
108
+ sensor_type: SensorType
109
+ filter: LineFilter
110
+
111
+
112
+ class GetErrorState(NamedTuple):
113
+ """
114
+ Tuple that contains the error states of the system. Over-/undervoltage indicates either a voltage above 3.3 V or
115
+ below 0 V and likely a defective thermocouple. An open circuit indicates a missing or defective thermocouple.
116
+ """
117
+
118
+ over_under: bool
119
+ open_circuit: bool
120
+
121
+
122
+ class BrickletThermocoupleV2(BrickletWithMCU):
123
+ """
124
+ Measures temperature with a thermocouple.
125
+ """
126
+
127
+ DEVICE_IDENTIFIER = DeviceIdentifier.BRICKLET_THERMOCOUPLE_V2
128
+ DEVICE_DISPLAY_NAME = "Thermocouple Bricklet 2.0"
129
+
130
+ # Convenience imports, so that the user does not need to additionally import them
131
+ CallbackID = CallbackID
132
+ FunctionID = FunctionID
133
+ ThresholdOption = Threshold
134
+ Averaging = Averaging
135
+ SensorType = SensorType
136
+ LineFilter = LineFilter
137
+
138
+ CALLBACK_FORMATS = {CallbackID.TEMPERATURE: "i", CallbackID.ERROR_STATE: "! !"}
139
+
140
+ SID_TO_CALLBACK = {
141
+ 0: (CallbackID.TEMPERATURE,),
142
+ 1: (CallbackID.ERROR_STATE,),
143
+ }
144
+
145
+ @property
146
+ def sensor_type(self) -> _SensorType:
147
+ """
148
+ Return the type of sensor. Either PT100 oder PT1000 as a SensorType enum.
149
+ """
150
+ return self.__sensor_type
151
+
152
+ @sensor_type.setter
153
+ def sensor_type(self, value: _SensorType):
154
+ if not isinstance(value, SensorType):
155
+ self.__sensor_type: SensorType = SensorType(value)
156
+ else:
157
+ self.__sensor_type = value
158
+
159
+ def __init__(self, uid, ipcon: IPConnectionAsync, sensor_type: _SensorType = SensorType.TYPE_K) -> None:
160
+ """
161
+ Creates an object with the unique device ID *uid* and adds it to
162
+ the IP Connection *ipcon*.
163
+ """
164
+ super().__init__(self.DEVICE_DISPLAY_NAME, uid, ipcon)
165
+
166
+ self.api_version = (2, 0, 0)
167
+ self.sensor_type = sensor_type # Use the setter to automatically convert to enum
168
+
169
+ def __repr__(self) -> str:
170
+ return (
171
+ f"{self.__class__.__module__}.{self.__class__.__qualname__}"
172
+ f"(uid={self.uid}, ipcon={self.ipcon!r}, sensor_type={self.sensor_type})"
173
+ )
174
+
175
+ async def get_value(self, sid: int) -> Decimal | GetErrorState:
176
+ assert sid in (0, 1)
177
+
178
+ if sid == 0:
179
+ return await self.get_temperature()
180
+ if sid == 1:
181
+ return await self.get_error_state()
182
+ raise ValueError(f"Invalid sid: {sid}. sid must be in (0, 1).")
183
+
184
+ async def set_callback_configuration( # pylint: disable=too-many-arguments
185
+ self,
186
+ sid: int,
187
+ period: int = 0,
188
+ value_has_to_change: bool = False,
189
+ option: Threshold | int = Threshold.OFF,
190
+ minimum: float | Decimal | None = None,
191
+ maximum: float | Decimal | None = None,
192
+ response_expected: bool = True,
193
+ ) -> None:
194
+ minimum = Decimal("273.15") if minimum is None else minimum
195
+ maximum = Decimal("273.15") if maximum is None else maximum
196
+
197
+ if sid == 0:
198
+ await self.set_temperature_callback_configuration(
199
+ period, value_has_to_change, option, minimum, maximum, response_expected
200
+ )
201
+ else:
202
+ raise ValueError(f"Invalid sid: {sid}. sid must be in (0, ).")
203
+
204
+ async def get_callback_configuration(self, sid: int) -> AdvancedCallbackConfiguration:
205
+ if sid == 0:
206
+ return await self.get_temperature_callback_configuration()
207
+
208
+ raise ValueError(f"Invalid sid: {sid}. sid must be in (0, ).")
209
+
210
+ async def get_temperature(self) -> Decimal:
211
+ """
212
+ Returns the temperature of the thermocouple. The value is given in °C/100,
213
+ e.g. a value of 4223 means that a temperature of 42.23 °C is measured.
214
+
215
+ If you want to get the temperature periodically, it is recommended
216
+ to use the :cb:`Temperature` callback and set the period with
217
+ :func:`Set Temperature Callback Configuration`.
218
+
219
+ If you want to get the value periodically, it is recommended to use the
220
+ :cb:`Temperature` callback. You can set the callback configuration
221
+ with :func:`Set Temperature Callback Configuration`.
222
+ """
223
+ _, payload = await self.ipcon.send_request(
224
+ device=self, function_id=FunctionID.GET_TEMPERATURE, response_expected=True
225
+ )
226
+ return self.__value_to_si(unpack_payload(payload, "i"))
227
+
228
+ async def set_temperature_callback_configuration( # pylint: disable=too-many-arguments
229
+ self,
230
+ period: int = 0,
231
+ value_has_to_change: bool = False,
232
+ option: Threshold | int = Threshold.OFF,
233
+ minimum: Decimal | int | float = Decimal("273.15"),
234
+ maximum: Decimal | int | float = Decimal("273.15"),
235
+ response_expected=True,
236
+ ) -> None:
237
+ """
238
+ The period is the period with which the :cb:`Temperature` callback is triggered
239
+ periodically. A value of 0 turns the callback off.
240
+
241
+ If the `value has to change`-parameter is set to true, the callback is only
242
+ triggered after the value has changed. If the value didn't change
243
+ within the period, the callback is triggered immediately on change.
244
+
245
+ If it is set to false, the callback is continuously triggered with the period,
246
+ independent of the value.
247
+
248
+ It is furthermore possible to constrain the callback with thresholds.
249
+
250
+ The `option`-parameter together with min/max sets a threshold for the :cb:`Temperature` callback.
251
+
252
+ The following options are possible:
253
+
254
+ .. csv-table::
255
+ :header: "Option", "Description"
256
+ :widths: 10, 100
257
+
258
+ "'x'", "Threshold is turned off"
259
+ "'o'", "Threshold is triggered when the value is *outside* the min and max values"
260
+ "'i'", "Threshold is triggered when the value is *inside* or equal to the min and max values"
261
+ "'<'", "Threshold is triggered when the value is smaller than the min value (max is ignored)"
262
+ "'>'", "Threshold is triggered when the value is greater than the min value (max is ignored)"
263
+
264
+ If the option is set to 'x' (threshold turned off) the callback is triggered with the fixed period.
265
+ """
266
+ if not isinstance(option, Threshold):
267
+ option = Threshold(option)
268
+ assert period >= 0
269
+
270
+ await self.ipcon.send_request(
271
+ device=self,
272
+ function_id=FunctionID.SET_TEMPERATURE_CALLBACK_CONFIGURATION,
273
+ data=pack_payload(
274
+ (
275
+ int(period),
276
+ bool(value_has_to_change),
277
+ option.value.encode("ascii"),
278
+ self.__si_to_value(minimum),
279
+ self.__si_to_value(maximum),
280
+ ),
281
+ "I ! c i i",
282
+ ),
283
+ response_expected=response_expected,
284
+ )
285
+
286
+ async def get_temperature_callback_configuration(self) -> AdvancedCallbackConfiguration:
287
+ """
288
+ Returns the callback configuration as set by :func:`Set Temperature Callback Configuration`.
289
+ """
290
+ _, payload = await self.ipcon.send_request(
291
+ device=self, function_id=FunctionID.GET_TEMPERATURE_CALLBACK_CONFIGURATION, response_expected=True
292
+ )
293
+ period, value_has_to_change, option, minimum, maximum = unpack_payload(payload, "I ! c i i")
294
+ option = Threshold(option)
295
+ minimum, maximum = self.__value_to_si(minimum), self.__value_to_si(maximum)
296
+ return AdvancedCallbackConfiguration(period, value_has_to_change, option, minimum, maximum)
297
+
298
+ async def set_configuration(
299
+ self,
300
+ averaging: _Averaging = Averaging.AVERAGING_16,
301
+ sensor_type: _SensorType = SensorType.TYPE_K,
302
+ line_filter: _LineFilter = LineFilter.FREQUENCY_50HZ,
303
+ response_expected: bool = True,
304
+ ) -> None:
305
+ """
306
+ You can configure averaging size, thermocouple type and frequency
307
+ filtering.
308
+
309
+ Available averaging sizes are 1, 2, 4, 8 and 16 samples.
310
+
311
+ As thermocouple type you can use B, E, J, K, N, R, S and T. If you have a
312
+ different thermocouple or a custom thermocouple you can also use
313
+ G8 and G32. With these types the returned value will not be in °C/100,
314
+ it will be calculated by the following formulas:
315
+
316
+ * G8: ``value = 8 * 1.6 * 2^17 * Vin``
317
+ * G32: ``value = 32 * 1.6 * 2^17 * Vin``
318
+
319
+ where Vin is the thermocouple input voltage.
320
+
321
+ The frequency filter can be either configured to 50Hz or to 60Hz. You should
322
+ configure it according to your utility frequency.
323
+
324
+ The conversion time depends on the averaging and filter configuration, it can
325
+ be calculated as follows:
326
+
327
+ * 60Hz: ``time = 82 + (samples - 1) * 16.67``
328
+ * 50Hz: ``time = 98 + (samples - 1) * 20``
329
+ """
330
+ if not isinstance(averaging, Averaging):
331
+ averaging = Averaging(averaging)
332
+ if not isinstance(sensor_type, SensorType):
333
+ sensor_type = SensorType(sensor_type)
334
+ if not isinstance(line_filter, LineFilter):
335
+ line_filter = LineFilter(line_filter)
336
+
337
+ self.__sensor_type = sensor_type
338
+ await self.ipcon.send_request(
339
+ device=self,
340
+ function_id=FunctionID.SET_CONFIGURATION,
341
+ data=pack_payload((averaging.value, sensor_type.value, line_filter.value), "B B B"),
342
+ response_expected=response_expected,
343
+ )
344
+
345
+ async def get_configuration(self) -> GetConfiguration:
346
+ _, payload = await self.ipcon.send_request(
347
+ device=self, function_id=FunctionID.GET_CONFIGURATION, response_expected=True
348
+ )
349
+
350
+ averaging, sensor_type, line_filter = unpack_payload(payload, "B B B")
351
+ return GetConfiguration(Averaging(averaging), SensorType(sensor_type), LineFilter(line_filter))
352
+
353
+ async def get_error_state(self) -> GetErrorState:
354
+ """
355
+ Returns the current error state. There are two possible errors:
356
+
357
+ * Over/Under Voltage and
358
+ * Open Circuit.
359
+
360
+ Over/Under Voltage happens for voltages below 0V or above 3.3V. In this case
361
+ it is very likely that your thermocouple is defective. An Open Circuit error
362
+ indicates that there is no thermocouple connected.
363
+
364
+ You can use the :cb:`Error State` callback to automatically get triggered
365
+ when the error state changes.
366
+ """
367
+ _, payload = await self.ipcon.send_request(
368
+ device=self, function_id=FunctionID.GET_ERROR_STATE, response_expected=True
369
+ )
370
+
371
+ over_under, open_circuit = unpack_payload(payload, "! !")
372
+ return GetErrorState(over_under, open_circuit)
373
+
374
+ def __value_to_si(self, value: int) -> Decimal:
375
+ """
376
+ Convert to the sensor value to SI units
377
+ """
378
+ if self.__sensor_type is SensorType.TYPE_G8:
379
+ return Decimal(value / 8 / 1.6 / 2**17)
380
+ if self.__sensor_type is SensorType.TYPE_G32:
381
+ return Decimal(value / 8 / 1.6 / 2**17)
382
+ return Decimal(value + 27315) / 100
383
+
384
+ def __si_to_value(self, value: float | Decimal) -> int:
385
+ if self.__sensor_type is SensorType.TYPE_G8:
386
+ return int(float(value) * 8 * 1.6 * 2**17)
387
+ if self.__sensor_type is SensorType.TYPE_G32:
388
+ return int(float(value) * 8 * 1.6 * 2**17)
389
+ return int(value * 100) - 27315
390
+
391
+ async def read_events(
392
+ self,
393
+ events: tuple[int | _CallbackID, ...] | list[int | _CallbackID] | None = None,
394
+ sids: tuple[int, ...] | list[int] | None = None,
395
+ ) -> AsyncGenerator[Event, None]:
396
+ registered_events = set()
397
+ if events:
398
+ for event in events:
399
+ registered_events.add(self.CallbackID(event))
400
+ if sids is not None:
401
+ for sid in sids:
402
+ for callback in self.SID_TO_CALLBACK.get(sid, []):
403
+ registered_events.add(callback)
404
+
405
+ if events is None and sids is None:
406
+ registered_events = set(self.CALLBACK_FORMATS.keys())
407
+
408
+ async for header, payload in super()._read_events():
409
+ try:
410
+ function_id = CallbackID(header.function_id)
411
+ except ValueError:
412
+ # Invalid header. Drop the packet.
413
+ continue
414
+ if function_id in registered_events:
415
+ value = unpack_payload(payload, self.CALLBACK_FORMATS[function_id])
416
+ if function_id is CallbackID.TEMPERATURE:
417
+ yield Event(self, 0, function_id, self.__value_to_si(value))
418
+ else:
419
+ yield Event(self, 1, function_id, value)
@@ -28,6 +28,7 @@ from .bricklet_segment_display_4x7 import BrickletSegmentDisplay4x7
28
28
  from .bricklet_segment_display_4x7_v2 import BrickletSegmentDisplay4x7V2
29
29
  from .bricklet_temperature import BrickletTemperature
30
30
  from .bricklet_temperature_v2 import BrickletTemperatureV2
31
+ from .bricklet_thermocouple_v2 import BrickletThermocoupleV2
31
32
 
32
33
  if TYPE_CHECKING:
33
34
  from . import IPConnectionAsync
@@ -83,3 +84,4 @@ device_factory.register(BrickletSegmentDisplay4x7V2)
83
84
  device_factory.register(BrickletRS232V2)
84
85
  device_factory.register(BrickletTemperature)
85
86
  device_factory.register(BrickletTemperatureV2)
87
+ device_factory.register(BrickletThermocoupleV2)
@@ -56,6 +56,7 @@ class DeviceIdentifier(Enum):
56
56
  BRICKLET_MOTION_DETECTOR_V2 = 292
57
57
  BRICKLET_PTC_V2 = 2101
58
58
  BRICKLET_RS232_V2 = 2108
59
+ BRICKLET_THERMOCOUPLE_V2 = 2109
59
60
  BRICKLET_IO_4_V2 = 2111
60
61
  BRICKLET_TEMPERATURE_V2 = 2113
61
62
  BRICKLET_BAROMETER_V2 = 2117
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinkerforge_async
3
- Version: 1.5.0
3
+ Version: 1.5.2
4
4
  Summary: Python3 AsyncIO Tinkerforge driver
5
5
  Author-email: Patrick Baus <patrick.baus@physik.tu-darmstadt.de>
6
6
  License: GNU General Public License v3 (GPLv3)
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.8
14
14
  Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Development Status :: 5 - Production/Stable
18
19
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
19
20
  Classifier: Operating System :: OS Independent
@@ -42,6 +43,7 @@ Provides-Extra: test
42
43
  Requires-Dist: mypy ; extra == 'test'
43
44
  Requires-Dist: pylint ; extra == 'test'
44
45
  Requires-Dist: pytest ; extra == 'test'
46
+ Requires-Dist: setuptools ; extra == 'test'
45
47
 
46
48
  [![pylint](../../actions/workflows/pylint.yml/badge.svg)](../../actions/workflows/pylint.yml)
47
49
  [![PyPI](https://img.shields.io/pypi/v/tinkerforge-async)](https://pypi.org/project/tinkerforge-async/)
@@ -84,6 +86,7 @@ The library is fully type-hinted.
84
86
  | [Segment Display 4x7 2.0](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Segment_Display_4x7_V2.html) |:heavy_check_mark:|:heavy_check_mark:|
85
87
  | [Temperature](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Temperature.html) |:heavy_check_mark:|:heavy_check_mark:|
86
88
  | [Temperature 2.0](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Temperature_V2.html) |:heavy_check_mark:|:heavy_check_mark:|
89
+ | [Thermocouple 2.0](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermocouple_V2.html) |:heavy_check_mark:|:heavy_check_mark:|
87
90
 
88
91
  ## Documentation
89
92
  The documentation is currently work in progress. The full documentation will be moved to
@@ -203,6 +206,11 @@ Some design choices of the original Tinkerforge API are overly complex. I theref
203
206
  - `BrickletPtcV2()` takes an additional parameter to define the type of sensor. The options are `BrickletPtc.SensorType.PT_100` and `BrickletPtc.SensorType.PT_1000`. This only determines the resistance returned by the bricklet. The default is `BrickletPtc.SensorType.PT_100`.
204
207
  - `BrickletPtcV2.sensor_type` getter and setter to change the type of sensor used.
205
208
 
209
+ - ### [Thermocouple Bricklet 2.0](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermocouple_V2.html)
210
+ - `BrickletThermocoupleV2()` takes an additional parameter to define the type of sensor. The options are of type `BrickletThermocoupleV2.SensorType`. The default is `BrickletPtc.SensorType.TYPE_K`.
211
+ - `BrickletThermocoupleV2.sensor_type` getter and setter to change the type of sensor used.
212
+
213
+
206
214
  - ### [Segment Display 4x7 Bricklet 2.0](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Segment_Display_4x7_V2.html)
207
215
  - `BrickletSegmentDisplay4x7V2.set_segments()` takes a `list`/`tuple` of 4 `int` instead of digit0, digit1, digit2, digit3. This is the same API as the older [Segment Display 4x7 Bricklet](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Segment_Display_4x7.html).
208
216
 
@@ -1,5 +1,5 @@
1
1
  tinkerforge_async/__init__.py,sha256=wv8UTQrY0vlHwJEO-50PAeUt1cnrAdtSW-2by3CtaaE,376
2
- tinkerforge_async/_version.py,sha256=8tv365RSIevo4FRLjkkw8YGADkX0majxQJmFFD8Qffw,65
2
+ tinkerforge_async/_version.py,sha256=UqJ3HNCU2vsgoUrCIWF8t4wsYLyCQGZJ4mOgfolgaoU,65
3
3
  tinkerforge_async/async_event_bus.py,sha256=Ng1bNw4tfPZUSMBudy47rTxLqJF96qpTEJIzh1MCq44,1806
4
4
  tinkerforge_async/brick_master.py,sha256=kZDN_FzuYmGjaZvYFI2ba2Sfv1mwGoFx9ZayH1DJGqI,129607
5
5
  tinkerforge_async/bricklet_ambient_light_v2.py,sha256=6OVxGK8kBU_ZcRXa9iJH_B8GbZ74XGBB5ix7WquS8yw,13402
@@ -16,19 +16,20 @@ tinkerforge_async/bricklet_io4_v2.py,sha256=GYb2N44jVV_hvijJ_YPx2Vf0Td-oJzGNT53g
16
16
  tinkerforge_async/bricklet_isolator.py,sha256=miTYcDMzY6gQ8lNU8ZS6vcPs0HDr8JrJ0y1J7nKsJHs,11159
17
17
  tinkerforge_async/bricklet_moisture.py,sha256=ICnnwPAcWmFcOL73OGWYlLlnAxsr_g7RUe6eZUNDR5I,10078
18
18
  tinkerforge_async/bricklet_motion_detector_v2.py,sha256=nCbYQd4staw62_mYcUVF1qBhzG_04y0jbzXGOyLXcWQ,6451
19
- tinkerforge_async/bricklet_ptc.py,sha256=QU4AwystKH4m0lrOLLHTIWHfUhF0s9HDVEI7me3EGyA,21722
20
- tinkerforge_async/bricklet_ptc_v2.py,sha256=BuKfBh6kzYC-yeP1JCXnT3rtLSXCD8czt02f5a9gjE8,22210
19
+ tinkerforge_async/bricklet_ptc.py,sha256=6tuVQvJVmM3LuRrvFJdDIXiNt-ArLeHQJkIqYuekqRY,22159
20
+ tinkerforge_async/bricklet_ptc_v2.py,sha256=tsH3e_Ppi7XQvhXzQclLxdubw8aZwSnkB0mPHaAsRUo,22648
21
21
  tinkerforge_async/bricklet_rs232_v2.py,sha256=fsZ6SS5ZwJFUrQhXcKatvAki6Vni-ozz58zpri65ZRc,18053
22
22
  tinkerforge_async/bricklet_segment_display_4x7.py,sha256=kl_ctg86w2-uPhEgiraSbtIDS0PH854_9LdA48xrBiQ,6404
23
23
  tinkerforge_async/bricklet_segment_display_4x7_v2.py,sha256=T5g-voFLtLAOyWKn_TNuKDJVaG5vi_7eVCNvkE5ziIs,8902
24
24
  tinkerforge_async/bricklet_temperature.py,sha256=wsaI5vq50d7X_FonRZfxpjtNOVM8tdqA74MPVrts8h4,11341
25
25
  tinkerforge_async/bricklet_temperature_v2.py,sha256=uYSnfW1Hr1WxY5M7kVahtpaQEK5XvdIhM_HhdJdSc-g,9702
26
- tinkerforge_async/device_factory.py,sha256=tkJFlzR87hrUjItGqzKiA5x5m9qsBeD6E7bS5QeNIVs,3260
27
- tinkerforge_async/devices.py,sha256=qPltGqMM4-zv0AfxytoG4N2jriC9NmYKQwg7kOtl8OY,15598
26
+ tinkerforge_async/bricklet_thermocouple_v2.py,sha256=KoVu6E3ZpXqR2aLMktepZVD86q0CQFYlGxUmBkVZO7o,15245
27
+ tinkerforge_async/device_factory.py,sha256=UkK8mU-UN3bBPI9Z8kRpbUslxwGbUiGglFnGRyg6c9o,3369
28
+ tinkerforge_async/devices.py,sha256=XQezaYuiH25MX8rD7sVMdfERYhDlvUg8x1jhj3xNsKI,15634
28
29
  tinkerforge_async/ip_connection.py,sha256=KPAFGTysuCj8uVWMgVUDvP_zPOpjeYOKVb16SDLRcjE,27671
29
30
  tinkerforge_async/ip_connection_helper.py,sha256=kt4JhONMxJdN4upIpVZlqTKmQcSyG2zXkmnCC2QL91Y,4305
30
- tinkerforge_async-1.5.0.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
31
- tinkerforge_async-1.5.0.dist-info/METADATA,sha256=foukM9LXZmljOpWsdG4JBLiDDfNasRrooHVoHPovho4,16033
32
- tinkerforge_async-1.5.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
33
- tinkerforge_async-1.5.0.dist-info/top_level.txt,sha256=YuYlWDVtbFvjqm-GoyH2asasmmn-lH1KeKBBtA17QJ4,18
34
- tinkerforge_async-1.5.0.dist-info/RECORD,,
31
+ tinkerforge_async-1.5.2.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
32
+ tinkerforge_async-1.5.2.dist-info/METADATA,sha256=eUWus5K4ai4ueovreuHwyyy4TrTtBrBplXbE22D_C2w,16699
33
+ tinkerforge_async-1.5.2.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
34
+ tinkerforge_async-1.5.2.dist-info/top_level.txt,sha256=YuYlWDVtbFvjqm-GoyH2asasmmn-lH1KeKBBtA17QJ4,18
35
+ tinkerforge_async-1.5.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5