ruuvitag-sensor 2.3.0__tar.gz → 2.3.1__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-2.3.1}/PKG-INFO +81 -63
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/README.md +78 -61
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/pyproject.toml +3 -2
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/__init__.py +25 -10
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/bleak_ble.py +17 -5
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/bleson.py +4 -0
- ruuvitag_sensor-2.3.1/ruuvitag_sensor/adapters/utils.py +2 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/data_formats.py +1 -1
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/PKG-INFO +82 -64
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/SOURCES.txt +1 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/requires.txt +1 -1
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/LICENSE +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/MANIFEST.in +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/__init__.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/__main__.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/development/__init__.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/development/dev_bleak_scanner.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/dummy.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/nix_hci.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/nix_hci_file.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/decoder.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/log.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/ruuvi.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/ruuvi_rx.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/ruuvi_types.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/ruuvitag.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/dependency_links.txt +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/top_level.txt +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/setup.cfg +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/tests/test_data_formats.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/tests/test_decoder.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/tests/test_ruuvitag_sensor.py +0 -0
- {ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/tests/test_ruuvitag_sensor_async.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ruuvitag_sensor
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.1
|
|
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
|
|
@@ -36,6 +36,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
36
36
|
Classifier: Programming Language :: Python :: 3.9
|
|
37
37
|
Classifier: Programming Language :: Python :: 3.10
|
|
38
38
|
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
40
|
Classifier: License :: OSI Approved :: MIT License
|
|
40
41
|
Classifier: Operating System :: OS Independent
|
|
41
42
|
Classifier: Intended Audience :: Developers
|
|
@@ -57,7 +58,7 @@ Requires-Dist: flake8-pyproject; extra == "dev"
|
|
|
57
58
|
Requires-Dist: pylint; extra == "dev"
|
|
58
59
|
Requires-Dist: mypy; extra == "dev"
|
|
59
60
|
Requires-Dist: isort; extra == "dev"
|
|
60
|
-
Requires-Dist: black; extra == "dev"
|
|
61
|
+
Requires-Dist: black==23.3.0; extra == "dev"
|
|
61
62
|
|
|
62
63
|
RuuviTag Sensor Python Package
|
|
63
64
|
---------------------------------
|
|
@@ -66,7 +67,7 @@ RuuviTag Sensor Python Package
|
|
|
66
67
|
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
67
68
|
[](https://pypi.python.org/pypi/ruuvitag_-sensor)
|
|
68
69
|
[](https://pypistats.org/packages/ruuvitag-sensor)
|
|
69
|
-
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
70
71
|
|
|
71
72
|
`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
73
|
|
|
@@ -78,18 +79,21 @@ RuuviTag Sensor Python Package
|
|
|
78
79
|
* Setup [guide](https://ruuvi.com/quick-start/)
|
|
79
80
|
* Supports [Data Format 2, 3, 4 and 5](https://docs.ruuvi.com/)
|
|
80
81
|
* __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)
|
|
87
82
|
* [Bleak](https://github.com/hbldh/bleak) communication module (Windows, macOS and Linux)
|
|
88
83
|
* Default adapter for Windows and macOS
|
|
89
84
|
* Bleak supports
|
|
90
85
|
* [Async-methods](#usage)
|
|
91
86
|
* [Observable streams](#usage)
|
|
92
87
|
* [Install guide](#Bleak)
|
|
88
|
+
* Bluez (Linux-only)
|
|
89
|
+
* Default adapter for Linux
|
|
90
|
+
* Bluez supports
|
|
91
|
+
* [Sync-methods](#usage)
|
|
92
|
+
* [Observable streams](#usage)
|
|
93
|
+
* [Install guide](#BlueZ)
|
|
94
|
+
* __NOTE:__ The BlueZ-adapter implementation uses deprecated BlueZ tools that are no longer supported.
|
|
95
|
+
* Even though BlueZ is still the default adapter, it is recommended to use the Bleak-communication adapter with Linux. Bleak will be the default adapter for Linux in the next major release.
|
|
96
|
+
* 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.
|
|
93
97
|
* Python 3.7+
|
|
94
98
|
* For Python 2.x or <3.7 support, check [installation instructions](#python-2x-and-36-and-below) for an older version
|
|
95
99
|
|
|
@@ -118,8 +122,8 @@ Full installation guide for [Raspberry PI & Raspbian](https://github.com/ttu/ruu
|
|
|
118
122
|
|
|
119
123
|
The package provides 3 ways to fetch data from sensors:
|
|
120
124
|
|
|
121
|
-
1.
|
|
122
|
-
2.
|
|
125
|
+
1. Asynchronously with async/await
|
|
126
|
+
2. Synchronously with callback
|
|
123
127
|
3. Observable streams with ReactiveX
|
|
124
128
|
|
|
125
129
|
RuuviTag sensors can be identified using MAC addresses. Methods return a tuple with MAC and sensor data payload.
|
|
@@ -128,56 +132,11 @@ RuuviTag sensors can be identified using MAC addresses. Methods return a tuple w
|
|
|
128
132
|
('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
133
|
```
|
|
130
134
|
|
|
131
|
-
### 1. Get sensor data
|
|
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
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def handle_data(found_data):
|
|
140
|
-
print(f"MAC {found_data[0]}")
|
|
141
|
-
print(f"Data {found_data[1]}")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if __name__ == "__main__":
|
|
145
|
-
RuuviTagSensor.get_data(handle_data)
|
|
146
|
-
```
|
|
147
|
-
|
|
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
|
-
|
|
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
|
|
135
|
+
### 1. Get sensor data asynchronously with async/await
|
|
177
136
|
|
|
178
137
|
__NOTE:__ Asynchronous functionality works only with `Bleak`-adapter.
|
|
179
138
|
|
|
180
|
-
`get_data_async` returns the data whenever a RuuviTag sensor broadcasts data. `get_data_async` will
|
|
139
|
+
`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
140
|
|
|
182
141
|
```py
|
|
183
142
|
import asyncio
|
|
@@ -218,6 +177,53 @@ if __name__ == "__main__":
|
|
|
218
177
|
asyncio.get_event_loop().run_until_complete(main())
|
|
219
178
|
```
|
|
220
179
|
|
|
180
|
+
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.
|
|
181
|
+
|
|
182
|
+
### 2. Get sensor data synchronously with callback
|
|
183
|
+
|
|
184
|
+
__NOTE:__ Asynchronous functionality works only with `BlueZ`-adapter.
|
|
185
|
+
|
|
186
|
+
`get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def handle_data(found_data):
|
|
193
|
+
print(f"MAC {found_data[0]}")
|
|
194
|
+
print(f"Data {found_data[1]}")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
if __name__ == "__main__":
|
|
198
|
+
RuuviTagSensor.get_data(handle_data)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
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.
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
|
|
205
|
+
|
|
206
|
+
counter = 10
|
|
207
|
+
# RunFlag for stopping execution at desired time
|
|
208
|
+
run_flag = RunFlag()
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def handle_data(found_data):
|
|
212
|
+
print(f"MAC: {found_data[0]}")
|
|
213
|
+
print(f"Data: {found_data[1]}")
|
|
214
|
+
|
|
215
|
+
global counter
|
|
216
|
+
counter = counter - 1
|
|
217
|
+
if counter < 0:
|
|
218
|
+
run_flag.running = False
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# List of MACs of sensors which will execute callback function
|
|
222
|
+
macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
|
|
223
|
+
|
|
224
|
+
RuuviTagSensor.get_data(handle_data, macs, run_flag)
|
|
225
|
+
```
|
|
226
|
+
|
|
221
227
|
### 3. Get sensor data with observable streams (ReactiveX / RxPY)
|
|
222
228
|
|
|
223
229
|
`RuuviTagReactive` is a reactive wrapper and background process for RuuviTagSensor `get_data`. An optional MAC address list can be passed on the initializer and execution can be stopped with the stop function.
|
|
@@ -245,7 +251,7 @@ ruuvi_rx.get_subject().pipe(
|
|
|
245
251
|
ops.distinct_until_changed()
|
|
246
252
|
).subscribe(lambda x: print(f"Temperature changed: {x}"))
|
|
247
253
|
|
|
248
|
-
# Close all connections and stop
|
|
254
|
+
# Close all connections and stop Bluetooth communication
|
|
249
255
|
ruuvi_rx.stop()
|
|
250
256
|
```
|
|
251
257
|
|
|
@@ -311,7 +317,7 @@ RuuviTagSensor.find_ruuvitags()
|
|
|
311
317
|
|
|
312
318
|
### Using different Bluetooth device
|
|
313
319
|
|
|
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.
|
|
320
|
+
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.
|
|
315
321
|
|
|
316
322
|
```python
|
|
317
323
|
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
@@ -481,6 +487,18 @@ $ sudo apt-get install bluez bluez-hcidump
|
|
|
481
487
|
|
|
482
488
|
`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
489
|
|
|
490
|
+
If you wish to test the library on Windows or macOS, enable it with `RUUVI_BLE_ADAPTER` environment variable.
|
|
491
|
+
|
|
492
|
+
```sh
|
|
493
|
+
$ export RUUVI_BLE_ADAPTER="bluez"
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
And install ptyprocess.
|
|
497
|
+
|
|
498
|
+
```sh
|
|
499
|
+
python -m pip install ptyprocess
|
|
500
|
+
```
|
|
501
|
+
|
|
484
502
|
#### BlueZ limitations
|
|
485
503
|
|
|
486
504
|
`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.
|
|
@@ -503,7 +521,7 @@ Add environment variable RUUVI_BLE_ADAPTER with value Bleak. E.g.
|
|
|
503
521
|
$ export RUUVI_BLE_ADAPTER="bleak"
|
|
504
522
|
```
|
|
505
523
|
|
|
506
|
-
Or use `os.environ`.
|
|
524
|
+
Or use `os.environ`. __NOTE:__ this must be set before importing `ruuvitag_sensor`.
|
|
507
525
|
|
|
508
526
|
```py
|
|
509
527
|
import os
|
|
@@ -537,12 +555,12 @@ Bleak-adapter has a development-time generator for dummy data, which can be usef
|
|
|
537
555
|
|
|
538
556
|
Current state and known bugs in [issue #78](https://github.com/ttu/ruuvitag-sensor/issues/78).
|
|
539
557
|
|
|
540
|
-
Bleson works with Linux, macOS and partially with Windows.
|
|
558
|
+
[Bleson](https://github.com/TheCellule/python-bleson) works with Linux, macOS and partially with Windows.
|
|
541
559
|
|
|
542
560
|
Bleson is not installed automatically with `ruuvitag-sensor` package. Install it manually from GitHub.
|
|
543
561
|
|
|
544
562
|
```sh
|
|
545
|
-
$ pip install git+https://github.com/TheCellule/python-bleson
|
|
563
|
+
$ python -m pip install git+https://github.com/TheCellule/python-bleson
|
|
546
564
|
```
|
|
547
565
|
|
|
548
566
|
Add environment variable `RUUVI_BLE_ADAPTER` with value `bleson`. E.g.
|
|
@@ -5,7 +5,7 @@ RuuviTag Sensor Python Package
|
|
|
5
5
|
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
6
6
|
[](https://pypi.python.org/pypi/ruuvitag_-sensor)
|
|
7
7
|
[](https://pypistats.org/packages/ruuvitag-sensor)
|
|
8
|
-
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
9
9
|
|
|
10
10
|
`ruuvitag-sensor` is a Python package for communicating with [RuuviTag BLE Sensor](https://ruuvi.com/) and for decoding measurement data from broadcasted BLE data.
|
|
11
11
|
|
|
@@ -17,18 +17,21 @@ RuuviTag Sensor Python Package
|
|
|
17
17
|
* Setup [guide](https://ruuvi.com/quick-start/)
|
|
18
18
|
* Supports [Data Format 2, 3, 4 and 5](https://docs.ruuvi.com/)
|
|
19
19
|
* __NOTE:__ Data Formats 2, 3 and 4 are _deprecated_ and should not be used
|
|
20
|
-
* Bluez (Linux-only)
|
|
21
|
-
* Default adapter for Linux
|
|
22
|
-
* Bluez supports
|
|
23
|
-
* [Sync-methods](#usage)
|
|
24
|
-
* [Observable streams](#usage)
|
|
25
|
-
* [Install guide](#BlueZ)
|
|
26
20
|
* [Bleak](https://github.com/hbldh/bleak) communication module (Windows, macOS and Linux)
|
|
27
21
|
* Default adapter for Windows and macOS
|
|
28
22
|
* Bleak supports
|
|
29
23
|
* [Async-methods](#usage)
|
|
30
24
|
* [Observable streams](#usage)
|
|
31
25
|
* [Install guide](#Bleak)
|
|
26
|
+
* Bluez (Linux-only)
|
|
27
|
+
* Default adapter for Linux
|
|
28
|
+
* Bluez supports
|
|
29
|
+
* [Sync-methods](#usage)
|
|
30
|
+
* [Observable streams](#usage)
|
|
31
|
+
* [Install guide](#BlueZ)
|
|
32
|
+
* __NOTE:__ The BlueZ-adapter implementation uses deprecated BlueZ tools that are no longer supported.
|
|
33
|
+
* Even though BlueZ is still the default adapter, it is recommended to use the Bleak-communication adapter with Linux. Bleak will be the default adapter for Linux in the next major release.
|
|
34
|
+
* 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.
|
|
32
35
|
* Python 3.7+
|
|
33
36
|
* For Python 2.x or <3.7 support, check [installation instructions](#python-2x-and-36-and-below) for an older version
|
|
34
37
|
|
|
@@ -57,8 +60,8 @@ Full installation guide for [Raspberry PI & Raspbian](https://github.com/ttu/ruu
|
|
|
57
60
|
|
|
58
61
|
The package provides 3 ways to fetch data from sensors:
|
|
59
62
|
|
|
60
|
-
1.
|
|
61
|
-
2.
|
|
63
|
+
1. Asynchronously with async/await
|
|
64
|
+
2. Synchronously with callback
|
|
62
65
|
3. Observable streams with ReactiveX
|
|
63
66
|
|
|
64
67
|
RuuviTag sensors can be identified using MAC addresses. Methods return a tuple with MAC and sensor data payload.
|
|
@@ -67,56 +70,11 @@ RuuviTag sensors can be identified using MAC addresses. Methods return a tuple w
|
|
|
67
70
|
('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})
|
|
68
71
|
```
|
|
69
72
|
|
|
70
|
-
### 1. Get sensor data
|
|
71
|
-
|
|
72
|
-
`get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
|
|
73
|
-
|
|
74
|
-
```python
|
|
75
|
-
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def handle_data(found_data):
|
|
79
|
-
print(f"MAC {found_data[0]}")
|
|
80
|
-
print(f"Data {found_data[1]}")
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if __name__ == "__main__":
|
|
84
|
-
RuuviTagSensor.get_data(handle_data)
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
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.
|
|
88
|
-
|
|
89
|
-
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.
|
|
90
|
-
|
|
91
|
-
```python
|
|
92
|
-
from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
|
|
93
|
-
|
|
94
|
-
counter = 10
|
|
95
|
-
# RunFlag for stopping execution at desired time
|
|
96
|
-
run_flag = RunFlag()
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def handle_data(found_data):
|
|
100
|
-
print(f"MAC: {found_data[0]}")
|
|
101
|
-
print(f"Data: {found_data[1]}")
|
|
102
|
-
|
|
103
|
-
global counter
|
|
104
|
-
counter = counter - 1
|
|
105
|
-
if counter < 0:
|
|
106
|
-
run_flag.running = False
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# List of MACs of sensors which will execute callback function
|
|
110
|
-
macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
|
|
111
|
-
|
|
112
|
-
RuuviTagSensor.get_data(handle_data, macs, run_flag)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### 2. Get sensor data asynchronously
|
|
73
|
+
### 1. Get sensor data asynchronously with async/await
|
|
116
74
|
|
|
117
75
|
__NOTE:__ Asynchronous functionality works only with `Bleak`-adapter.
|
|
118
76
|
|
|
119
|
-
`get_data_async` returns the data whenever a RuuviTag sensor broadcasts data. `get_data_async` will
|
|
77
|
+
`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_.
|
|
120
78
|
|
|
121
79
|
```py
|
|
122
80
|
import asyncio
|
|
@@ -157,6 +115,53 @@ if __name__ == "__main__":
|
|
|
157
115
|
asyncio.get_event_loop().run_until_complete(main())
|
|
158
116
|
```
|
|
159
117
|
|
|
118
|
+
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.
|
|
119
|
+
|
|
120
|
+
### 2. Get sensor data synchronously with callback
|
|
121
|
+
|
|
122
|
+
__NOTE:__ Asynchronous functionality works only with `BlueZ`-adapter.
|
|
123
|
+
|
|
124
|
+
`get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def handle_data(found_data):
|
|
131
|
+
print(f"MAC {found_data[0]}")
|
|
132
|
+
print(f"Data {found_data[1]}")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
if __name__ == "__main__":
|
|
136
|
+
RuuviTagSensor.get_data(handle_data)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
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.
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
|
|
143
|
+
|
|
144
|
+
counter = 10
|
|
145
|
+
# RunFlag for stopping execution at desired time
|
|
146
|
+
run_flag = RunFlag()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def handle_data(found_data):
|
|
150
|
+
print(f"MAC: {found_data[0]}")
|
|
151
|
+
print(f"Data: {found_data[1]}")
|
|
152
|
+
|
|
153
|
+
global counter
|
|
154
|
+
counter = counter - 1
|
|
155
|
+
if counter < 0:
|
|
156
|
+
run_flag.running = False
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# List of MACs of sensors which will execute callback function
|
|
160
|
+
macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
|
|
161
|
+
|
|
162
|
+
RuuviTagSensor.get_data(handle_data, macs, run_flag)
|
|
163
|
+
```
|
|
164
|
+
|
|
160
165
|
### 3. Get sensor data with observable streams (ReactiveX / RxPY)
|
|
161
166
|
|
|
162
167
|
`RuuviTagReactive` is a reactive wrapper and background process for RuuviTagSensor `get_data`. An optional MAC address list can be passed on the initializer and execution can be stopped with the stop function.
|
|
@@ -184,7 +189,7 @@ ruuvi_rx.get_subject().pipe(
|
|
|
184
189
|
ops.distinct_until_changed()
|
|
185
190
|
).subscribe(lambda x: print(f"Temperature changed: {x}"))
|
|
186
191
|
|
|
187
|
-
# Close all connections and stop
|
|
192
|
+
# Close all connections and stop Bluetooth communication
|
|
188
193
|
ruuvi_rx.stop()
|
|
189
194
|
```
|
|
190
195
|
|
|
@@ -250,7 +255,7 @@ RuuviTagSensor.find_ruuvitags()
|
|
|
250
255
|
|
|
251
256
|
### Using different Bluetooth device
|
|
252
257
|
|
|
253
|
-
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.
|
|
258
|
+
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.
|
|
254
259
|
|
|
255
260
|
```python
|
|
256
261
|
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
@@ -420,6 +425,18 @@ $ sudo apt-get install bluez bluez-hcidump
|
|
|
420
425
|
|
|
421
426
|
`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))
|
|
422
427
|
|
|
428
|
+
If you wish to test the library on Windows or macOS, enable it with `RUUVI_BLE_ADAPTER` environment variable.
|
|
429
|
+
|
|
430
|
+
```sh
|
|
431
|
+
$ export RUUVI_BLE_ADAPTER="bluez"
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
And install ptyprocess.
|
|
435
|
+
|
|
436
|
+
```sh
|
|
437
|
+
python -m pip install ptyprocess
|
|
438
|
+
```
|
|
439
|
+
|
|
423
440
|
#### BlueZ limitations
|
|
424
441
|
|
|
425
442
|
`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.
|
|
@@ -442,7 +459,7 @@ Add environment variable RUUVI_BLE_ADAPTER with value Bleak. E.g.
|
|
|
442
459
|
$ export RUUVI_BLE_ADAPTER="bleak"
|
|
443
460
|
```
|
|
444
461
|
|
|
445
|
-
Or use `os.environ`.
|
|
462
|
+
Or use `os.environ`. __NOTE:__ this must be set before importing `ruuvitag_sensor`.
|
|
446
463
|
|
|
447
464
|
```py
|
|
448
465
|
import os
|
|
@@ -476,12 +493,12 @@ Bleak-adapter has a development-time generator for dummy data, which can be usef
|
|
|
476
493
|
|
|
477
494
|
Current state and known bugs in [issue #78](https://github.com/ttu/ruuvitag-sensor/issues/78).
|
|
478
495
|
|
|
479
|
-
Bleson works with Linux, macOS and partially with Windows.
|
|
496
|
+
[Bleson](https://github.com/TheCellule/python-bleson) works with Linux, macOS and partially with Windows.
|
|
480
497
|
|
|
481
498
|
Bleson is not installed automatically with `ruuvitag-sensor` package. Install it manually from GitHub.
|
|
482
499
|
|
|
483
500
|
```sh
|
|
484
|
-
$ pip install git+https://github.com/TheCellule/python-bleson
|
|
501
|
+
$ python -m pip install git+https://github.com/TheCellule/python-bleson
|
|
485
502
|
```
|
|
486
503
|
|
|
487
504
|
Add environment variable `RUUVI_BLE_ADAPTER` with value `bleson`. E.g.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ruuvitag_sensor"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.1"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Tomi Tuhkanen", email="tomi.tuhkanen@iki.fi" },
|
|
10
10
|
]
|
|
@@ -19,6 +19,7 @@ classifiers = [
|
|
|
19
19
|
"Programming Language :: Python :: 3.9",
|
|
20
20
|
"Programming Language :: Python :: 3.10",
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
22
23
|
"License :: OSI Approved :: MIT License",
|
|
23
24
|
"Operating System :: OS Independent",
|
|
24
25
|
"Intended Audience :: Developers",
|
|
@@ -43,7 +44,7 @@ dev = [
|
|
|
43
44
|
"pylint",
|
|
44
45
|
"mypy",
|
|
45
46
|
"isort",
|
|
46
|
-
"black"
|
|
47
|
+
"black==23.3.0" # Lock black to the latest version that supports Python 3.7
|
|
47
48
|
]
|
|
48
49
|
|
|
49
50
|
[project.urls]
|
|
@@ -5,28 +5,43 @@ from typing import AsyncGenerator, Generator, List
|
|
|
5
5
|
|
|
6
6
|
from ruuvitag_sensor.ruuvi_types import MacAndRawData, RawData
|
|
7
7
|
|
|
8
|
-
# pylint: disable=import-outside-toplevel, cyclic-import
|
|
8
|
+
# pylint: disable=import-outside-toplevel, cyclic-import, too-many-return-statements
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def get_ble_adapter():
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
forced_ble_adapter = os.environ.get("RUUVI_BLE_ADAPTER", "").lower()
|
|
13
|
+
use_ruuvi_nix_from_file = "RUUVI_NIX_FROMFILE" in os.environ
|
|
14
|
+
is_ci_env = "CI" in os.environ
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
if forced_ble_adapter:
|
|
17
|
+
if "bleak" in forced_ble_adapter:
|
|
18
|
+
from ruuvitag_sensor.adapters.bleak_ble import BleCommunicationBleak
|
|
19
|
+
|
|
20
|
+
return BleCommunicationBleak()
|
|
21
|
+
if "bleson" in forced_ble_adapter:
|
|
22
|
+
from ruuvitag_sensor.adapters.bleson import BleCommunicationBleson
|
|
23
|
+
|
|
24
|
+
return BleCommunicationBleson()
|
|
25
|
+
if "bluez" in forced_ble_adapter:
|
|
26
|
+
from ruuvitag_sensor.adapters.nix_hci import BleCommunicationNix
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
return BleCommunicationNix()
|
|
29
|
+
|
|
30
|
+
raise RuntimeError(f"Unknown BLE adapter: {forced_ble_adapter}")
|
|
31
|
+
|
|
32
|
+
if use_ruuvi_nix_from_file:
|
|
21
33
|
# Emulate BleCommunicationNix by reading hcidump data from a file
|
|
22
34
|
from ruuvitag_sensor.adapters.nix_hci_file import BleCommunicationNixFile
|
|
23
35
|
|
|
24
36
|
return BleCommunicationNixFile()
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
|
|
38
|
+
if is_ci_env:
|
|
39
|
+
# Use BleCommunicationDummy for CI as it can't use BlueZ
|
|
27
40
|
from ruuvitag_sensor.adapters.dummy import BleCommunicationDummy
|
|
28
41
|
|
|
29
42
|
return BleCommunicationDummy()
|
|
43
|
+
|
|
44
|
+
# Use default adapter for platform
|
|
30
45
|
if sys.platform.startswith("win") or sys.platform.startswith("darwin"):
|
|
31
46
|
from ruuvitag_sensor.adapters.bleak_ble import BleCommunicationBleak
|
|
32
47
|
|
|
@@ -6,15 +6,16 @@ import sys
|
|
|
6
6
|
from typing import AsyncGenerator, List, Tuple
|
|
7
7
|
|
|
8
8
|
from bleak import BleakScanner
|
|
9
|
-
from bleak.backends.scanner import AdvertisementData, BLEDevice
|
|
9
|
+
from bleak.backends.scanner import AdvertisementData, AdvertisementDataCallback, BLEDevice
|
|
10
10
|
|
|
11
11
|
from ruuvitag_sensor.adapters import BleCommunicationAsync
|
|
12
|
+
from ruuvitag_sensor.adapters.utils import rssi_to_hex
|
|
12
13
|
from ruuvitag_sensor.ruuvi_types import MacAndRawData, RawData
|
|
13
14
|
|
|
14
15
|
MAC_REGEX = "[0-9a-f]{2}([:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
def _get_scanner(detection_callback):
|
|
18
|
+
def _get_scanner(detection_callback: AdvertisementDataCallback, bt_device: str = ""):
|
|
18
19
|
# NOTE: On Linux - bleak.exc.BleakError: passive scanning mode requires bluez or_patterns
|
|
19
20
|
# NOTE: On macOS - bleak.exc.BleakError: macOS does not support passive scanning
|
|
20
21
|
scanning_mode = "passive" if sys.platform.startswith("win") else "active"
|
|
@@ -25,7 +26,12 @@ def _get_scanner(detection_callback):
|
|
|
25
26
|
|
|
26
27
|
return DevBleakScanner(detection_callback, scanning_mode)
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
if bt_device:
|
|
30
|
+
return BleakScanner(
|
|
31
|
+
detection_callback=detection_callback, scanning_mode=scanning_mode, adapter=bt_device
|
|
32
|
+
) # type: ignore[arg-type]
|
|
33
|
+
|
|
34
|
+
return BleakScanner(detection_callback=detection_callback, scanning_mode=scanning_mode) # type: ignore[arg-type]
|
|
29
35
|
|
|
30
36
|
|
|
31
37
|
# TODO: Python 3.7 - TypeError: 'type' object is not subscriptable
|
|
@@ -71,15 +77,19 @@ class BleCommunicationBleak(BleCommunicationAsync):
|
|
|
71
77
|
if 1177 not in advertisement_data.manufacturer_data:
|
|
72
78
|
return
|
|
73
79
|
|
|
80
|
+
log.debug("Received data: %s", advertisement_data)
|
|
81
|
+
|
|
74
82
|
data = BleCommunicationBleak._parse_data(advertisement_data.manufacturer_data[1177])
|
|
75
83
|
|
|
76
84
|
# Add RSSI to encoded data as hex. All adapters use a common decoder.
|
|
77
|
-
data +=
|
|
85
|
+
data += rssi_to_hex(advertisement_data.rssi)
|
|
78
86
|
await queue.put((mac, data))
|
|
79
87
|
|
|
80
|
-
scanner = _get_scanner(detection_callback)
|
|
88
|
+
scanner = _get_scanner(detection_callback, bt_device)
|
|
81
89
|
await scanner.start()
|
|
82
90
|
|
|
91
|
+
log.debug("Bleak scanner started")
|
|
92
|
+
|
|
83
93
|
try:
|
|
84
94
|
while True:
|
|
85
95
|
next_item: Tuple[str, str] = await queue.get()
|
|
@@ -93,6 +103,8 @@ class BleCommunicationBleak(BleCommunicationAsync):
|
|
|
93
103
|
|
|
94
104
|
await scanner.stop()
|
|
95
105
|
|
|
106
|
+
log.debug("Bleak scanner stopped")
|
|
107
|
+
|
|
96
108
|
@staticmethod
|
|
97
109
|
async def get_first_data(mac: str, bt_device: str = "") -> RawData:
|
|
98
110
|
"""
|
|
@@ -8,6 +8,7 @@ from typing import Generator, List
|
|
|
8
8
|
from bleson import Observer, get_provider
|
|
9
9
|
|
|
10
10
|
from ruuvitag_sensor.adapters import BleCommunication
|
|
11
|
+
from ruuvitag_sensor.adapters.utils import rssi_to_hex
|
|
11
12
|
from ruuvitag_sensor.ruuvi_types import MacAndRawData, RawData
|
|
12
13
|
|
|
13
14
|
log = logging.getLogger(__name__)
|
|
@@ -56,6 +57,9 @@ class BleCommunicationBleson(BleCommunication):
|
|
|
56
57
|
data = f"FF{data.hex()}"
|
|
57
58
|
data = f"{(len(data) >> 1):02x}{data}"
|
|
58
59
|
data = f"{(len(data) >> 1):02x}{data}"
|
|
60
|
+
|
|
61
|
+
# Add RSSI to encoded data as hex. All adapters use a common decoder.
|
|
62
|
+
data += rssi_to_hex(advertisement.rssi)
|
|
59
63
|
queue.put((mac, data.upper()))
|
|
60
64
|
except GeneratorExit:
|
|
61
65
|
break
|
|
@@ -78,7 +78,7 @@ class DataFormats:
|
|
|
78
78
|
break
|
|
79
79
|
except ShortDataError as ex:
|
|
80
80
|
# Data might be from RuuviTag, but received data was invalid
|
|
81
|
-
# e.g. it's
|
|
81
|
+
# e.g. it's possible that Bluetooth stack received only partial data
|
|
82
82
|
# Set the format to None, and data to '', this allows the
|
|
83
83
|
# caller to determine that we did indeed see a Ruuvitag.
|
|
84
84
|
log.debug("Error parsing advertisement data: %s", ex)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.3.
|
|
2
|
+
Name: ruuvitag_sensor
|
|
3
|
+
Version: 2.3.1
|
|
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
|
|
@@ -36,6 +36,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
36
36
|
Classifier: Programming Language :: Python :: 3.9
|
|
37
37
|
Classifier: Programming Language :: Python :: 3.10
|
|
38
38
|
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
40
|
Classifier: License :: OSI Approved :: MIT License
|
|
40
41
|
Classifier: Operating System :: OS Independent
|
|
41
42
|
Classifier: Intended Audience :: Developers
|
|
@@ -57,7 +58,7 @@ Requires-Dist: flake8-pyproject; extra == "dev"
|
|
|
57
58
|
Requires-Dist: pylint; extra == "dev"
|
|
58
59
|
Requires-Dist: mypy; extra == "dev"
|
|
59
60
|
Requires-Dist: isort; extra == "dev"
|
|
60
|
-
Requires-Dist: black; extra == "dev"
|
|
61
|
+
Requires-Dist: black==23.3.0; extra == "dev"
|
|
61
62
|
|
|
62
63
|
RuuviTag Sensor Python Package
|
|
63
64
|
---------------------------------
|
|
@@ -66,7 +67,7 @@ RuuviTag Sensor Python Package
|
|
|
66
67
|
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
67
68
|
[](https://pypi.python.org/pypi/ruuvitag_-sensor)
|
|
68
69
|
[](https://pypistats.org/packages/ruuvitag-sensor)
|
|
69
|
-
[](https://pypi.python.org/pypi/ruuvitag-sensor/)
|
|
70
71
|
|
|
71
72
|
`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
73
|
|
|
@@ -78,18 +79,21 @@ RuuviTag Sensor Python Package
|
|
|
78
79
|
* Setup [guide](https://ruuvi.com/quick-start/)
|
|
79
80
|
* Supports [Data Format 2, 3, 4 and 5](https://docs.ruuvi.com/)
|
|
80
81
|
* __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)
|
|
87
82
|
* [Bleak](https://github.com/hbldh/bleak) communication module (Windows, macOS and Linux)
|
|
88
83
|
* Default adapter for Windows and macOS
|
|
89
84
|
* Bleak supports
|
|
90
85
|
* [Async-methods](#usage)
|
|
91
86
|
* [Observable streams](#usage)
|
|
92
87
|
* [Install guide](#Bleak)
|
|
88
|
+
* Bluez (Linux-only)
|
|
89
|
+
* Default adapter for Linux
|
|
90
|
+
* Bluez supports
|
|
91
|
+
* [Sync-methods](#usage)
|
|
92
|
+
* [Observable streams](#usage)
|
|
93
|
+
* [Install guide](#BlueZ)
|
|
94
|
+
* __NOTE:__ The BlueZ-adapter implementation uses deprecated BlueZ tools that are no longer supported.
|
|
95
|
+
* Even though BlueZ is still the default adapter, it is recommended to use the Bleak-communication adapter with Linux. Bleak will be the default adapter for Linux in the next major release.
|
|
96
|
+
* 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.
|
|
93
97
|
* Python 3.7+
|
|
94
98
|
* For Python 2.x or <3.7 support, check [installation instructions](#python-2x-and-36-and-below) for an older version
|
|
95
99
|
|
|
@@ -118,8 +122,8 @@ Full installation guide for [Raspberry PI & Raspbian](https://github.com/ttu/ruu
|
|
|
118
122
|
|
|
119
123
|
The package provides 3 ways to fetch data from sensors:
|
|
120
124
|
|
|
121
|
-
1.
|
|
122
|
-
2.
|
|
125
|
+
1. Asynchronously with async/await
|
|
126
|
+
2. Synchronously with callback
|
|
123
127
|
3. Observable streams with ReactiveX
|
|
124
128
|
|
|
125
129
|
RuuviTag sensors can be identified using MAC addresses. Methods return a tuple with MAC and sensor data payload.
|
|
@@ -128,56 +132,11 @@ RuuviTag sensors can be identified using MAC addresses. Methods return a tuple w
|
|
|
128
132
|
('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
133
|
```
|
|
130
134
|
|
|
131
|
-
### 1. Get sensor data
|
|
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
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def handle_data(found_data):
|
|
140
|
-
print(f"MAC {found_data[0]}")
|
|
141
|
-
print(f"Data {found_data[1]}")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if __name__ == "__main__":
|
|
145
|
-
RuuviTagSensor.get_data(handle_data)
|
|
146
|
-
```
|
|
147
|
-
|
|
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
|
-
|
|
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
|
|
135
|
+
### 1. Get sensor data asynchronously with async/await
|
|
177
136
|
|
|
178
137
|
__NOTE:__ Asynchronous functionality works only with `Bleak`-adapter.
|
|
179
138
|
|
|
180
|
-
`get_data_async` returns the data whenever a RuuviTag sensor broadcasts data. `get_data_async` will
|
|
139
|
+
`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
140
|
|
|
182
141
|
```py
|
|
183
142
|
import asyncio
|
|
@@ -218,6 +177,53 @@ if __name__ == "__main__":
|
|
|
218
177
|
asyncio.get_event_loop().run_until_complete(main())
|
|
219
178
|
```
|
|
220
179
|
|
|
180
|
+
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.
|
|
181
|
+
|
|
182
|
+
### 2. Get sensor data synchronously with callback
|
|
183
|
+
|
|
184
|
+
__NOTE:__ Asynchronous functionality works only with `BlueZ`-adapter.
|
|
185
|
+
|
|
186
|
+
`get_data` calls the callback whenever a RuuviTag sensor broadcasts data. This method is the preferred way to use the library with _BlueZ_.
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def handle_data(found_data):
|
|
193
|
+
print(f"MAC {found_data[0]}")
|
|
194
|
+
print(f"Data {found_data[1]}")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
if __name__ == "__main__":
|
|
198
|
+
RuuviTagSensor.get_data(handle_data)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
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.
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from ruuvitag_sensor.ruuvi import RuuviTagSensor, RunFlag
|
|
205
|
+
|
|
206
|
+
counter = 10
|
|
207
|
+
# RunFlag for stopping execution at desired time
|
|
208
|
+
run_flag = RunFlag()
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def handle_data(found_data):
|
|
212
|
+
print(f"MAC: {found_data[0]}")
|
|
213
|
+
print(f"Data: {found_data[1]}")
|
|
214
|
+
|
|
215
|
+
global counter
|
|
216
|
+
counter = counter - 1
|
|
217
|
+
if counter < 0:
|
|
218
|
+
run_flag.running = False
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# List of MACs of sensors which will execute callback function
|
|
222
|
+
macs = ["AA:2C:6A:1E:59:3D", "CC:2C:6A:1E:59:3D"]
|
|
223
|
+
|
|
224
|
+
RuuviTagSensor.get_data(handle_data, macs, run_flag)
|
|
225
|
+
```
|
|
226
|
+
|
|
221
227
|
### 3. Get sensor data with observable streams (ReactiveX / RxPY)
|
|
222
228
|
|
|
223
229
|
`RuuviTagReactive` is a reactive wrapper and background process for RuuviTagSensor `get_data`. An optional MAC address list can be passed on the initializer and execution can be stopped with the stop function.
|
|
@@ -245,7 +251,7 @@ ruuvi_rx.get_subject().pipe(
|
|
|
245
251
|
ops.distinct_until_changed()
|
|
246
252
|
).subscribe(lambda x: print(f"Temperature changed: {x}"))
|
|
247
253
|
|
|
248
|
-
# Close all connections and stop
|
|
254
|
+
# Close all connections and stop Bluetooth communication
|
|
249
255
|
ruuvi_rx.stop()
|
|
250
256
|
```
|
|
251
257
|
|
|
@@ -311,7 +317,7 @@ RuuviTagSensor.find_ruuvitags()
|
|
|
311
317
|
|
|
312
318
|
### Using different Bluetooth device
|
|
313
319
|
|
|
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.
|
|
320
|
+
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.
|
|
315
321
|
|
|
316
322
|
```python
|
|
317
323
|
from ruuvitag_sensor.ruuvi import RuuviTagSensor
|
|
@@ -481,6 +487,18 @@ $ sudo apt-get install bluez bluez-hcidump
|
|
|
481
487
|
|
|
482
488
|
`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
489
|
|
|
490
|
+
If you wish to test the library on Windows or macOS, enable it with `RUUVI_BLE_ADAPTER` environment variable.
|
|
491
|
+
|
|
492
|
+
```sh
|
|
493
|
+
$ export RUUVI_BLE_ADAPTER="bluez"
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
And install ptyprocess.
|
|
497
|
+
|
|
498
|
+
```sh
|
|
499
|
+
python -m pip install ptyprocess
|
|
500
|
+
```
|
|
501
|
+
|
|
484
502
|
#### BlueZ limitations
|
|
485
503
|
|
|
486
504
|
`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.
|
|
@@ -503,7 +521,7 @@ Add environment variable RUUVI_BLE_ADAPTER with value Bleak. E.g.
|
|
|
503
521
|
$ export RUUVI_BLE_ADAPTER="bleak"
|
|
504
522
|
```
|
|
505
523
|
|
|
506
|
-
Or use `os.environ`.
|
|
524
|
+
Or use `os.environ`. __NOTE:__ this must be set before importing `ruuvitag_sensor`.
|
|
507
525
|
|
|
508
526
|
```py
|
|
509
527
|
import os
|
|
@@ -537,12 +555,12 @@ Bleak-adapter has a development-time generator for dummy data, which can be usef
|
|
|
537
555
|
|
|
538
556
|
Current state and known bugs in [issue #78](https://github.com/ttu/ruuvitag-sensor/issues/78).
|
|
539
557
|
|
|
540
|
-
Bleson works with Linux, macOS and partially with Windows.
|
|
558
|
+
[Bleson](https://github.com/TheCellule/python-bleson) works with Linux, macOS and partially with Windows.
|
|
541
559
|
|
|
542
560
|
Bleson is not installed automatically with `ruuvitag-sensor` package. Install it manually from GitHub.
|
|
543
561
|
|
|
544
562
|
```sh
|
|
545
|
-
$ pip install git+https://github.com/TheCellule/python-bleson
|
|
563
|
+
$ python -m pip install git+https://github.com/TheCellule/python-bleson
|
|
546
564
|
```
|
|
547
565
|
|
|
548
566
|
Add environment variable `RUUVI_BLE_ADAPTER` with value `bleson`. E.g.
|
|
@@ -22,6 +22,7 @@ ruuvitag_sensor/adapters/bleson.py
|
|
|
22
22
|
ruuvitag_sensor/adapters/dummy.py
|
|
23
23
|
ruuvitag_sensor/adapters/nix_hci.py
|
|
24
24
|
ruuvitag_sensor/adapters/nix_hci_file.py
|
|
25
|
+
ruuvitag_sensor/adapters/utils.py
|
|
25
26
|
ruuvitag_sensor/adapters/development/__init__.py
|
|
26
27
|
ruuvitag_sensor/adapters/development/dev_bleak_scanner.py
|
|
27
28
|
tests/test_data_formats.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor/adapters/development/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ruuvitag_sensor-2.3.0 → ruuvitag_sensor-2.3.1}/ruuvitag_sensor.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|