Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
420d63c
feat(fota): add eraseFirmwareSlot method
DennisMoschina May 12, 2026
d485579
doc(fota): added documentation for image erase
DennisMoschina May 12, 2026
063dc7c
chore(example): changed dependency of mcumgr_flutter to be compatible…
DennisMoschina May 12, 2026
d20f63b
chore(dependencies): update mcumgr_flutter to version 0.9.0
DennisMoschina May 18, 2026
2824321
chore(changelog): updated changelog for 2.3.7
DennisMoschina May 18, 2026
4ef7f62
chore(version): bump version to 2.3.7
DennisMoschina May 18, 2026
e904261
chore(deps): update flutter dependencies
DennisMoschina May 19, 2026
df58a9b
chore: add .pubignore to exclude build artifacts and Python cache files
DennisMoschina May 19, 2026
52e69dd
chore(flutter_version): bump flutter version to 3.44.0
DennisMoschina May 20, 2026
be3df2f
chore(version): bump version to 2.3.8 and update changelog for new de…
DennisMoschina May 20, 2026
95d9aa2
feat(web): add browser support
o-bagge May 21, 2026
5d1ce7f
style: add missing trailing commas
o-bagge May 21, 2026
06eadb7
feat(wearable-factories): get list of ble services from factories in …
DennisMoschina May 21, 2026
3aade5e
chore(version): bumped version to 2.3.9
DennisMoschina May 21, 2026
4fb97cc
docs(documentation): enhance custom wearable factory guide with servi…
DennisMoschina May 21, 2026
175b582
fix(ble_manager): removed prefix filter in ble scanning
DennisMoschina May 27, 2026
51b770b
feat(power-saving-service): Support power saving service
Ruben-Lohberg May 18, 2026
5bb0777
chore(version): bump version to 2.3.10
Ruben-Lohberg May 28, 2026
4373f5b
lib/src/models/capabilites/audio_response_manager.dart: added new cap…
DennisMoschina Dec 12, 2025
e3ace36
lib/open_earable_flutter.dart: export AudioResponseManager
DennisMoschina Dec 12, 2025
20ff23d
lib/src/models/devices/open_earable_v2.dart: implement AudioResponseM…
DennisMoschina Dec 12, 2025
c051138
lib/src/models/devices/open_earable_v2.dart: changed mean magnitude f…
DennisMoschina Dec 12, 2025
d6108d6
lib/src/models/devices: extracted audio resopnse manager to be an opt…
DennisMoschina Feb 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flutter_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.32.0
3.44.0
3 changes: 3 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
**/__pycache__/
*.pyc
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 2.3.10

* added dynamic power saving mode capability for OpenEarable v2 devices

## 2.3.9

* fixed permissions on web, where web was not able to access the devices BLE services

## 2.3.8

* updated dependencies to latest versions

## 2.3.7

* added erase firmware image slot function for FOTA slot info capability

## 2.3.6

