ruuvitag-sensor 2.3.0__tar.gz → 3.1.0__tar.gz

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.

Potentially problematic release.


This version of ruuvitag-sensor might be problematic. Click here for more details.

Files changed (38) hide show
  1. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/PKG-INFO +206 -117
  2. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/README.md +196 -103
  3. ruuvitag_sensor-3.1.0/pyproject.toml +92 -0
  4. ruuvitag_sensor-3.1.0/ruuvitag_sensor/__init__.py +3 -0
  5. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/__main__.py +1 -1
  6. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/__init__.py +26 -20
  7. ruuvitag_sensor-3.1.0/ruuvitag_sensor/adapters/bleak_ble.py +262 -0
  8. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/bleson.py +6 -7
  9. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/development/dev_bleak_scanner.py +0 -2
  10. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/nix_hci.py +5 -8
  11. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/nix_hci_file.py +3 -1
  12. ruuvitag_sensor-3.1.0/ruuvitag_sensor/adapters/utils.py +2 -0
  13. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/data_formats.py +3 -4
  14. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/decoder.py +133 -1
  15. ruuvitag_sensor-3.1.0/ruuvitag_sensor/log.py +44 -0
  16. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi.py +131 -34
  17. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi_rx.py +13 -9
  18. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi_types.py +8 -6
  19. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/PKG-INFO +207 -118
  20. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/SOURCES.txt +1 -0
  21. ruuvitag_sensor-3.1.0/ruuvitag_sensor.egg-info/requires.txt +11 -0
  22. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_data_formats.py +0 -2
  23. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_decoder.py +94 -1
  24. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_ruuvitag_sensor.py +0 -2
  25. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_ruuvitag_sensor_async.py +2 -10
  26. ruuvitag_sensor-2.3.0/pyproject.toml +0 -89
  27. ruuvitag_sensor-2.3.0/ruuvitag_sensor/__init__.py +0 -8
  28. ruuvitag_sensor-2.3.0/ruuvitag_sensor/adapters/bleak_ble.py +0 -111
  29. ruuvitag_sensor-2.3.0/ruuvitag_sensor/log.py +0 -27
  30. ruuvitag_sensor-2.3.0/ruuvitag_sensor.egg-info/requires.txt +0 -20
  31. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/LICENSE +0 -0
  32. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/MANIFEST.in +0 -0
  33. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/development/__init__.py +0 -0
  34. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/dummy.py +0 -0
  35. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvitag.py +0 -0
  36. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/dependency_links.txt +0 -0
  37. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/top_level.txt +0 -0
  38. {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ruuvitag_sensor
3
- Version: 2.3.0
3
+ Version: 3.1.0
4
4
  Summary: Find RuuviTag sensors and get decoded data from selected sensors
5
5
  Author-email: Tomi Tuhkanen <tomi.tuhkanen@iki.fi>
6
6
  License: MIT License
@@ -26,47 +26,43 @@ License: MIT License
26
26
  SOFTWARE.
27
27
 
28
28
  Project-URL: homepage, https://github.com/ttu/ruuvitag-sensor
29
+ Project-URL: documentation, https://ttu.github.io/ruuvitag-sensor/
29
30
  Project-URL: source, https://github.com/ttu/ruuvitag-sensor
30
31
  Project-URL: changelog, https://github.com/ttu/ruuvitag-sensor/blob/master/CHANGELOG.md
31
- Project-URL: Bug Tracker, https://github.com/ttu/ruuvitag-sensor/issues
32
- Keywords: RuuviTag BLE
32
+ Project-URL: issues, https://github.com/ttu/ruuvitag-sensor/issues
33
+ Keywords: RuuviTag,BLE,Bluetooth,IoT,Sensor
33
34
  Classifier: Programming Language :: Python
34
- Classifier: Programming Language :: Python :: 3.7
35
- Classifier: Programming Language :: Python :: 3.8
36
35
  Classifier: Programming Language :: Python :: 3.9
37
36
  Classifier: Programming Language :: Python :: 3.10
38
37
  Classifier: Programming Language :: Python :: 3.11
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Programming Language :: Python :: 3.13
39
40
  Classifier: License :: OSI Approved :: MIT License
40
41
  Classifier: Operating System :: OS Independent
41
42
  Classifier: Intended Audience :: Developers
42
43
  Classifier: Development Status :: 5 - Production/Stable
43
44
  Classifier: Framework :: AsyncIO
44
45
  Classifier: Framework :: Pytest
45
- Requires-Python: >=3.7
46
+ Requires-Python: >=3.9
46
47
  Description-Content-Type: text/markdown
47
48
  License-File: LICENSE
48
49
  Requires-Dist: reactivex
49
50
  Requires-Dist: ptyprocess; platform_system == "Linux"
50
- Requires-Dist: mypy-extensions; python_version < "3.8"
51
- Requires-Dist: importlib-metadata<4.3,>=1.1.0; python_version < "3.8"
52
- Requires-Dist: bleak; platform_system == "Windows" or platform_system == "Darwin"
51
+ Requires-Dist: bleak
53
52
  Provides-Extra: dev
54
53
  Requires-Dist: pytest; extra == "dev"
55
54
  Requires-Dist: pytest-asyncio; extra == "dev"
56
- Requires-Dist: flake8-pyproject; extra == "dev"
57
- Requires-Dist: pylint; extra == "dev"
55
+ Requires-Dist: ruff; extra == "dev"
58
56
  Requires-Dist: mypy; extra == "dev"
59
- Requires-Dist: isort; extra == "dev"
60
- Requires-Dist: black; extra == "dev"
61
57
 
62
58
  RuuviTag Sensor Python Package
63
59
  ---------------------------------
64
60
 
65
61
  [![Build Status](https://github.com/ttu/ruuvitag-sensor/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/ttu/ruuvitag-sensor/actions/workflows/build.yml)
66
62
  [![License](https://img.shields.io/pypi/l/ruuvitag-sensor.svg)](https://pypi.python.org/pypi/ruuvitag-sensor/)
67
- [![PyPI version](https://img.shields.io/pypi/v/ruuvitag-sensor.svg)](https://pypi.python.org/pypi/ruuvitag_-sensor)
63
+ [![PyPI version](https://img.shields.io/pypi/v/ruuvitag-sensor.svg)](https://pypi.python.org/pypi/ruuvitag-sensor)
68
64
  [![PyPI downloads](https://img.shields.io/pypi/dm/ruuvitag-sensor.svg)](https://pypistats.org/packages/ruuvitag-sensor)
69
- [![Python versions](https://img.shields.io/pypi/pyversions/ruuvitag-sensor.svg)](https://pypi.python.org/pypi/ruuvitag-sensor/)
65
+ [![Python versions](https://img.shields.io/badge/python-3.9+-blue.svg)](https://pypi.python.org/pypi/ruuvitag-sensor/)
70
66
 
71
67
  `ruuvitag-sensor` is a Python package for communicating with [RuuviTag BLE Sensor](https://ruuvi.com/) and for decoding measurement data from broadcasted BLE data.
72
68
 
@@ -77,23 +73,30 @@ RuuviTag Sensor Python Package
77
73
  * RuuviTag sensor
78
74
  * Setup [guide](https://ruuvi.com/quick-start/)
79
75
  * Supports [Data Format 2, 3, 4 and 5](https://docs.ruuvi.com/)
80
- * __NOTE:__ Data Formats 2, 3 and 4 are _deprecated_ and should not be used
81
- * Bluez (Linux-only)
82
- * Default adapter for Linux
83
- * Bluez supports
84
- * [Sync-methods](#usage)
85
- * [Observable streams](#usage)
86
- * [Install guide](#BlueZ)
76
+ * __NOTE:__ Data Formats 2, 3 and 4 are _deprecated_ and should not be used.
87
77
  * [Bleak](https://github.com/hbldh/bleak) communication module (Windows, macOS and Linux)
88
- * Default adapter for Windows and macOS
78
+ * Default adapter for all supported operating systems.
89
79
  * Bleak supports
90
80
  * [Async-methods](#usage)
91
81
  * [Observable streams](#usage)
82
+ * [Fetch history data](#usage)
92
83
  * [Install guide](#Bleak)
93
- * Python 3.7+
94
- * For Python 2.x or <3.7 support, check [installation instructions](#python-2x-and-36-and-below) for an older version
84
+ * Bluez (Linux-only)
85
+ * Bluez supports
86
+ * [Sync-methods](#usage)
87
+ * [Observable streams](#usage)
88
+ * [Install guide](#BlueZ)
89
+ * __NOTE:__ The BlueZ-adapter implementation uses deprecated BlueZ tools that are no longer supported.
90
+ * Bleson-adapter supports sync-methods, but please be aware that it is not fully supported due to the alpha release status of the Bleson communication module. See [Bleson](#Bleson) for more information.
91
+ * Python 3.9+
92
+ * For Python 3.7 and 3.8 support, check installation [instructions](#python-37-and-38) for an older version.
93
+ * For Python 2.x or <3.7 support, check installation [instructions](#python-2x-and-36-and-below) for an older version.
94
+
95
+
96
+ __NOTE: Major version changes__
97
+ * Version 3.0 changed default BLE adapter for all platforms to Bleak with async-methods. To use `Bluez`and sync-methods, check the installation [instructions](#BlueZ).
98
+ * Version 2.0 contains method renames. When using a version prior to 2.0, check the documentation and examples from [documentation](https://ttu.github.io/ruuvitag-sensor/#/1.2.1/) or in GitHub, switch to the correct release tag from _switch branches/tags_.
95
99
 
96
- __NOTE:__ Version 2.0 contains method renames. When using a version prior to 2.0, check the documentation and examples from [PyPI](https://pypi.org/project/ruuvitag-sensor/) or in GitHub, switch to the correct release tag from _switch branches/tags_.
97
100
 
98
101
  ## Installation
99
102
 
@@ -116,68 +119,40 @@ Full installation guide for [Raspberry PI & Raspbian](https://github.com/ttu/ruu
116
119
 
117
120
  ## Usage
118
121
 
119
- The package provides 3 ways to fetch data from sensors:
122
+ ### Fetch broadcast data from RuuviTags
123
+
124
+ The package provides 3 ways to fetch broadcasted data from sensors:
120
125
 
121
- 1. Synchronously with callback
122
- 2. Asynchronously with async/await
126
+ 1. Asynchronously with async/await
127
+ 2. Synchronously with callback
123
128
  3. Observable streams with ReactiveX
124
129
 
125
- RuuviTag sensors can be identified using MAC addresses. Methods return a tuple with MAC and sensor data payload.
130
+ RuuviTag sensors can be identified using MAC addresses. Methods return a tuple containing MAC and sensor data payload.
126
131
 
127
132
  ```py
128
133
  ('D2:A3:6E:C8:E0:25', {'data_format': 5, 'humidity': 47.62, 'temperature': 23.58, 'pressure': 1023.68, 'acceleration': 993.2331045630729, 'acceleration_x': -48, 'acceleration_y': -12, 'acceleration_z': 992, 'tx_power': 4, 'battery': 2197, 'movement_counter': 0, 'measurement_sequence_number': 88, 'mac': 'd2a36ec8e025', 'rssi': -80})
129
134
  ```
130
135
 
131
- ### 1. Get sensor data synchronously with callback
132
-
133
- `get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
134
-
135
- ```python
136
- from ruuvitag_sensor.ruuvi import RuuviTagSensor
136
+ ### Fetch stored history data from RuuviTags internal memory
137
137
 
138
+ 4. Fetch history data with async/await
138
139
 
139
- def handle_data(found_data):
140
- print(f"MAC {found_data[0]}")
141
- print(f"Data {found_data[1]}")
140
+ Each history entry contains one measurement type (temperature, humidity, or pressure) with a Unix timestamp (integer). RuuviTag sends each measurement type as a separate entry.
142
141
 
143
-
144
- if __name__ == "__main__":
145
- RuuviTagSensor.get_data(handle_data)
142
+ ```py
143
+ [
144
+ {'temperature': 22.22, 'humidity': None, 'pressure': None, 'timestamp': 1738476581}
145
+ {'temperature': None, 'humidity': 38.8, 'pressure': None, 'timestamp': 1738476581},
146
+ {'temperature': None, 'humidity': None, 'pressure': 35755.0, 'timestamp': 1738476581},
147
+ ]
146
148
  ```
147
149
 
148
- The line `if __name__ == "__main__":` is required on Windows and macOS due to the way the `multiprocessing` library works. It is not required on Linux, but it is recommended. It is omitted from the rest of the examples below.
149
-
150
- The optional list of MACs and run flag can be passed to the `get_data` function. The callback is called only for MACs in the list and setting the run flag to false will stop execution. If the run flag is not passed, the function will execute forever.
151
-
152
- ```python
153
- from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
154
-
155
- counter = 10
156
- # RunFlag for stopping execution at desired time
157
- run_flag = RunFlag()
158
-
159
-
160
- def handle_data(found_data):
161
- print(f"MAC: {found_data[0]}")
162
- print(f"Data: {found_data[1]}")
163
-
164
- global counter
165
- counter = counter - 1
166
- if counter < 0:
167
- run_flag.running = False
168
-
169
150
 
170
- # List of MACs of sensors which will execute callback function
171
- macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
172
-
173
- RuuviTagSensor.get_data(handle_data, macs, run_flag)
174
- ```
175
-
176
- ### 2. Get sensor data asynchronously
151
+ ### 1. Get sensor data asynchronously with async/await
177
152
 
178
153
  __NOTE:__ Asynchronous functionality works only with `Bleak`-adapter.
179
154
 
180
- `get_data_async` returns the data whenever a RuuviTag sensor broadcasts data. `get_data_async` will exceute until iterator is exited. This method is the preferred way to use the library with _Bleak_.
155
+ `get_data_async` returns the data whenever a RuuviTag sensor broadcasts data. `get_data_async` will execute until iterator is exited. This method is the preferred way to use the library with _Bleak_.
181
156
 
182
157
  ```py
183
158
  import asyncio
@@ -191,7 +166,7 @@ async def main():
191
166
 
192
167
 
193
168
  if __name__ == "__main__":
194
- asyncio.get_event_loop().run_until_complete(main())
169
+ asyncio.run(main())
195
170
  ```
196
171
 
197
172
  The optional list of MACs can be passed to the `get_data_async` function.
@@ -209,13 +184,62 @@ async def main():
209
184
  async for found_data in RuuviTagSensor.get_data_async(macs):
210
185
  print(f"MAC: {found_data[0]}")
211
186
  print(f"Data: {found_data[1]}")
212
- datas.push(found_data)
187
+ datas.append(found_data)
213
188
  if len(datas) > 10:
214
189
  break
215
190
 
216
191
 
217
192
  if __name__ == "__main__":
218
- asyncio.get_event_loop().run_until_complete(main())
193
+ asyncio.run(main())
194
+ ```
195
+
196
+ The line `if __name__ == "__main__":` is required on Windows and macOS due to the way the `multiprocessing` library works. While not required on Linux, it is recommended. It is omitted from the rest of the examples below.
197
+
198
+ For Python 3.9, you must replace `asyncio.run(main())` with `asyncio.get_event_loop().run_until_complete(main())` due to limitations in the RuuviTag package's Bleak adapter. In Python 3.10 and later versions, you can use `asyncio.run(main())`.
199
+
200
+ ### 2. Get sensor data synchronously with callback
201
+
202
+ __NOTE:__ Synchronous functionality works only with `BlueZ`-adapter.
203
+
204
+ `get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
205
+
206
+ ```python
207
+ from ruuvitag_sensor.ruuvi import RuuviTagSensor
208
+
209
+
210
+ def handle_data(found_data):
211
+ print(f"MAC {found_data[0]}")
212
+ print(f"Data {found_data[1]}")
213
+
214
+
215
+ if __name__ == "__main__":
216
+ RuuviTagSensor.get_data(handle_data)
217
+ ```
218
+
219
+ The optional list of MACs and run flag can be passed to the `get_data` function. The callback is called only for MACs in the list and setting the run flag to false will stop execution. If the run flag is not passed, the function will execute forever.
220
+
221
+ ```python
222
+ from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
223
+
224
+ counter = 10
225
+ # RunFlag for stopping execution at desired time
226
+ run_flag = RunFlag()
227
+
228
+
229
+ def handle_data(found_data):
230
+ print(f"MAC: {found_data[0]}")
231
+ print(f"Data: {found_data[1]}")
232
+
233
+ global counter
234
+ counter = counter - 1
235
+ if counter < 0:
236
+ run_flag.running = False
237
+
238
+
239
+ # List of MACs of sensors which will execute callback function
240
+ macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
241
+
242
+ RuuviTagSensor.get_data(handle_data, macs, run_flag)
219
243
  ```
220
244
 
221
245
  ### 3. Get sensor data with observable streams (ReactiveX / RxPY)
@@ -245,7 +269,7 @@ ruuvi_rx.get_subject().pipe(
245
269
  ops.distinct_until_changed()
246
270
  ).subscribe(lambda x: print(f"Temperature changed: {x}"))
247
271
 
248
- # Close all connections and stop bluetooth communication
272
+ # Close all connections and stop Bluetooth communication
249
273
  ruuvi_rx.stop()
250
274
  ```
251
275
 
@@ -253,6 +277,54 @@ More [samples](https://github.com/ttu/ruuvitag-sensor/blob/master/examples/react
253
277
 
254
278
  Check the official documentation of [ReactiveX](https://rxpy.readthedocs.io/en/latest/index.html) and the [list of operators](https://rxpy.readthedocs.io/en/latest/operators.html).
255
279
 
280
+ ### 4. Fetch history data
281
+
282
+ __NOTE:__ History data functionality works only with `Bleak`-adapter.
283
+
284
+ RuuviTags with firmware version 3.30.0 or newer support retrieving historical measurements. The package provides two methods to access this data:
285
+
286
+ 1. `get_history_async`: Stream history entries as they arrive
287
+ 2. `download_history`: Download all history entries at once
288
+
289
+ Each history entry contains one measurement type (temperature, humidity, or pressure) with a Unix timestamp (integer). RuuviTag sends each measurement type as a separate entry.
290
+
291
+ Example history entry:
292
+ ```py
293
+ {
294
+ 'temperature': 22.22, # Only one measurement type per entry
295
+ 'humidity': None,
296
+ 'pressure': None,
297
+ 'timestamp': 1738476581 # Unix timestamp (integer)
298
+ }
299
+ ```
300
+
301
+ ```py
302
+ import asyncio
303
+ from datetime import datetime, timedelta
304
+
305
+ from ruuvitag_sensor.ruuvi import RuuviTagSensor
306
+
307
+
308
+ async def main():
309
+ # Get history from the last 10 minutes
310
+ start_time = datetime.now() - timedelta(minutes=10)
311
+
312
+ # Stream entries as they arrive
313
+ async for entry in RuuviTagSensor.get_history_async(mac="AA:BB:CC:DD:EE:FF", start_time=start_time):
314
+ print(f"Time: {entry['timestamp']} - {entry}")
315
+
316
+ # Or download all entries at once
317
+ history = await RuuviTagSensor.download_history(mac="AA:BB:CC:DD:EE:FF", start_time=start_time)
318
+ for entry in history:
319
+ print(f"Time: {entry['timestamp']} - {entry}")
320
+
321
+
322
+ if __name__ == "__main__":
323
+ asyncio.run(main())
324
+ ```
325
+
326
+ __NOTE:__ Due to the way macOS handles Bluetooth, methods uses UUIDs to identify RuuviTags instead of MAC addresses.
327
+
256
328
  ### Other helper methods
257
329
 
258
330
  #### Get data for specified sensors for a specific duration
@@ -311,7 +383,7 @@ RuuviTagSensor.find_ruuvitags()
311
383
 
312
384
  ### Using different Bluetooth device
313
385
 
314
- If you have multiple Bluetooth devices installed, a device to be used might not be the default (Linux: hci0). The device can be passed with a `bt_device`-parameter.
386
+ If you have multiple Bluetooth devices installed, the device to be used might not be the default (Linux: `hci0`). The device can be passed with a `bt_device` parameter.
315
387
 
316
388
  ```python
317
389
  from ruuvitag_sensor.ruuvi import RuuviTagSensor
@@ -365,41 +437,42 @@ Example data has data from 4 sensors with different firmware.
365
437
 
366
438
  There is no reason to use Data Format 2 or 4.
367
439
 
368
- The original reason to use the URL-encoded data was to use _Google's Nearby_ notifications to let users view tags without the need to install any app. Since _Google's Nearby_ has been discontinued, there isn't any benefit in using the Eddystone format anymore.
440
+ The original reason to use URL-encoded data was to use _Google's Nearby_ notifications to let users view tags without the need to install any app. Since _Google's Nearby_ has been discontinued, there isn't any benefit in using the Eddystone format anymore.
441
+
442
+ ## Logging
369
443
 
370
- ## Logging and printing to the console
444
+ The package uses Python's standard `logging` module. Each module in the package creates its own logger using `logging.getLogger(__name__)`.
371
445
 
372
- Logging can be enabled by importing `ruuvitag_sensor.log`. Console print can be enabled by calling `ruuvitag_sensor.log.enable_console()`. The command line application has console logging enabled by default.
446
+ ### Library usage
447
+
448
+ When using ruuvitag-sensor as a library in your application, you should configure logging according to your application's needs:
373
449
 
374
450
  ```py
451
+ import logging
375
452
  from ruuvitag_sensor.ruuvi import RuuviTagSensor
376
- import ruuvitag_sensor.log
377
453
 
378
- ruuvitag_sensor.log.enable_console()
454
+ # Configure logging at the application level
455
+ logging.basicConfig(level=logging.INFO)
456
+ # Or set up custom handlers, formatters, etc.
379
457
 
380
458
  data = RuuviTagSensor.get_data_for_sensors()
381
-
382
- print(data)
383
459
  ```
384
460
 
385
- To enable debug logging to console, set log-level to `DEBUG`.
461
+ ### Command-line and script usage
462
+
463
+ For command-line and script usage, the package provides convenience functions to enable console output:
386
464
 
387
465
  ```py
388
- import logging
389
- import ruuvitag_sensor.log
390
- from ruuvitag_sensor.log import log
391
466
  from ruuvitag_sensor.ruuvi import RuuviTagSensor
467
+ import ruuvitag_sensor.log
392
468
 
469
+ # Enable console logging (defaults to INFO level)
393
470
  ruuvitag_sensor.log.enable_console()
394
471
 
395
- log.setLevel(logging.DEBUG)
396
-
397
- for handler in log.handlers:
398
- handler.setLevel(logging.DEBUG)
472
+ # For debug logging
473
+ ruuvitag_sensor.log.enable_console(level=logging.DEBUG)
399
474
 
400
475
  data = RuuviTagSensor.get_data_for_sensors()
401
-
402
- print(data)
403
476
  ```
404
477
 
405
478
  ### Log all events to log-file
@@ -422,7 +495,7 @@ data = RuuviTagSensor.get_data_for_sensors()
422
495
 
423
496
  ### A custom event handler for a specific log event
424
497
 
425
- If custom functionality is required when a specific event happens, e.g. exit when a specific sensor is blacklisted, logging event handlers can be utilized for this functionality.
498
+ You can add custom handlers to respond to specific log events. For example, to exit when a specific sensor is blacklisted:
426
499
 
427
500
  ```py
428
501
  from logging import StreamHandler
@@ -433,7 +506,7 @@ from ruuvitag_sensor.ruuvi import RuuviTagSensor
433
506
  class ExitHandler(StreamHandler):
434
507
 
435
508
  def emit(self, record):
436
- if (record.levelname != "DEBUG"):
509
+ if record.levelname != "DEBUG":
437
510
  return
438
511
  msg = self.format(record)
439
512
  if "Blacklisting MAC F4:A5:74:89:16:57E" in msg:
@@ -481,37 +554,38 @@ $ sudo apt-get install bluez bluez-hcidump
481
554
 
482
555
  `ruuvitag-sensor` package uses internally _hciconfig_, _hcitool_ and _hcidump_. These tools are deprecated. In case tools are missing, an older version of BlueZ is required ([Issue](https://github.com/ttu/ruuvitag-sensor/issues/31))
483
556
 
484
- #### BlueZ limitations
557
+ Enable Bluez with the `RUUVI_BLE_ADAPTER` environment variable.
485
558
 
486
- `ruuvitag-sensor` package uses BlueZ to listen to broadcasted BL information (uses _hciconf_, _hcitool_, _hcidump_). Implementation does not handle well all unexpected errors or changes, e.g. when the adapter is busy, rebooted or powered down.
559
+ ```sh
560
+ $ export RUUVI_BLE_ADAPTER="bluez"
561
+ ```
487
562
 
488
- In case of errors, the application tries to exit immediately, so it can be automatically restarted.
563
+ Or use `os.environ`. __NOTE:__ this must be set before importing `ruuvitag_sensor`.
489
564
 
490
- ### Bleak
565
+ ```py
566
+ import os
491
567
 
492
- On Windows and macOS Bleak is installed and used automatically with `ruuvitag-sensor` package.
568
+ os.environ["RUUVI_BLE_ADAPTER"] = "bluez"
569
+ ```
493
570
 
494
- On Linux install it manually from PyPI and enable it with `RUUVI_BLE_ADAPTER` environment variable.
571
+ And install ptyprocess.
495
572
 
496
573
  ```sh
497
- $ python -m pip install bleak
574
+ python -m pip install ptyprocess
498
575
  ```
499
576
 
500
- Add environment variable RUUVI_BLE_ADAPTER with value Bleak. E.g.
577
+ #### BlueZ limitations
501
578
 
502
- ```sh
503
- $ export RUUVI_BLE_ADAPTER="bleak"
504
- ```
579
+ `ruuvitag-sensor` package uses BlueZ to listen to broadcasted BL information (uses _hciconf_, _hcitool_, _hcidump_). Implementation does not handle well all unexpected errors or changes, e.g. when the adapter is busy, rebooted or powered down.
505
580
 
506
- Or use `os.environ`. NOTE: this must be set before importing `ruuvitag_sensor`.
581
+ In case of errors, the application tries to exit immediately, so it can be automatically restarted.
507
582
 
508
- ```py
509
- import os
583
+ ### Bleak
510
584
 
511
- os.environ["RUUVI_BLE_ADAPTER"] = "bleak"
512
- ```
585
+ Bleak is automatically installed with `ruuvitag-sensor` package on all platforms.
586
+ It is automatically used with `ruuvitag-sensor` package on all platforms.
513
587
 
514
- Bleak supports only async methods.
588
+ Bleak only supports asynchronous methods.
515
589
 
516
590
  ```py
517
591
  import asyncio
@@ -524,25 +598,25 @@ async def main():
524
598
 
525
599
 
526
600
  if __name__ == "__main__":
527
- asyncio.get_event_loop().run_until_complete(main())
601
+ asyncio.run(main())
528
602
  ```
529
603
 
530
604
  Check [get_async_bleak](https://github.com/ttu/ruuvitag-sensor/blob/master/examples/get_async_bleak.py) and other async examples from [examples](https://github.com/ttu/ruuvitag-sensor/tree/master/examples) directory.
531
605
 
532
606
  #### Bleak dummy BLE data
533
607
 
534
- Bleak-adapter has a development-time generator for dummy data, which can be useful during the development, if no sensors are available. Set `RUUVI_BLE_ADAPTER` environment variable to `bleak_dev`.
608
+ Bleak-adapter has a development-time generator for dummy data, which can be useful during development if no sensors are available. Set the `RUUVI_BLE_ADAPTER` environment variable to `bleak_dev`.
535
609
 
536
610
  ### Bleson
537
611
 
538
612
  Current state and known bugs in [issue #78](https://github.com/ttu/ruuvitag-sensor/issues/78).
539
613
 
540
- Bleson works with Linux, macOS and partially with Windows.
614
+ [Bleson](https://github.com/TheCellule/python-bleson) works with Linux, macOS and partially with Windows.
541
615
 
542
616
  Bleson is not installed automatically with `ruuvitag-sensor` package. Install it manually from GitHub.
543
617
 
544
618
  ```sh
545
- $ pip install git+https://github.com/TheCellule/python-bleson
619
+ $ python -m pip install git+https://github.com/TheCellule/python-bleson
546
620
  ```
547
621
 
548
622
  Add environment variable `RUUVI_BLE_ADAPTER` with value `bleson`. E.g.
@@ -556,6 +630,21 @@ __NOTE:__ On macOS, only Data Format 5 works, as macOS doesn't advertise MAC add
556
630
  __NOTE:__ On Windows, Bleson requires _Python 3.6_. Unfortunately on Windows, Bleson doesn't send any payload for the advertised package, so it is still unusable.
557
631
 
558
632
 
633
+ ## Python 3.7 and 3.8
634
+
635
+ Last version of `ruuvitag-sensor` with Python 3.7 and 3.8 support is [2.3.1](https://pypi.org/project/ruuvitag-sensor/2.3.1/).
636
+
637
+ [Branch](https://github.com/ttu/ruuvitag-sensor/tree/release/2.3.1) / [Tag / commit](https://github.com/ttu/ruuvitag-sensor/commit/b16c9580d75eafe5508d0551642eb3b022ae1325)
638
+
639
+ ```sh
640
+ $ git checkout release/2.3.1
641
+ ```
642
+
643
+ Install from PyPI
644
+ ```sh
645
+ $ python -m pip install ruuvitag-sensor==2.3.1
646
+ ```
647
+
559
648
  ## Python 2.x and 3.6 and below
560
649
 
561
650
  Last version of `ruuvitag-sensor` with Python 2.x and <3.7 support is [1.2.1](https://pypi.org/project/ruuvitag-sensor/1.2.1/).