blynk-provisioning 0.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.
- blynk_provisioning-0.1.0/LICENSE +21 -0
- blynk_provisioning-0.1.0/PKG-INFO +208 -0
- blynk_provisioning-0.1.0/README.md +184 -0
- blynk_provisioning-0.1.0/pyproject.toml +38 -0
- blynk_provisioning-0.1.0/setup.cfg +4 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning/__init__.py +12 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning/_ble.py +861 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning/credentials.py +352 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning.egg-info/PKG-INFO +208 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning.egg-info/SOURCES.txt +11 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning.egg-info/dependency_links.txt +1 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning.egg-info/requires.txt +3 -0
- blynk_provisioning-0.1.0/src/blynk_provisioning.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anthony Elder
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blynk-provisioning
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial, experimental Blynk.Inject-style BLE provisioning for Linux/Raspberry Pi - get a device's Blynk credentials by pairing with the Blynk app
|
|
5
|
+
Author: Anthony Elder
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/anthony-blynk/blynk-provisioning
|
|
8
|
+
Project-URL: Issues, https://github.com/anthony-blynk/blynk-provisioning/issues
|
|
9
|
+
Keywords: blynk,blynk-inject,ble,bluetooth,provisioning,raspberry-pi,iot,mqtt
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: Home Automation
|
|
16
|
+
Classifier: Topic :: System :: Hardware
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: paho-mqtt<3,>=2.0
|
|
21
|
+
Requires-Dist: python-dotenv>=1.0
|
|
22
|
+
Requires-Dist: bluez-peripheral<0.2,>=0.1.7
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# blynk-provisioning
|
|
26
|
+
|
|
27
|
+
> **Unofficial and experimental.** A personal proof of concept, not a Blynk
|
|
28
|
+
> product and not covered by Blynk support. Expect changes.
|
|
29
|
+
|
|
30
|
+
Get a device's Blynk credentials via BLE pairing with the Blynk app, so a
|
|
31
|
+
plain Python script can talk to Blynk directly - no need for the full
|
|
32
|
+
[blynk-edge-agent](https://github.com/anthony-blynk/blynk-edge-agent) stack.
|
|
33
|
+
|
|
34
|
+
**Scope, deliberately narrow:** this library does exactly one thing - get
|
|
35
|
+
your device paired with the Blynk app and hand back a real, working
|
|
36
|
+
identity (server + auth token). It doesn't wrap the Blynk MQTT device
|
|
37
|
+
protocol itself (topics, datastreams, OTA, any of that) - `paho-mqtt`
|
|
38
|
+
already does MQTT well, and Blynk's own topic conventions
|
|
39
|
+
(`ds/<name>`, `get/ds`, `downlink/ds/<name>`) are simple enough to use
|
|
40
|
+
directly. If you want the fuller device SDK experience, see Blynk's
|
|
41
|
+
Edgent libraries for Arduino/ESP-IDF, or the
|
|
42
|
+
[edge-agent](https://github.com/anthony-blynk/blynk-edge-agent) project,
|
|
43
|
+
which do considerably more than this.
|
|
44
|
+
|
|
45
|
+
**One identity per template, per physical machine** - not one per script,
|
|
46
|
+
and not one overall. Blynk's own device model is one real device = one
|
|
47
|
+
real auth token = one connection; this library doesn't try to paper over
|
|
48
|
+
that. Two scripts using the *same* identity at the same time will
|
|
49
|
+
disconnect each other. A machine provisioning more than one template gets
|
|
50
|
+
a separate identity for each (see "Multiple templates" below) - that's
|
|
51
|
+
normal, not a workaround. If you need several logical devices represented
|
|
52
|
+
under a *single* template from one machine, that's what the edge-agent's
|
|
53
|
+
own MQTT Gateway feature is for - it doesn't need BLE pairing per device
|
|
54
|
+
at all.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
Linux only - needs BlueZ and NetworkManager, reached over D-Bus (tested on
|
|
59
|
+
Raspberry Pi OS). Not for Windows/macOS.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
sudo pip install --break-system-packages blynk-provisioning
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Installing with `sudo` makes it available to both `python3` and
|
|
66
|
+
`sudo python3`, so the examples below work as written.
|
|
67
|
+
`--break-system-packages` is needed because Raspberry Pi OS (like other
|
|
68
|
+
recent Debian-based systems) otherwise refuses to `pip install` outside a
|
|
69
|
+
virtual environment. pip's "Running pip as the 'root' user" warning is
|
|
70
|
+
expected with this install method.
|
|
71
|
+
|
|
72
|
+
**First pairing usually needs `sudo`** - WiFi setup goes through
|
|
73
|
+
NetworkManager, which only allows it from a local console session, not over
|
|
74
|
+
SSH. If the device is already on the WiFi network you choose in the app,
|
|
75
|
+
pairing leaves NetworkManager alone and works without `sudo`.
|
|
76
|
+
|
|
77
|
+
<details>
|
|
78
|
+
<summary>Prefer a virtual environment?</summary>
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python3 -m venv ~/blynk-venv
|
|
82
|
+
~/blynk-venv/bin/pip install blynk-provisioning
|
|
83
|
+
source ~/blynk-venv/bin/activate # then plain python3 uses it
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`sudo` ignores an activated venv, so for runs that need it, point it at the
|
|
87
|
+
venv's Python: `sudo ~/blynk-venv/bin/python3 my_script.py`.
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
## Quick test - Subscribe and print datastream updates
|
|
91
|
+
|
|
92
|
+
Paste and run as-is (swap in your own template ID for TMPLxxxxxxxx first):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python3 -c "
|
|
96
|
+
import blynk_provisioning
|
|
97
|
+
creds = blynk_provisioning.get_credentials(template_id='TMPLxxxxxxxx')
|
|
98
|
+
client = creds.get_mqtt_client()
|
|
99
|
+
client.on_message = lambda c, u, m: print(f'{m.topic}: {m.payload.decode()}')
|
|
100
|
+
client.subscribe('downlink/#')
|
|
101
|
+
client.loop_forever()
|
|
102
|
+
"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## One-off publish
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
python3 -c "
|
|
109
|
+
import paho.mqtt.publish as publish
|
|
110
|
+
import blynk_provisioning
|
|
111
|
+
creds = blynk_provisioning.get_credentials(template_id='TMPLxxxxxxxx')
|
|
112
|
+
publish.single('ds/Test', payload='42', **creds.connection_kwargs())
|
|
113
|
+
"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The first run for a given template ID blocks until you've paired via the
|
|
117
|
+
Blynk app (BLE advertising starts, same flow as pairing a new edge-agent
|
|
118
|
+
device). Every run after that returns instantly - credentials are cached in `~/.blynk/credentials.env`.
|
|
119
|
+
|
|
120
|
+
`get_mqtt_client()` connects for you but doesn't start the network loop - call
|
|
121
|
+
`client.loop_forever()` to block and process messages, or
|
|
122
|
+
`client.loop_start()` if your script needs to do other things
|
|
123
|
+
concurrently.
|
|
124
|
+
|
|
125
|
+
## Firmware version
|
|
126
|
+
|
|
127
|
+
Blynk shows a firmware version for each device - `unknown` unless you pass
|
|
128
|
+
your script's own version:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
creds = blynk_provisioning.get_credentials(template_id="TMPLxxxxxxxx", fw_version="1.0.3")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The build date shown alongside it is the script file's last-modified time.
|
|
135
|
+
|
|
136
|
+
## Debug output
|
|
137
|
+
|
|
138
|
+
To see every message exchanged with the Blynk app during pairing, plus the
|
|
139
|
+
MQTT checkin, pass `debug=True` to `get_credentials()` or set `BLYNK_DEBUG=1`:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
BLYNK_DEBUG=1 python3 my_script.py
|
|
143
|
+
sudo BLYNK_DEBUG=1 python3 my_script.py # not "BLYNK_DEBUG=1 sudo ..." - sudo drops it
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The auth token is shown as its last 4 characters; WiFi password and SIM PIN
|
|
147
|
+
are masked. Only this library's own log is enabled - paho and D-Bus stay quiet.
|
|
148
|
+
|
|
149
|
+
## Multiple templates
|
|
150
|
+
|
|
151
|
+
One identity per template, not one per script (see above) - but a machine
|
|
152
|
+
can legitimately need more than one template's identity (e.g. two
|
|
153
|
+
different kinds of sensor script running on the same Pi). Calling
|
|
154
|
+
`get_credentials()` with a different `template_id` provisions and stores a
|
|
155
|
+
separate identity alongside any already in the same file - they're keyed
|
|
156
|
+
by template internally, so they don't overwrite each other:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
temp_creds = blynk_provisioning.get_credentials(template_id="TMPL_temperature")
|
|
160
|
+
door_creds = blynk_provisioning.get_credentials(template_id="TMPL_doorsensor")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Both get their own BLE pairing ceremony the first time, and both are
|
|
164
|
+
cached in `~/.blynk/credentials.env` from then on.
|
|
165
|
+
|
|
166
|
+
## Custom vendor prefix
|
|
167
|
+
|
|
168
|
+
Defaults to advertising as `"Blynk Device-XXXX"` over BLE. Enterprise/
|
|
169
|
+
white-labeled Blynk apps are typically configured to only discover devices
|
|
170
|
+
broadcasting their own vendor prefix, so pass yours if that applies:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
creds = blynk_provisioning.get_credentials(
|
|
174
|
+
template_id="TMPLxxxxxxxx",
|
|
175
|
+
vendor_prefix="Acme",
|
|
176
|
+
)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Sharing identity with a co-located edge-agent
|
|
180
|
+
|
|
181
|
+
If this script runs on the same machine as a full edge-agent install,
|
|
182
|
+
point at its own credentials file instead of provisioning a separate
|
|
183
|
+
identity:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
creds = blynk_provisioning.get_credentials(
|
|
187
|
+
template_id="TMPLxxxxxxxx",
|
|
188
|
+
path="/opt/blynk/blynk.env",
|
|
189
|
+
)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Re-pairing (device deleted on the server)
|
|
193
|
+
|
|
194
|
+
Deleting the device in Blynk invalidates its token, but the local copy
|
|
195
|
+
stays. `get_mqtt_client()` then raises `CredentialsRejectedError` saying so.
|
|
196
|
+
To pair again, replacing just that template's stored identity:
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
creds = blynk_provisioning.get_credentials(template_id="TMPLxxxxxxxx", reprovision=True)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Status
|
|
203
|
+
|
|
204
|
+
Experimental (`0.1.0`), tested on a Raspberry Pi 5 with Raspberry Pi OS.
|
|
205
|
+
The BLE/NetworkManager/ModemManager engine underneath is adapted from
|
|
206
|
+
blynk-edge-agent's own `agent/ble_provisioning.py` (real, hardware-tested
|
|
207
|
+
code). Issues and feedback welcome on
|
|
208
|
+
[GitHub](https://github.com/anthony-blynk/blynk-provisioning/issues).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# blynk-provisioning
|
|
2
|
+
|
|
3
|
+
> **Unofficial and experimental.** A personal proof of concept, not a Blynk
|
|
4
|
+
> product and not covered by Blynk support. Expect changes.
|
|
5
|
+
|
|
6
|
+
Get a device's Blynk credentials via BLE pairing with the Blynk app, so a
|
|
7
|
+
plain Python script can talk to Blynk directly - no need for the full
|
|
8
|
+
[blynk-edge-agent](https://github.com/anthony-blynk/blynk-edge-agent) stack.
|
|
9
|
+
|
|
10
|
+
**Scope, deliberately narrow:** this library does exactly one thing - get
|
|
11
|
+
your device paired with the Blynk app and hand back a real, working
|
|
12
|
+
identity (server + auth token). It doesn't wrap the Blynk MQTT device
|
|
13
|
+
protocol itself (topics, datastreams, OTA, any of that) - `paho-mqtt`
|
|
14
|
+
already does MQTT well, and Blynk's own topic conventions
|
|
15
|
+
(`ds/<name>`, `get/ds`, `downlink/ds/<name>`) are simple enough to use
|
|
16
|
+
directly. If you want the fuller device SDK experience, see Blynk's
|
|
17
|
+
Edgent libraries for Arduino/ESP-IDF, or the
|
|
18
|
+
[edge-agent](https://github.com/anthony-blynk/blynk-edge-agent) project,
|
|
19
|
+
which do considerably more than this.
|
|
20
|
+
|
|
21
|
+
**One identity per template, per physical machine** - not one per script,
|
|
22
|
+
and not one overall. Blynk's own device model is one real device = one
|
|
23
|
+
real auth token = one connection; this library doesn't try to paper over
|
|
24
|
+
that. Two scripts using the *same* identity at the same time will
|
|
25
|
+
disconnect each other. A machine provisioning more than one template gets
|
|
26
|
+
a separate identity for each (see "Multiple templates" below) - that's
|
|
27
|
+
normal, not a workaround. If you need several logical devices represented
|
|
28
|
+
under a *single* template from one machine, that's what the edge-agent's
|
|
29
|
+
own MQTT Gateway feature is for - it doesn't need BLE pairing per device
|
|
30
|
+
at all.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
Linux only - needs BlueZ and NetworkManager, reached over D-Bus (tested on
|
|
35
|
+
Raspberry Pi OS). Not for Windows/macOS.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
sudo pip install --break-system-packages blynk-provisioning
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Installing with `sudo` makes it available to both `python3` and
|
|
42
|
+
`sudo python3`, so the examples below work as written.
|
|
43
|
+
`--break-system-packages` is needed because Raspberry Pi OS (like other
|
|
44
|
+
recent Debian-based systems) otherwise refuses to `pip install` outside a
|
|
45
|
+
virtual environment. pip's "Running pip as the 'root' user" warning is
|
|
46
|
+
expected with this install method.
|
|
47
|
+
|
|
48
|
+
**First pairing usually needs `sudo`** - WiFi setup goes through
|
|
49
|
+
NetworkManager, which only allows it from a local console session, not over
|
|
50
|
+
SSH. If the device is already on the WiFi network you choose in the app,
|
|
51
|
+
pairing leaves NetworkManager alone and works without `sudo`.
|
|
52
|
+
|
|
53
|
+
<details>
|
|
54
|
+
<summary>Prefer a virtual environment?</summary>
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
python3 -m venv ~/blynk-venv
|
|
58
|
+
~/blynk-venv/bin/pip install blynk-provisioning
|
|
59
|
+
source ~/blynk-venv/bin/activate # then plain python3 uses it
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`sudo` ignores an activated venv, so for runs that need it, point it at the
|
|
63
|
+
venv's Python: `sudo ~/blynk-venv/bin/python3 my_script.py`.
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
## Quick test - Subscribe and print datastream updates
|
|
67
|
+
|
|
68
|
+
Paste and run as-is (swap in your own template ID for TMPLxxxxxxxx first):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python3 -c "
|
|
72
|
+
import blynk_provisioning
|
|
73
|
+
creds = blynk_provisioning.get_credentials(template_id='TMPLxxxxxxxx')
|
|
74
|
+
client = creds.get_mqtt_client()
|
|
75
|
+
client.on_message = lambda c, u, m: print(f'{m.topic}: {m.payload.decode()}')
|
|
76
|
+
client.subscribe('downlink/#')
|
|
77
|
+
client.loop_forever()
|
|
78
|
+
"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## One-off publish
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
python3 -c "
|
|
85
|
+
import paho.mqtt.publish as publish
|
|
86
|
+
import blynk_provisioning
|
|
87
|
+
creds = blynk_provisioning.get_credentials(template_id='TMPLxxxxxxxx')
|
|
88
|
+
publish.single('ds/Test', payload='42', **creds.connection_kwargs())
|
|
89
|
+
"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The first run for a given template ID blocks until you've paired via the
|
|
93
|
+
Blynk app (BLE advertising starts, same flow as pairing a new edge-agent
|
|
94
|
+
device). Every run after that returns instantly - credentials are cached in `~/.blynk/credentials.env`.
|
|
95
|
+
|
|
96
|
+
`get_mqtt_client()` connects for you but doesn't start the network loop - call
|
|
97
|
+
`client.loop_forever()` to block and process messages, or
|
|
98
|
+
`client.loop_start()` if your script needs to do other things
|
|
99
|
+
concurrently.
|
|
100
|
+
|
|
101
|
+
## Firmware version
|
|
102
|
+
|
|
103
|
+
Blynk shows a firmware version for each device - `unknown` unless you pass
|
|
104
|
+
your script's own version:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
creds = blynk_provisioning.get_credentials(template_id="TMPLxxxxxxxx", fw_version="1.0.3")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The build date shown alongside it is the script file's last-modified time.
|
|
111
|
+
|
|
112
|
+
## Debug output
|
|
113
|
+
|
|
114
|
+
To see every message exchanged with the Blynk app during pairing, plus the
|
|
115
|
+
MQTT checkin, pass `debug=True` to `get_credentials()` or set `BLYNK_DEBUG=1`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
BLYNK_DEBUG=1 python3 my_script.py
|
|
119
|
+
sudo BLYNK_DEBUG=1 python3 my_script.py # not "BLYNK_DEBUG=1 sudo ..." - sudo drops it
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The auth token is shown as its last 4 characters; WiFi password and SIM PIN
|
|
123
|
+
are masked. Only this library's own log is enabled - paho and D-Bus stay quiet.
|
|
124
|
+
|
|
125
|
+
## Multiple templates
|
|
126
|
+
|
|
127
|
+
One identity per template, not one per script (see above) - but a machine
|
|
128
|
+
can legitimately need more than one template's identity (e.g. two
|
|
129
|
+
different kinds of sensor script running on the same Pi). Calling
|
|
130
|
+
`get_credentials()` with a different `template_id` provisions and stores a
|
|
131
|
+
separate identity alongside any already in the same file - they're keyed
|
|
132
|
+
by template internally, so they don't overwrite each other:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
temp_creds = blynk_provisioning.get_credentials(template_id="TMPL_temperature")
|
|
136
|
+
door_creds = blynk_provisioning.get_credentials(template_id="TMPL_doorsensor")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Both get their own BLE pairing ceremony the first time, and both are
|
|
140
|
+
cached in `~/.blynk/credentials.env` from then on.
|
|
141
|
+
|
|
142
|
+
## Custom vendor prefix
|
|
143
|
+
|
|
144
|
+
Defaults to advertising as `"Blynk Device-XXXX"` over BLE. Enterprise/
|
|
145
|
+
white-labeled Blynk apps are typically configured to only discover devices
|
|
146
|
+
broadcasting their own vendor prefix, so pass yours if that applies:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
creds = blynk_provisioning.get_credentials(
|
|
150
|
+
template_id="TMPLxxxxxxxx",
|
|
151
|
+
vendor_prefix="Acme",
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Sharing identity with a co-located edge-agent
|
|
156
|
+
|
|
157
|
+
If this script runs on the same machine as a full edge-agent install,
|
|
158
|
+
point at its own credentials file instead of provisioning a separate
|
|
159
|
+
identity:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
creds = blynk_provisioning.get_credentials(
|
|
163
|
+
template_id="TMPLxxxxxxxx",
|
|
164
|
+
path="/opt/blynk/blynk.env",
|
|
165
|
+
)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Re-pairing (device deleted on the server)
|
|
169
|
+
|
|
170
|
+
Deleting the device in Blynk invalidates its token, but the local copy
|
|
171
|
+
stays. `get_mqtt_client()` then raises `CredentialsRejectedError` saying so.
|
|
172
|
+
To pair again, replacing just that template's stored identity:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
creds = blynk_provisioning.get_credentials(template_id="TMPLxxxxxxxx", reprovision=True)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Status
|
|
179
|
+
|
|
180
|
+
Experimental (`0.1.0`), tested on a Raspberry Pi 5 with Raspberry Pi OS.
|
|
181
|
+
The BLE/NetworkManager/ModemManager engine underneath is adapted from
|
|
182
|
+
blynk-edge-agent's own `agent/ble_provisioning.py` (real, hardware-tested
|
|
183
|
+
code). Issues and feedback welcome on
|
|
184
|
+
[GitHub](https://github.com/anthony-blynk/blynk-provisioning/issues).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "blynk-provisioning"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Unofficial, experimental Blynk.Inject-style BLE provisioning for Linux/Raspberry Pi - get a device's Blynk credentials by pairing with the Blynk app"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Anthony Elder" }]
|
|
14
|
+
keywords = ["blynk", "blynk-inject", "ble", "bluetooth", "provisioning", "raspberry-pi", "iot", "mqtt"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: POSIX :: Linux",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Topic :: Home Automation",
|
|
22
|
+
"Topic :: System :: Hardware",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"paho-mqtt>=2.0,<3",
|
|
26
|
+
"python-dotenv>=1.0",
|
|
27
|
+
"bluez-peripheral>=0.1.7,<0.2",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/anthony-blynk/blynk-provisioning"
|
|
32
|
+
Issues = "https://github.com/anthony-blynk/blynk-provisioning/issues"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.dynamic]
|
|
35
|
+
version = { attr = "blynk_provisioning.__version__" }
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
blynk_provisioning - get this device's Blynk credentials via BLE pairing
|
|
3
|
+
with the Blynk app, so a plain Python/paho script can talk to Blynk without
|
|
4
|
+
needing the full blynk-edge-agent stack. See the project README for scope
|
|
5
|
+
and the one-off-publish / subscribe-and-print examples.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .credentials import Credentials, CredentialsRejectedError, ProvisioningError, get_credentials
|
|
9
|
+
|
|
10
|
+
__all__ = ["get_credentials", "Credentials", "ProvisioningError", "CredentialsRejectedError"]
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|