btbricks 0.2.2__tar.gz → 0.2.4__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.
- {btbricks-0.2.2 → btbricks-0.2.4}/PKG-INFO +47 -23
- {btbricks-0.2.2 → btbricks-0.2.4}/README.md +44 -23
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks/__init__.py +17 -3
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks/bt.py +5 -6
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks.egg-info/PKG-INFO +47 -23
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks.egg-info/SOURCES.txt +2 -1
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks.egg-info/requires.txt +3 -0
- btbricks-0.2.4/docs/index.rst +40 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/pyproject.toml +4 -2
- btbricks-0.2.4/tests/test_precommit_checks.py +221 -0
- btbricks-0.2.2/docs/index.rst +0 -14
- {btbricks-0.2.2 → btbricks-0.2.4}/.readthedocs.yaml +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/CHANGELOG.md +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/LICENSE +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/MANIFEST.in +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks/bthub.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks/ctrl_plus.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks.egg-info/dependency_links.txt +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/btbricks.egg-info/top_level.txt +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/docs/Makefile +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/docs/conf.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/ble-midi-esp/main.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/ble_uart_light_matrix_client.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/ble_uart_light_matrix_server.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/ble_uart_simple_central.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/ble_uart_simple_peripheral.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/inventor_ble_midi_guitar.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/midi_controller_example.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_batmobile_spike_wheel.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_extreme_offroader_spike_wheel.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_hotrod_car_receiver.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_hotrod_transmitter.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_mecanum_wheels.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_multi_snake_head.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_multi_snake_seg_1.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_receiver_example.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_snake.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_snake_with_simple_remote.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_snake_with_spike_steering_wheel.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/rc_transmitter_example.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/uart_central_example.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/examples/uart_peripheral_example.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/setup.cfg +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/setup.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/tests/__init__.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/tests/test_bthub.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/tests/test_constants.py +0 -0
- {btbricks-0.2.2 → btbricks-0.2.4}/tests/test_imports.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: btbricks
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A MicroPython Bluetooth library for remote controlling LEGO hubs via BLE
|
|
5
5
|
Home-page: https://github.com/antonvh/btbricks
|
|
6
6
|
Author: Anton Vanhoucke
|
|
@@ -28,6 +28,9 @@ Requires-Dist: pytest-asyncio>=0.20.0; extra == "dev"
|
|
|
28
28
|
Requires-Dist: black>=23.0; extra == "dev"
|
|
29
29
|
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
30
30
|
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mpy-cross>=1.20; extra == "dev"
|
|
32
|
+
Requires-Dist: requests>=2.28.0; extra == "dev"
|
|
33
|
+
Requires-Dist: markdown-link-validator>=0.1.0; extra == "dev"
|
|
31
34
|
Provides-Extra: docs
|
|
32
35
|
Requires-Dist: sphinx>=4.0; extra == "docs"
|
|
33
36
|
Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
|
|
@@ -37,17 +40,24 @@ Dynamic: home-page
|
|
|
37
40
|
Dynamic: license-file
|
|
38
41
|
Dynamic: requires-python
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
<div align="center">
|
|
42
44
|
<img alt="btbricks logo" src="https://raw.githubusercontent.com/antonvh/btbricks/master/img/btbricks.png" width="200">
|
|
43
45
|
|
|
46
|
+
# btbricks
|
|
47
|
+
|
|
44
48
|
[](https://pypi.org/project/btbricks/)
|
|
45
49
|
[](LICENSE)
|
|
46
50
|
[](https://micropython.org/)
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
btbricks is MicroPython Bluetooth library. It implements **BLE** (Bluetooth 5, Bluetooth Low Energy). Of the know BLE services, this library implements **Nordic Uart Service** (NUS), **LEGO Service** and **MIDI service**. The library contains both the BLE Central (client) and BLE Peripheral (server) classes.
|
|
53
|
+
|
|
54
|
+
</div>
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
The BLE services allow controlling LEGO hubs running official firmware. You can
|
|
57
|
+
also create custom Bluetooth peripherals: RC controllers, MIDI devices, and more.
|
|
58
|
+
For LEGO hub control, a
|
|
59
|
+
[hub expansion board like the LMS-ESP32](https://www.antonsmindstorms.com/product/wifi-python-esp32-board-for-mindstorms/)
|
|
60
|
+
is recommended.
|
|
51
61
|
|
|
52
62
|
## Table of Contents
|
|
53
63
|
|
|
@@ -56,28 +66,45 @@ These BLE services allow for controlling LEGO hubs, running official firmware. T
|
|
|
56
66
|
- [Quick Start](#quick-start)
|
|
57
67
|
- [Documentation](#documentation-and-api-reference)
|
|
58
68
|
- [Supported Platforms](#supported-platforms)
|
|
59
|
-
- [Firmware Notes](#firmware-notes)
|
|
60
69
|
- [License](#license)
|
|
61
70
|
- [Author](#author)
|
|
62
71
|
|
|
63
72
|
## Features
|
|
64
73
|
|
|
65
|
-
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
-
|
|
74
|
+
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
75
|
+
MicroPython's `ubluetooth`
|
|
76
|
+
- 🎮 **Hub Control**: Control LEGO MINDSTORMS hubs, SPIKE sets, and smart hubs
|
|
77
|
+
over Bluetooth
|
|
78
|
+
- 📱 **Custom Peripherals**: Create RC controllers, MIDI controllers, and other
|
|
79
|
+
BLE peripherals compatible with LEGO hubs
|
|
80
|
+
- 🚀 **MicroPython Ready**: Optimized for MicroPython on ESP32, LEGO SPIKE, and
|
|
81
|
+
other platforms
|
|
82
|
+
- 📡 **LEGO Protocol**: Full support for LEGO Bluetooth protocols (LPF2, LPUP,
|
|
83
|
+
CTRL+)
|
|
84
|
+
- 🎛️ **Multiple Interfaces**: Nordic UART, MIDI, RC control, and native LEGO hub
|
|
85
|
+
communication
|
|
86
|
+
- ⚙️ **Advanced BLE**: Automatic MTU negotiation, descriptor handling, and
|
|
87
|
+
efficient payload management
|
|
72
88
|
|
|
73
89
|
## Installation
|
|
74
90
|
|
|
91
|
+
### Using ViperIDE Package Manager (Recommended)
|
|
92
|
+
|
|
93
|
+
1. Open **ViperIDE** on your device
|
|
94
|
+
2. Go to **Tools** → **Package Manager**
|
|
95
|
+
3. Select **Install Package via Link**
|
|
96
|
+
4. Enter the package link: `https://github.com/antonvh/btbricks.git`
|
|
97
|
+
5. Follow the on-screen prompts to complete installation
|
|
98
|
+
|
|
75
99
|
### On LMS-ESP32
|
|
76
100
|
|
|
77
|
-
The module should be included in the latest Micropython firmware from <https
|
|
78
|
-
Copy the contents from the same file in this repository inside.
|
|
101
|
+
The module should be included in the latest Micropython firmware from <https:/firmware.antonsmindstorms.com>. If not, use ViperIDE as described above.
|
|
79
102
|
|
|
80
|
-
### On
|
|
103
|
+
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
104
|
+
|
|
105
|
+
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
106
|
+
|
|
107
|
+
### Deprecated: using `micropip` from PyPI
|
|
81
108
|
|
|
82
109
|
```python
|
|
83
110
|
import micropip
|
|
@@ -86,10 +113,6 @@ await micropip.install("btbricks")
|
|
|
86
113
|
|
|
87
114
|
Note: `micropip` must be available on the target board and may require an internet connection from the device.
|
|
88
115
|
|
|
89
|
-
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
90
|
-
|
|
91
|
-
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
92
|
-
|
|
93
116
|
## Quick Start
|
|
94
117
|
|
|
95
118
|
### Connect to a LEGO Hub
|
|
@@ -119,7 +142,9 @@ if hub.is_connected():
|
|
|
119
142
|
```
|
|
120
143
|
|
|
121
144
|
### Create an RC Receiver (Hub-side)
|
|
122
|
-
|
|
145
|
+
|
|
146
|
+
Use the examples in the `examples/` folder for full, runnable code. Minimal
|
|
147
|
+
receiver/transmitter snippets:
|
|
123
148
|
|
|
124
149
|
```python
|
|
125
150
|
from btbricks import RCReceiver, R_STICK_HOR, R_STICK_VER
|
|
@@ -195,7 +220,7 @@ except KeyboardInterrupt:
|
|
|
195
220
|
|
|
196
221
|
See the full documentation and API reference at:
|
|
197
222
|
|
|
198
|
-
https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
223
|
+
[docs.antonsmindstorms.com](https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html)
|
|
199
224
|
|
|
200
225
|
### Core Classes
|
|
201
226
|
|
|
@@ -222,7 +247,6 @@ https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
|
222
247
|
- **ESP32** with MicroPython
|
|
223
248
|
- Other MicroPython boards with `ubluetooth` support
|
|
224
249
|
|
|
225
|
-
|
|
226
250
|
## License
|
|
227
251
|
|
|
228
252
|
MIT License
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<div align="center">
|
|
3
2
|
<img alt="btbricks logo" src="https://raw.githubusercontent.com/antonvh/btbricks/master/img/btbricks.png" width="200">
|
|
4
3
|
|
|
4
|
+
# btbricks
|
|
5
|
+
|
|
5
6
|
[](https://pypi.org/project/btbricks/)
|
|
6
7
|
[](LICENSE)
|
|
7
8
|
[](https://micropython.org/)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
btbricks is MicroPython Bluetooth library. It implements **BLE** (Bluetooth 5, Bluetooth Low Energy). Of the know BLE services, this library implements **Nordic Uart Service** (NUS), **LEGO Service** and **MIDI service**. The library contains both the BLE Central (client) and BLE Peripheral (server) classes.
|
|
11
|
+
|
|
12
|
+
</div>
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
The BLE services allow controlling LEGO hubs running official firmware. You can
|
|
15
|
+
also create custom Bluetooth peripherals: RC controllers, MIDI devices, and more.
|
|
16
|
+
For LEGO hub control, a
|
|
17
|
+
[hub expansion board like the LMS-ESP32](https://www.antonsmindstorms.com/product/wifi-python-esp32-board-for-mindstorms/)
|
|
18
|
+
is recommended.
|
|
12
19
|
|
|
13
20
|
## Table of Contents
|
|
14
21
|
|
|
@@ -17,28 +24,45 @@ These BLE services allow for controlling LEGO hubs, running official firmware. T
|
|
|
17
24
|
- [Quick Start](#quick-start)
|
|
18
25
|
- [Documentation](#documentation-and-api-reference)
|
|
19
26
|
- [Supported Platforms](#supported-platforms)
|
|
20
|
-
- [Firmware Notes](#firmware-notes)
|
|
21
27
|
- [License](#license)
|
|
22
28
|
- [Author](#author)
|
|
23
29
|
|
|
24
30
|
## Features
|
|
25
31
|
|
|
26
|
-
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
-
|
|
32
|
+
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
33
|
+
MicroPython's `ubluetooth`
|
|
34
|
+
- 🎮 **Hub Control**: Control LEGO MINDSTORMS hubs, SPIKE sets, and smart hubs
|
|
35
|
+
over Bluetooth
|
|
36
|
+
- 📱 **Custom Peripherals**: Create RC controllers, MIDI controllers, and other
|
|
37
|
+
BLE peripherals compatible with LEGO hubs
|
|
38
|
+
- 🚀 **MicroPython Ready**: Optimized for MicroPython on ESP32, LEGO SPIKE, and
|
|
39
|
+
other platforms
|
|
40
|
+
- 📡 **LEGO Protocol**: Full support for LEGO Bluetooth protocols (LPF2, LPUP,
|
|
41
|
+
CTRL+)
|
|
42
|
+
- 🎛️ **Multiple Interfaces**: Nordic UART, MIDI, RC control, and native LEGO hub
|
|
43
|
+
communication
|
|
44
|
+
- ⚙️ **Advanced BLE**: Automatic MTU negotiation, descriptor handling, and
|
|
45
|
+
efficient payload management
|
|
33
46
|
|
|
34
47
|
## Installation
|
|
35
48
|
|
|
49
|
+
### Using ViperIDE Package Manager (Recommended)
|
|
50
|
+
|
|
51
|
+
1. Open **ViperIDE** on your device
|
|
52
|
+
2. Go to **Tools** → **Package Manager**
|
|
53
|
+
3. Select **Install Package via Link**
|
|
54
|
+
4. Enter the package link: `https://github.com/antonvh/btbricks.git`
|
|
55
|
+
5. Follow the on-screen prompts to complete installation
|
|
56
|
+
|
|
36
57
|
### On LMS-ESP32
|
|
37
58
|
|
|
38
|
-
The module should be included in the latest Micropython firmware from <https
|
|
39
|
-
Copy the contents from the same file in this repository inside.
|
|
59
|
+
The module should be included in the latest Micropython firmware from <https:/firmware.antonsmindstorms.com>. If not, use ViperIDE as described above.
|
|
40
60
|
|
|
41
|
-
### On
|
|
61
|
+
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
62
|
+
|
|
63
|
+
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
64
|
+
|
|
65
|
+
### Deprecated: using `micropip` from PyPI
|
|
42
66
|
|
|
43
67
|
```python
|
|
44
68
|
import micropip
|
|
@@ -47,10 +71,6 @@ await micropip.install("btbricks")
|
|
|
47
71
|
|
|
48
72
|
Note: `micropip` must be available on the target board and may require an internet connection from the device.
|
|
49
73
|
|
|
50
|
-
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
51
|
-
|
|
52
|
-
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
53
|
-
|
|
54
74
|
## Quick Start
|
|
55
75
|
|
|
56
76
|
### Connect to a LEGO Hub
|
|
@@ -80,7 +100,9 @@ if hub.is_connected():
|
|
|
80
100
|
```
|
|
81
101
|
|
|
82
102
|
### Create an RC Receiver (Hub-side)
|
|
83
|
-
|
|
103
|
+
|
|
104
|
+
Use the examples in the `examples/` folder for full, runnable code. Minimal
|
|
105
|
+
receiver/transmitter snippets:
|
|
84
106
|
|
|
85
107
|
```python
|
|
86
108
|
from btbricks import RCReceiver, R_STICK_HOR, R_STICK_VER
|
|
@@ -156,7 +178,7 @@ except KeyboardInterrupt:
|
|
|
156
178
|
|
|
157
179
|
See the full documentation and API reference at:
|
|
158
180
|
|
|
159
|
-
https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
181
|
+
[docs.antonsmindstorms.com](https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html)
|
|
160
182
|
|
|
161
183
|
### Core Classes
|
|
162
184
|
|
|
@@ -183,11 +205,10 @@ https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
|
183
205
|
- **ESP32** with MicroPython
|
|
184
206
|
- Other MicroPython boards with `ubluetooth` support
|
|
185
207
|
|
|
186
|
-
|
|
187
208
|
## License
|
|
188
209
|
|
|
189
210
|
MIT License
|
|
190
211
|
|
|
191
212
|
## Author
|
|
192
213
|
|
|
193
|
-
Anton Vanhoucke
|
|
214
|
+
Anton Vanhoucke
|
|
@@ -7,7 +7,7 @@ use it to create custom Bluetooth peripherals like RC controllers or MIDI
|
|
|
7
7
|
devices compatible with LEGO hubs.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
__version__ = "0.
|
|
10
|
+
__version__ = "0.2.4"
|
|
11
11
|
__author__ = "Anton Vanhoucke"
|
|
12
12
|
__license__ = "MIT"
|
|
13
13
|
|
|
@@ -28,8 +28,22 @@ from .bt import (
|
|
|
28
28
|
SETTING1,
|
|
29
29
|
SETTING2,
|
|
30
30
|
)
|
|
31
|
-
from .bthub import
|
|
32
|
-
|
|
31
|
+
from .bthub import (
|
|
32
|
+
BtHub,
|
|
33
|
+
OFF,
|
|
34
|
+
PINK,
|
|
35
|
+
PURPLE,
|
|
36
|
+
DARK_BLUE,
|
|
37
|
+
BLUE,
|
|
38
|
+
TEAL,
|
|
39
|
+
GREEN,
|
|
40
|
+
YELLOW,
|
|
41
|
+
ORANGE,
|
|
42
|
+
RED,
|
|
43
|
+
WHITE,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
from .bthub import BtHub as SmartHub
|
|
33
47
|
|
|
34
48
|
__all__ = [
|
|
35
49
|
"BLEHandler",
|
|
@@ -299,7 +299,6 @@ class BLEHandler:
|
|
|
299
299
|
|
|
300
300
|
def __init__(self, debug=False):
|
|
301
301
|
self._ble = ubluetooth.BLE()
|
|
302
|
-
self._ble.config(rxbuf=TARGET_MTU)
|
|
303
302
|
self._ble.active(True)
|
|
304
303
|
try:
|
|
305
304
|
self._ble.gap_disconnect(1025) # Disconnect in case of previous crash
|
|
@@ -1103,16 +1102,16 @@ class RCReceiver(UARTPeripheral):
|
|
|
1103
1102
|
|
|
1104
1103
|
"""
|
|
1105
1104
|
try:
|
|
1106
|
-
|
|
1105
|
+
state = struct.unpack("bbbbBBhhB", self.read_buffer)
|
|
1107
1106
|
except:
|
|
1108
|
-
|
|
1107
|
+
state = [0] * 9
|
|
1109
1108
|
if indices:
|
|
1110
1109
|
if len(indices) == 1:
|
|
1111
|
-
return
|
|
1110
|
+
return state[indices[0]]
|
|
1112
1111
|
else:
|
|
1113
|
-
return [
|
|
1112
|
+
return [state[i] for i in indices]
|
|
1114
1113
|
else:
|
|
1115
|
-
return
|
|
1114
|
+
return state
|
|
1116
1115
|
|
|
1117
1116
|
|
|
1118
1117
|
class RCTransmitter(UARTCentral):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: btbricks
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A MicroPython Bluetooth library for remote controlling LEGO hubs via BLE
|
|
5
5
|
Home-page: https://github.com/antonvh/btbricks
|
|
6
6
|
Author: Anton Vanhoucke
|
|
@@ -28,6 +28,9 @@ Requires-Dist: pytest-asyncio>=0.20.0; extra == "dev"
|
|
|
28
28
|
Requires-Dist: black>=23.0; extra == "dev"
|
|
29
29
|
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
30
30
|
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mpy-cross>=1.20; extra == "dev"
|
|
32
|
+
Requires-Dist: requests>=2.28.0; extra == "dev"
|
|
33
|
+
Requires-Dist: markdown-link-validator>=0.1.0; extra == "dev"
|
|
31
34
|
Provides-Extra: docs
|
|
32
35
|
Requires-Dist: sphinx>=4.0; extra == "docs"
|
|
33
36
|
Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
|
|
@@ -37,17 +40,24 @@ Dynamic: home-page
|
|
|
37
40
|
Dynamic: license-file
|
|
38
41
|
Dynamic: requires-python
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
<div align="center">
|
|
42
44
|
<img alt="btbricks logo" src="https://raw.githubusercontent.com/antonvh/btbricks/master/img/btbricks.png" width="200">
|
|
43
45
|
|
|
46
|
+
# btbricks
|
|
47
|
+
|
|
44
48
|
[](https://pypi.org/project/btbricks/)
|
|
45
49
|
[](LICENSE)
|
|
46
50
|
[](https://micropython.org/)
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
btbricks is MicroPython Bluetooth library. It implements **BLE** (Bluetooth 5, Bluetooth Low Energy). Of the know BLE services, this library implements **Nordic Uart Service** (NUS), **LEGO Service** and **MIDI service**. The library contains both the BLE Central (client) and BLE Peripheral (server) classes.
|
|
53
|
+
|
|
54
|
+
</div>
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
The BLE services allow controlling LEGO hubs running official firmware. You can
|
|
57
|
+
also create custom Bluetooth peripherals: RC controllers, MIDI devices, and more.
|
|
58
|
+
For LEGO hub control, a
|
|
59
|
+
[hub expansion board like the LMS-ESP32](https://www.antonsmindstorms.com/product/wifi-python-esp32-board-for-mindstorms/)
|
|
60
|
+
is recommended.
|
|
51
61
|
|
|
52
62
|
## Table of Contents
|
|
53
63
|
|
|
@@ -56,28 +66,45 @@ These BLE services allow for controlling LEGO hubs, running official firmware. T
|
|
|
56
66
|
- [Quick Start](#quick-start)
|
|
57
67
|
- [Documentation](#documentation-and-api-reference)
|
|
58
68
|
- [Supported Platforms](#supported-platforms)
|
|
59
|
-
- [Firmware Notes](#firmware-notes)
|
|
60
69
|
- [License](#license)
|
|
61
70
|
- [Author](#author)
|
|
62
71
|
|
|
63
72
|
## Features
|
|
64
73
|
|
|
65
|
-
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
-
|
|
74
|
+
- 🔌 **BLE Communication**: Comprehensive Bluetooth Low Energy support via
|
|
75
|
+
MicroPython's `ubluetooth`
|
|
76
|
+
- 🎮 **Hub Control**: Control LEGO MINDSTORMS hubs, SPIKE sets, and smart hubs
|
|
77
|
+
over Bluetooth
|
|
78
|
+
- 📱 **Custom Peripherals**: Create RC controllers, MIDI controllers, and other
|
|
79
|
+
BLE peripherals compatible with LEGO hubs
|
|
80
|
+
- 🚀 **MicroPython Ready**: Optimized for MicroPython on ESP32, LEGO SPIKE, and
|
|
81
|
+
other platforms
|
|
82
|
+
- 📡 **LEGO Protocol**: Full support for LEGO Bluetooth protocols (LPF2, LPUP,
|
|
83
|
+
CTRL+)
|
|
84
|
+
- 🎛️ **Multiple Interfaces**: Nordic UART, MIDI, RC control, and native LEGO hub
|
|
85
|
+
communication
|
|
86
|
+
- ⚙️ **Advanced BLE**: Automatic MTU negotiation, descriptor handling, and
|
|
87
|
+
efficient payload management
|
|
72
88
|
|
|
73
89
|
## Installation
|
|
74
90
|
|
|
91
|
+
### Using ViperIDE Package Manager (Recommended)
|
|
92
|
+
|
|
93
|
+
1. Open **ViperIDE** on your device
|
|
94
|
+
2. Go to **Tools** → **Package Manager**
|
|
95
|
+
3. Select **Install Package via Link**
|
|
96
|
+
4. Enter the package link: `https://github.com/antonvh/btbricks.git`
|
|
97
|
+
5. Follow the on-screen prompts to complete installation
|
|
98
|
+
|
|
75
99
|
### On LMS-ESP32
|
|
76
100
|
|
|
77
|
-
The module should be included in the latest Micropython firmware from <https
|
|
78
|
-
Copy the contents from the same file in this repository inside.
|
|
101
|
+
The module should be included in the latest Micropython firmware from <https:/firmware.antonsmindstorms.com>. If not, use ViperIDE as described above.
|
|
79
102
|
|
|
80
|
-
### On
|
|
103
|
+
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
104
|
+
|
|
105
|
+
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
106
|
+
|
|
107
|
+
### Deprecated: using `micropip` from PyPI
|
|
81
108
|
|
|
82
109
|
```python
|
|
83
110
|
import micropip
|
|
@@ -86,10 +113,6 @@ await micropip.install("btbricks")
|
|
|
86
113
|
|
|
87
114
|
Note: `micropip` must be available on the target board and may require an internet connection from the device.
|
|
88
115
|
|
|
89
|
-
### On SPIKE Legacy or MINDSTORMS Robot Inventor
|
|
90
|
-
|
|
91
|
-
Use the installer script in mpy-robot-tools: <https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py>
|
|
92
|
-
|
|
93
116
|
## Quick Start
|
|
94
117
|
|
|
95
118
|
### Connect to a LEGO Hub
|
|
@@ -119,7 +142,9 @@ if hub.is_connected():
|
|
|
119
142
|
```
|
|
120
143
|
|
|
121
144
|
### Create an RC Receiver (Hub-side)
|
|
122
|
-
|
|
145
|
+
|
|
146
|
+
Use the examples in the `examples/` folder for full, runnable code. Minimal
|
|
147
|
+
receiver/transmitter snippets:
|
|
123
148
|
|
|
124
149
|
```python
|
|
125
150
|
from btbricks import RCReceiver, R_STICK_HOR, R_STICK_VER
|
|
@@ -195,7 +220,7 @@ except KeyboardInterrupt:
|
|
|
195
220
|
|
|
196
221
|
See the full documentation and API reference at:
|
|
197
222
|
|
|
198
|
-
https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
223
|
+
[docs.antonsmindstorms.com](https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html)
|
|
199
224
|
|
|
200
225
|
### Core Classes
|
|
201
226
|
|
|
@@ -222,7 +247,6 @@ https://docs.antonsmindstorms.com/en/latest/Software/btbricks/docs/index.html
|
|
|
222
247
|
- **ESP32** with MicroPython
|
|
223
248
|
- Other MicroPython boards with `ubluetooth` support
|
|
224
249
|
|
|
225
|
-
|
|
226
250
|
## License
|
|
227
251
|
|
|
228
252
|
MIT License
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
btbricks documentation
|
|
2
|
+
========================
|
|
3
|
+
|
|
4
|
+
.. image:: ../img/btbricks.png
|
|
5
|
+
:alt: btbricks logo
|
|
6
|
+
:align: center
|
|
7
|
+
:width: 200px
|
|
8
|
+
|
|
9
|
+
Installation
|
|
10
|
+
============
|
|
11
|
+
|
|
12
|
+
Using ViperIDE Package Manager (Recommended)
|
|
13
|
+
--------------------------------------------
|
|
14
|
+
|
|
15
|
+
1. Open **ViperIDE** on your device
|
|
16
|
+
2. Go to **Tools** → **Package Manager**
|
|
17
|
+
3. Select **Install Package via Link**
|
|
18
|
+
4. Enter the package link: ``https://github.com/antonvh/btbricks``
|
|
19
|
+
5. Follow the on-screen prompts to complete installation
|
|
20
|
+
|
|
21
|
+
Using micropip from PyPI
|
|
22
|
+
------------------------
|
|
23
|
+
|
|
24
|
+
.. code-block:: python
|
|
25
|
+
|
|
26
|
+
import micropip
|
|
27
|
+
await micropip.install("btbricks")
|
|
28
|
+
|
|
29
|
+
Note: ``micropip`` must be available on the target board and may require an internet connection from the device.
|
|
30
|
+
|
|
31
|
+
API Reference
|
|
32
|
+
=============
|
|
33
|
+
|
|
34
|
+
.. automodule:: btbricks
|
|
35
|
+
:members:
|
|
36
|
+
:undoc-members:
|
|
37
|
+
:show-inheritance:
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "btbricks"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.4"
|
|
8
8
|
description = "A MicroPython Bluetooth library for remote controlling LEGO hubs via BLE"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.7"
|
|
@@ -33,6 +33,9 @@ dev = [
|
|
|
33
33
|
"black>=23.0",
|
|
34
34
|
"flake8>=5.0",
|
|
35
35
|
"mypy>=1.0",
|
|
36
|
+
"mpy-cross>=1.20",
|
|
37
|
+
"requests>=2.28.0",
|
|
38
|
+
"markdown-link-validator>=0.1.0",
|
|
36
39
|
]
|
|
37
40
|
docs = [
|
|
38
41
|
"sphinx>=4.0",
|
|
@@ -58,4 +61,3 @@ disallow_untyped_defs = false
|
|
|
58
61
|
|
|
59
62
|
[tool.pytest.ini_options]
|
|
60
63
|
testpaths = ["tests"]
|
|
61
|
-
asyncio_mode = "auto"
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""Pre-commit checks for dead links and mpy-cross compilation."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import subprocess
|
|
6
|
+
import tempfile
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import List, Set
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
import requests
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def find_markdown_files() -> List[Path]:
|
|
15
|
+
"""Find all markdown files in the project."""
|
|
16
|
+
root = Path(__file__).parent.parent
|
|
17
|
+
md_files = []
|
|
18
|
+
for ext in ["*.md", "*.MD"]:
|
|
19
|
+
md_files.extend(root.glob(ext))
|
|
20
|
+
md_files.extend(root.glob(f"**/{ext}"))
|
|
21
|
+
|
|
22
|
+
# Exclude hidden directories and common ignore patterns
|
|
23
|
+
excluded = {".git", "node_modules", ".venv", "venv", "__pycache__"}
|
|
24
|
+
return [
|
|
25
|
+
f for f in md_files if not any(part.startswith(".") or part in excluded for part in f.parts)
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def extract_urls_from_markdown(file_path: Path) -> Set[str]:
|
|
30
|
+
"""Extract all HTTP(S) URLs from a markdown file."""
|
|
31
|
+
content = file_path.read_text(encoding="utf-8", errors="ignore")
|
|
32
|
+
|
|
33
|
+
# Match markdown links [text](url) and plain URLs
|
|
34
|
+
url_pattern = r"https?://[^\s\)<>\"\']+"
|
|
35
|
+
urls = set(re.findall(url_pattern, content))
|
|
36
|
+
|
|
37
|
+
# Clean up any trailing punctuation that might have been captured
|
|
38
|
+
cleaned_urls = set()
|
|
39
|
+
for url in urls:
|
|
40
|
+
# Remove trailing punctuation and backticks
|
|
41
|
+
url = re.sub(r'[.,;:!?\)`]+$', "", url)
|
|
42
|
+
cleaned_urls.add(url)
|
|
43
|
+
|
|
44
|
+
return cleaned_urls
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def is_url_valid(url: str, timeout: int = 10) -> tuple[bool, int]:
|
|
48
|
+
"""Check if a URL is accessible.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
tuple of (is_valid, http_code)
|
|
52
|
+
"""
|
|
53
|
+
# Skip localhost and example URLs
|
|
54
|
+
if "localhost" in url or "example.com" in url or "127.0.0.1" in url:
|
|
55
|
+
return True, 200
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# Use HEAD request first (faster)
|
|
59
|
+
response = requests.head(
|
|
60
|
+
url,
|
|
61
|
+
timeout=timeout,
|
|
62
|
+
allow_redirects=True,
|
|
63
|
+
headers={"User-Agent": "Mozilla/5.0 (compatible; LinkChecker/1.0)"},
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Some servers don't support HEAD, try GET if HEAD fails
|
|
67
|
+
if response.status_code >= 400:
|
|
68
|
+
response = requests.get(
|
|
69
|
+
url,
|
|
70
|
+
timeout=timeout,
|
|
71
|
+
allow_redirects=True,
|
|
72
|
+
headers={"User-Agent": "Mozilla/5.0 (compatible; LinkChecker/1.0)"},
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Consider 200-399 as valid
|
|
76
|
+
return response.status_code < 400, response.status_code
|
|
77
|
+
|
|
78
|
+
except requests.exceptions.Timeout:
|
|
79
|
+
return False, 408 # Request Timeout
|
|
80
|
+
except requests.exceptions.ConnectionError:
|
|
81
|
+
return False, 0 # Connection failed
|
|
82
|
+
except requests.exceptions.RequestException:
|
|
83
|
+
return False, 0 # Other request errors
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def find_python_files() -> List[Path]:
|
|
87
|
+
"""Find all Python files in the btbricks package."""
|
|
88
|
+
root = Path(__file__).parent.parent
|
|
89
|
+
btbricks_dir = root / "btbricks"
|
|
90
|
+
|
|
91
|
+
if not btbricks_dir.exists():
|
|
92
|
+
return []
|
|
93
|
+
|
|
94
|
+
py_files = []
|
|
95
|
+
for py_file in btbricks_dir.rglob("*.py"):
|
|
96
|
+
# Skip __pycache__ and other temp directories
|
|
97
|
+
if "__pycache__" not in py_file.parts:
|
|
98
|
+
py_files.append(py_file)
|
|
99
|
+
|
|
100
|
+
return py_files
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def check_mpy_cross_available() -> bool:
|
|
104
|
+
"""Check if mpy-cross is available."""
|
|
105
|
+
# Try to find mpy-cross in venv first
|
|
106
|
+
venv_mpy_cross = Path(__file__).parent.parent / ".venv" / "bin" / "mpy-cross"
|
|
107
|
+
if venv_mpy_cross.exists():
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
# Fall back to checking PATH
|
|
111
|
+
try:
|
|
112
|
+
result = subprocess.run(
|
|
113
|
+
["mpy-cross", "--version"], capture_output=True, text=True, timeout=5
|
|
114
|
+
)
|
|
115
|
+
return result.returncode == 0
|
|
116
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def compile_with_mpy_cross(py_file: Path) -> tuple[bool, str]:
|
|
121
|
+
"""Try to compile a Python file with mpy-cross.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
tuple of (success, error_message)
|
|
125
|
+
"""
|
|
126
|
+
# Find mpy-cross command
|
|
127
|
+
venv_mpy_cross = Path(__file__).parent.parent / ".venv" / "bin" / "mpy-cross"
|
|
128
|
+
mpy_cross_cmd = str(venv_mpy_cross) if venv_mpy_cross.exists() else "mpy-cross"
|
|
129
|
+
|
|
130
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
131
|
+
output_file = Path(tmpdir) / "temp.mpy"
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
result = subprocess.run(
|
|
135
|
+
[mpy_cross_cmd, str(py_file), "-o", str(output_file)],
|
|
136
|
+
capture_output=True,
|
|
137
|
+
text=True,
|
|
138
|
+
timeout=30,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if result.returncode == 0:
|
|
142
|
+
return True, ""
|
|
143
|
+
else:
|
|
144
|
+
return False, result.stderr or result.stdout
|
|
145
|
+
|
|
146
|
+
except subprocess.TimeoutExpired:
|
|
147
|
+
return False, "Compilation timeout"
|
|
148
|
+
except Exception as e:
|
|
149
|
+
return False, str(e)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class TestDeadLinks:
|
|
153
|
+
"""Test for dead links in markdown files."""
|
|
154
|
+
|
|
155
|
+
def test_no_dead_links(self):
|
|
156
|
+
"""Check that all links in markdown files are valid."""
|
|
157
|
+
md_files = find_markdown_files()
|
|
158
|
+
|
|
159
|
+
if not md_files:
|
|
160
|
+
pytest.skip("No markdown files found")
|
|
161
|
+
|
|
162
|
+
all_urls = set()
|
|
163
|
+
url_sources = {} # Track which file each URL came from
|
|
164
|
+
|
|
165
|
+
for md_file in md_files:
|
|
166
|
+
urls = extract_urls_from_markdown(md_file)
|
|
167
|
+
for url in urls:
|
|
168
|
+
all_urls.add(url)
|
|
169
|
+
if url not in url_sources:
|
|
170
|
+
url_sources[url] = set()
|
|
171
|
+
url_sources[url].add(md_file.name)
|
|
172
|
+
|
|
173
|
+
if not all_urls:
|
|
174
|
+
pytest.skip("No URLs found in markdown files")
|
|
175
|
+
|
|
176
|
+
dead_links = []
|
|
177
|
+
|
|
178
|
+
for url in sorted(all_urls):
|
|
179
|
+
is_valid, http_code = is_url_valid(url)
|
|
180
|
+
if not is_valid:
|
|
181
|
+
sources = ", ".join(sorted(url_sources[url]))
|
|
182
|
+
dead_links.append(f"{url} (HTTP {http_code}) in {sources}")
|
|
183
|
+
|
|
184
|
+
if dead_links:
|
|
185
|
+
error_msg = f"Found {len(dead_links)} dead link(s):\n"
|
|
186
|
+
error_msg += "\n".join(f" - {link}" for link in dead_links)
|
|
187
|
+
pytest.fail(error_msg)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class TestMpyCrossCompilation:
|
|
191
|
+
"""Test that all Python files compile with mpy-cross."""
|
|
192
|
+
|
|
193
|
+
def test_mpy_cross_installed(self):
|
|
194
|
+
"""Check that mpy-cross is available."""
|
|
195
|
+
if not check_mpy_cross_available():
|
|
196
|
+
pytest.fail(
|
|
197
|
+
"mpy-cross is not installed or not available in PATH.\n"
|
|
198
|
+
"Install with: pip install mpy-cross"
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def test_all_files_compile(self):
|
|
202
|
+
"""Check that all Python files in btbricks/ compile with mpy-cross."""
|
|
203
|
+
if not check_mpy_cross_available():
|
|
204
|
+
pytest.skip("mpy-cross not available")
|
|
205
|
+
|
|
206
|
+
py_files = find_python_files()
|
|
207
|
+
|
|
208
|
+
if not py_files:
|
|
209
|
+
pytest.skip("No Python files found in btbricks/")
|
|
210
|
+
|
|
211
|
+
failed_compilations = []
|
|
212
|
+
|
|
213
|
+
for py_file in py_files:
|
|
214
|
+
success, error = compile_with_mpy_cross(py_file)
|
|
215
|
+
if not success:
|
|
216
|
+
failed_compilations.append(f"{py_file.name}: {error}")
|
|
217
|
+
|
|
218
|
+
if failed_compilations:
|
|
219
|
+
error_msg = f"Failed to compile {len(failed_compilations)} file(s) with mpy-cross:\n"
|
|
220
|
+
error_msg += "\n".join(f" - {failure}" for failure in failed_compilations)
|
|
221
|
+
pytest.fail(error_msg)
|
btbricks-0.2.2/docs/index.rst
DELETED
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|