* added function to get all connected system devices
Expand Down
14 changes: 13 additions & 1 deletion doc/ADD_CUSTOM_WEARABLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ class MyCustomWearable extends Wearable {

## 2. Implement a Custom Wearable Factory

Create a factory that determines when your custom wearable should be used. This factory is responsible for recognizing a device and constructing the corresponding wearable object. If you need to perform ble gatt operations, you can use the `BleGattManager` in `bleManager` of the `WearableFactory` class. The `BleGattManager` provides methods for interacting with BLE devices, such as reading and writing characteristics. It is provided by the `WearableManager` and should not be set manually.
Create a factory that determines when your custom wearable should be used. This factory is responsible for recognizing a device and constructing the corresponding wearable object. If you need to perform BLE GATT operations, you can use the `BleGattManager` in `bleManager` of the `WearableFactory` class. The `BleGattManager` provides methods for interacting with BLE devices, such as reading and writing characteristics. It is provided by the `WearableManager` and should not be set manually.

If your wearable uses BLE services, declare them in `usedServiceUuids`. Web Bluetooth requires all services to be requested before a device is selected, so the `WearableManager` collects this list from all registered factories when scanning starts.

```dart
class MyCustomWearableFactory extends WearableFactory {
static const String _customServiceUuid =
"00000000-0000-1000-8000-000000000000";

@override
Set<String> get usedServiceUuids => const {
_customServiceUuid,
};

@override
Future<bool> matches(DiscoveredDevice device, List<BleService> services) async {
// Define logic to check if the device matches your custom wearable
Expand All @@ -45,6 +55,8 @@ class MyCustomWearableFactory extends WearableFactory {
}
```

Include every service your factory may need while matching, creating, or using the wearable. This includes services used by capabilities that are registered during `createFromDevice`, because those capabilities are still created after Web Bluetooth has already requested access.

---

## 3. Register the Custom Factory
Expand Down
17 changes: 17 additions & 0 deletions doc/CAPABILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ if (audioModeManager != null) {

---

### PowerSavingModeManager

Reads the power saving modes that the firmware currently supports, including
their display names, and applies the selected mode.

```dart
final powerSaving = wearable.getCapability<PowerSavingModeManager>();
if (powerSaving != null) {
final modes = await powerSaving.readSupportedPowerSavingModes();
final currentMode = await powerSaving.readPowerSavingMode();
await powerSaving.setPowerSavingMode(modes.first);
}
```

---

### ℹ️ Device Information Capabilities

#### DeviceFirmwareVersion
Expand Down Expand Up @@ -200,6 +216,7 @@ Provides firmware slot or image-table state for FOTA backends that expose it.
final slotInfo = wearable.getCapability<FotaSlotInfoCapability>();
if (slotInfo != null) {
final slots = await slotInfo.readFirmwareSlots();
await slotInfo.eraseFirmwareSlot();
}
```

Expand Down
21 changes: 20 additions & 1 deletion doc/FOTA.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,25 @@ Each `FirmwareSlotInfo` contains:
This is useful when you want to show the current primary and secondary images
before or after an update.

## Erase An Inactive Firmware Slot

Slot-aware wearables can erase an inactive firmware image slot through
`FotaSlotInfoCapability`:

```dart
final slotInfo = wearable.getCapability<FotaSlotInfoCapability>();
if (slotInfo != null) {
await slotInfo.eraseFirmwareSlot();
await slotInfo.eraseFirmwareSlot(channel: 1);
}
```

When `channel` is omitted, the firmware backend erases its default secondary
image slot. When `channel` is provided, the erase request targets that raw
mcumgr image slot channel. Devices reject erase requests for slots that contain
a confirmed image, an image pending test on the next reboot, or an active
split-image slot.

## What Happens Internally

You do not need to call the lower-level handler classes directly, but it helps to know what `UpdateBloc` is doing:
Expand Down Expand Up @@ -367,7 +386,7 @@ Recommended UX:
- `UnifiedFirmwareRepository` caches results for 15 minutes unless you request a refresh
- The current upload path uses `mcumgr_flutter` under the hood
- `FotaSlotInfoCapability` is optional and only available on wearables whose firmware backend exposes slot-style state
- `mcumgr_flutter 0.6.1` does not expose an API to erase an individual image slot, so this library does not currently offer slot erase either
- The current local `mcumgr_flutter` integration exposes slot erase through `FotaSlotInfoCapability.eraseFirmwareSlot`

## Related Source Files

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FirmwareList extends StatelessWidget {
floatingActionButton: FloatingActionButton(
onPressed: () async {
// Navigator.pop(context, 'Firmware');
FilePickerResult? result = await FilePicker.platform.pickFiles(
FilePickerResult? result = await FilePicker.pickFiles(
type: FileType.custom,
allowedExtensions: ['zip', 'bin'],
);
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
2 changes: 2 additions & 0 deletions example/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import Foundation

import file_picker
import flutter_archive
import mcumgr_flutter
import universal_ble

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FlutterArchivePlugin.register(with: registry.registrar(forPlugin: "FlutterArchivePlugin"))
McumgrFlutterPlugin.register(with: registry.registrar(forPlugin: "McumgrFlutterPlugin"))
UniversalBlePlugin.register(with: registry.registrar(forPlugin: "UniversalBlePlugin"))
}
Loading
Loading