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.
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/PKG-INFO +206 -117
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/README.md +196 -103
- ruuvitag_sensor-3.1.0/pyproject.toml +92 -0
- ruuvitag_sensor-3.1.0/ruuvitag_sensor/__init__.py +3 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/__main__.py +1 -1
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/__init__.py +26 -20
- ruuvitag_sensor-3.1.0/ruuvitag_sensor/adapters/bleak_ble.py +262 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/bleson.py +6 -7
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/development/dev_bleak_scanner.py +0 -2
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/nix_hci.py +5 -8
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/nix_hci_file.py +3 -1
- ruuvitag_sensor-3.1.0/ruuvitag_sensor/adapters/utils.py +2 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/data_formats.py +3 -4
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/decoder.py +133 -1
- ruuvitag_sensor-3.1.0/ruuvitag_sensor/log.py +44 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi.py +131 -34
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi_rx.py +13 -9
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvi_types.py +8 -6
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/PKG-INFO +207 -118
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/SOURCES.txt +1 -0
- ruuvitag_sensor-3.1.0/ruuvitag_sensor.egg-info/requires.txt +11 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_data_formats.py +0 -2
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_decoder.py +94 -1
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_ruuvitag_sensor.py +0 -2
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/tests/test_ruuvitag_sensor_async.py +2 -10
- ruuvitag_sensor-2.3.0/pyproject.toml +0 -89
- ruuvitag_sensor-2.3.0/ruuvitag_sensor/__init__.py +0 -8
- ruuvitag_sensor-2.3.0/ruuvitag_sensor/adapters/bleak_ble.py +0 -111
- ruuvitag_sensor-2.3.0/ruuvitag_sensor/log.py +0 -27
- ruuvitag_sensor-2.3.0/ruuvitag_sensor.egg-info/requires.txt +0 -20
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/LICENSE +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/MANIFEST.in +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/development/__init__.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/adapters/dummy.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor/ruuvitag.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/dependency_links.txt +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/ruuvitag_sensor.egg-info/top_level.txt +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-3.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: ruuvitag_sensor
|
|
3
|
-
Version:
|
|
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:
|
|
32
|
-
Keywords: RuuviTag
|
|
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.
|
|
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:
|
|
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:
|
|
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
|
[](https://github.com/ttu/ruuvitag-sensor/actions/workflows/build.yml)
|
|
66
62
|
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
67
|
-
[](https://pypi.python.org/pypi/
|
|
63
|
+
[](https://pypi.python.org/pypi/ruuvitag-sensor)
|
|
68
64
|
[](https://pypistats.org/packages/ruuvitag-sensor)
|
|
69
|
-
[](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
|
|
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
|
-
*
|
|
94
|
-
*
|
|
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
|
-
|
|
122
|
+
### Fetch broadcast data from RuuviTags
|
|
123
|
+
|
|
124
|
+
The package provides 3 ways to fetch broadcasted data from sensors:
|
|
120
125
|
|
|
121
|
-
1.
|
|
122
|
-
2.
|
|
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
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
557
|
+
Enable Bluez with the `RUUVI_BLE_ADAPTER` environment variable.
|
|
485
558
|
|
|
486
|
-
|
|
559
|
+
```sh
|
|
560
|
+
$ export RUUVI_BLE_ADAPTER="bluez"
|
|
561
|
+
```
|
|
487
562
|
|
|
488
|
-
|
|
563
|
+
Or use `os.environ`. __NOTE:__ this must be set before importing `ruuvitag_sensor`.
|
|
489
564
|
|
|
490
|
-
|
|
565
|
+
```py
|
|
566
|
+
import os
|
|
491
567
|
|
|
492
|
-
|
|
568
|
+
os.environ["RUUVI_BLE_ADAPTER"] = "bluez"
|
|
569
|
+
```
|
|
493
570
|
|
|
494
|
-
|
|
571
|
+
And install ptyprocess.
|
|
495
572
|
|
|
496
573
|
```sh
|
|
497
|
-
|
|
574
|
+
python -m pip install ptyprocess
|
|
498
575
|
```
|
|
499
576
|
|
|
500
|
-
|
|
577
|
+
#### BlueZ limitations
|
|
501
578
|
|
|
502
|
-
|
|
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
|
-
|
|
581
|
+
In case of errors, the application tries to exit immediately, so it can be automatically restarted.
|
|
507
582
|
|
|
508
|
-
|
|
509
|
-
import os
|
|
583
|
+
### Bleak
|
|
510
584
|
|
|
511
|
-
|
|
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
|
|
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.
|
|
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
|
|
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/).
|