Python library for OTA firmware updates on Silicon Labs EFR32 devices over BLE (AppLoader)
Project description
silabs-ble-ota
Flash firmware to Silicon Labs EFR32 devices over BLE from Python, using the
Silicon Labs AppLoader OTA GATT service (a .gbl image). Transport-agnostic
— it uses bleak-retry-connector's
establish_connection, so the same code flashes over a direct Bluetooth
adapter or an ESPHome Bluetooth proxy.
Installation
pip install silabs-ble-ota
Library
The device must already be in the AppLoader (OTA bootloader) when you call
perform_silabs_ota. Triggering the bootloader and re-discovering the device is
vendor/device specific and is the caller's responsibility.
from silabs_ble_ota import SilabsOTAError, perform_silabs_ota
# `ble_device` is a bleak BLEDevice already in (or booting into) the AppLoader,
# at the same address as the application:
gbl = open("firmware.gbl", "rb").read()
try:
await perform_silabs_ota(
gbl,
ble_device,
on_progress=lambda pct: print(f"{pct:.0f}%"),
on_log=print,
)
except SilabsOTAError as exc:
print(f"OTA failed: {exc}")
perform_silabs_ota(gbl_bytes, ble_device, on_progress=None, on_log=None, *, fast=False)
| Argument | Description |
|---|---|
gbl_bytes |
Raw .gbl firmware bytes. |
ble_device |
A bleak BLEDevice already in (or booting into) the AppLoader, at the same address as the application. |
on_progress |
Optional callback, called with a float percentage 0–100. |
on_log |
Optional callback for human-readable status messages. |
fast |
True uses a larger write-without-response window for a ~2× faster transfer. Only safe on a direct connection — see below. Defaults to False. |
Raises SilabsOTAError if the connection or transfer fails, or the device is not
in OTA mode. No external sleep is needed before calling — it retries the
connect itself while the AppLoader boots.
Reliability over Bluetooth proxies
The Silicon Labs AppLoader has no packet-receipt flow control. Over an
ESPHome proxy (which forwards write-without-response with no backpressure), an
unacknowledged data write can be silently dropped when the device's buffer
is full — producing a complete-looking stream but an incomplete image that fails
the finalize step. By default this library therefore acknowledges every data
write (response=True), so no chunk is silently lost, and retries on a proxy
Congested signal. This is the safe default and is required through a proxy.
fast=True for direct connections
On a direct Bluetooth adapter (BlueZ, CoreBluetooth) the OS socket
backpressures write-without-response, so chunks are never silently dropped.
Passing fast=True then streams a window of write-without-response chunks
between acks for roughly 2× the throughput (measured ~58s vs ~125s for a
234 KB image on EFR32BG22). Do not use fast=True through an ESPHome proxy —
dropped chunks will corrupt the image.
It also:
- connects with
use_services_cache=False(fresh GATT discovery — the AppLoader has a different service table than the application at the same address); - treats the connection as one-shot (the AppLoader reboots to the application when the connection drops), retrying only the connect, never reconnecting mid-flash;
- identifies the OTA service by its characteristic UUIDs (the OTA service UUID varies between AppLoader builds).
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file silabs_ble_ota-0.1.0.tar.gz.
File metadata
- Download URL: silabs_ble_ota-0.1.0.tar.gz
- Upload date:
- Size: 69.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4559504886d3cc7fd53b2ec200a86e6dadeda944ced727ce5786519817ba7e92
|
|
| MD5 |
1893eff5be28cc41acb36d8f06e8d4c4
|
|
| BLAKE2b-256 |
40d393c3fd8d646ba4550d1d4a95d8c4014836c05bd6e67b4d8203f2a3186c5b
|
Provenance
The following attestation bundles were made for silabs_ble_ota-0.1.0.tar.gz:
Publisher:
release.yml on OpenDisplay/silabs-ble-ota
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
silabs_ble_ota-0.1.0.tar.gz -
Subject digest:
4559504886d3cc7fd53b2ec200a86e6dadeda944ced727ce5786519817ba7e92 - Sigstore transparency entry: 1695856295
- Sigstore integration time:
-
Permalink:
OpenDisplay/silabs-ble-ota@d3c7e52160129910e0ee56976214c0c3f3e4e4c1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/OpenDisplay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d3c7e52160129910e0ee56976214c0c3f3e4e4c1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file silabs_ble_ota-0.1.0-py3-none-any.whl.
File metadata
- Download URL: silabs_ble_ota-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba1add7e96dda03ffb50c1737e49fad09db764c78c2a6f84738ea40d856c7c58
|
|
| MD5 |
a5af513d5c86f5e44a9d52b19e462445
|
|
| BLAKE2b-256 |
e4b6a57bae5ec8772a7ea977507aef788b0e1c162728ec58dfd7f34ae2a8912f
|
Provenance
The following attestation bundles were made for silabs_ble_ota-0.1.0-py3-none-any.whl:
Publisher:
release.yml on OpenDisplay/silabs-ble-ota
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
silabs_ble_ota-0.1.0-py3-none-any.whl -
Subject digest:
ba1add7e96dda03ffb50c1737e49fad09db764c78c2a6f84738ea40d856c7c58 - Sigstore transparency entry: 1695856544
- Sigstore integration time:
-
Permalink:
OpenDisplay/silabs-ble-ota@d3c7e52160129910e0ee56976214c0c3f3e4e4c1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/OpenDisplay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d3c7e52160129910e0ee56976214c0c3f3e4e4c1 -
Trigger Event:
push
-
Statement type: