From 61658a69fd2c9d654bdc344ebed2ac115190a0c3 Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 00:58:42 +0200 Subject: [PATCH 1/6] ble new error characteristic is added --- lib/src/constants.dart | 1 + lib/src/models/devices/open_earable_v2.dart | 32 +++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/src/constants.dart b/lib/src/constants.dart index e20e21a4..370dccd6 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -40,3 +40,4 @@ const String buttonStateCharacteristicUuid = const String ledServiceUuid = "81040a2e-4819-11ee-be56-0242ac120002"; const String ledSetStateCharacteristic = "81040e7a-4819-11ee-be56-0242ac120002"; +const String sensorErrorCharacteristicUuid = "1234567c-1234-5678-9abc-def123456789"; \ No newline at end of file diff --git a/lib/src/models/devices/open_earable_v2.dart b/lib/src/models/devices/open_earable_v2.dart index e2b617d6..a7d0b4c8 100644 --- a/lib/src/models/devices/open_earable_v2.dart +++ b/lib/src/models/devices/open_earable_v2.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:open_earable_flutter/src/constants.dart'; import 'package:open_earable_flutter/src/models/devices/bluetooth_wearable.dart'; import 'package:pub_semver/pub_semver.dart'; - +import 'package:open_earable_flutter/src/models/error/sensor_error.dart'; import '../../../open_earable_flutter.dart' hide Version; import '../../managers/v2_sensor_handler.dart'; import '../capabilities/device_firmware_version.dart'; @@ -90,6 +90,31 @@ class OpenEarableV2 extends BluetoothWearable @override bool get isConnectedViaSystem => _isConnectedViaSystem; +final _errorController = StreamController.broadcast(); +Stream get onError => _errorController.stream; +// Add this method after the _errorController declaration +void _subscribeToErrorNotifications() { + bleManager + .subscribe( + deviceId: deviceId, + serviceId: sensorServiceUuid, + characteristicId: sensorErrorCharacteristicUuid, + ) + .listen( + (data) { + try { + final error = SensorError.fromBytes(Uint8List.fromList(data)); + logger.i('Received sensor error: $error'); + _errorController.add(error); + } catch (e) { + logger.e('Failed to parse sensor error: $e'); + } + }, + onError: (error) { + logger.e('Error in error notification stream: $error'); + }, + ); +} @override Stream> get sensorConfigurationStream { @@ -279,7 +304,10 @@ class OpenEarableV2 extends BluetoothWearable bool isConnectedViaSystem = false, }) : _sensors = sensors, _sensorConfigurations = sensorConfigurations, - _isConnectedViaSystem = isConnectedViaSystem; + _isConnectedViaSystem = isConnectedViaSystem { + // ADD THIS LINE HERE + _subscribeToErrorNotifications(); +} @override String get deviceId => discoveredDevice.id; From 72fdb12fd8c7ae4f81ed464e2c888786907ace6b Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 01:31:18 +0200 Subject: [PATCH 2/6] the missing file --- lib/src/models/devices/open_earable_v2.dart | 2 +- lib/src/models/error/sensor_error.dart | 60 +++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 lib/src/models/error/sensor_error.dart diff --git a/lib/src/models/devices/open_earable_v2.dart b/lib/src/models/devices/open_earable_v2.dart index a7d0b4c8..f56aa0d5 100644 --- a/lib/src/models/devices/open_earable_v2.dart +++ b/lib/src/models/devices/open_earable_v2.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:open_earable_flutter/src/constants.dart'; import 'package:open_earable_flutter/src/models/devices/bluetooth_wearable.dart'; import 'package:pub_semver/pub_semver.dart'; -import 'package:open_earable_flutter/src/models/error/sensor_error.dart'; +import 'package:open_earable_flutter-ble-errors/lib/src/models/error/sensor_error.dart'; import '../../../open_earable_flutter.dart' hide Version; import '../../managers/v2_sensor_handler.dart'; import '../capabilities/device_firmware_version.dart'; diff --git a/lib/src/models/error/sensor_error.dart b/lib/src/models/error/sensor_error.dart new file mode 100644 index 00000000..1ff4b505 --- /dev/null +++ b/lib/src/models/error/sensor_error.dart @@ -0,0 +1,60 @@ +import 'dart:typed_data'; + +class SensorError { + final int errorCode; + final int sensorId; + final int timestamp; + final String message; + + SensorError({ + required this.errorCode, + required this.sensorId, + required this.timestamp, + required this.message, + }); + + factory SensorError.fromBytes(Uint8List bytes) { + if (bytes.length < 70) { + throw Exception('Invalid error data length: ${bytes.length}'); + } + + return SensorError( + errorCode: bytes[0], + sensorId: bytes[1], + timestamp: (bytes[5] << 24) | + (bytes[4] << 16) | + (bytes[3] << 8) | + bytes[2], + message: String.fromCharCodes(bytes.sublist(6, 70)).trim(), + ); + } + + String get errorDescription { + switch (errorCode) { + case 0x01: return 'Sensor initialization failed'; + case 0x02: return 'Sensor read failed'; + case 0x03: return 'SD card error'; + case 0x04: return 'Audio playback failed'; + case 0x05: return 'BLE notification failed'; + case 0xFF: return 'Test notification'; + default: return 'Unknown error (code: ${errorCode.toRadixString(16)})'; + } + } + + String get sensorName { + switch (sensorId) { + case 0: return 'IMU'; + case 1: return 'Barometer'; + case 2: return 'PPG'; + case 3: return 'Optic Temp'; + case 4: return 'Bone Conduction'; + case 5: return 'Microphone'; + default: return 'System'; + } + } + + String get formattedMessage => '[$sensorName] $errorDescription: $message'; + + @override + String toString() => formattedMessage; +} \ No newline at end of file From 011dc0707312aced15999f1582b7f83a415c64dd Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 01:49:54 +0200 Subject: [PATCH 3/6] missing file 2 --- lib/src/models/devices/open_earable_v2.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/models/devices/open_earable_v2.dart b/lib/src/models/devices/open_earable_v2.dart index f56aa0d5..7698995b 100644 --- a/lib/src/models/devices/open_earable_v2.dart +++ b/lib/src/models/devices/open_earable_v2.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:open_earable_flutter/src/constants.dart'; import 'package:open_earable_flutter/src/models/devices/bluetooth_wearable.dart'; import 'package:pub_semver/pub_semver.dart'; -import 'package:open_earable_flutter-ble-errors/lib/src/models/error/sensor_error.dart'; +import 'package:open_earable_flutter/lib/src/models/error/sensor_error.dart'; import '../../../open_earable_flutter.dart' hide Version; import '../../managers/v2_sensor_handler.dart'; import '../capabilities/device_firmware_version.dart'; From 8228dc891cb1896b4088d3f2b771a1a2868060fd Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 01:59:47 +0200 Subject: [PATCH 4/6] fix: correct import path (remove extra /lib/) and add onError to Wearable --- lib/src/models/devices/open_earable_v2.dart | 2 +- lib/src/models/devices/wearable.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/models/devices/open_earable_v2.dart b/lib/src/models/devices/open_earable_v2.dart index 7698995b..a7d0b4c8 100644 --- a/lib/src/models/devices/open_earable_v2.dart +++ b/lib/src/models/devices/open_earable_v2.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:open_earable_flutter/src/constants.dart'; import 'package:open_earable_flutter/src/models/devices/bluetooth_wearable.dart'; import 'package:pub_semver/pub_semver.dart'; -import 'package:open_earable_flutter/lib/src/models/error/sensor_error.dart'; +import 'package:open_earable_flutter/src/models/error/sensor_error.dart'; import '../../../open_earable_flutter.dart' hide Version; import '../../managers/v2_sensor_handler.dart'; import '../capabilities/device_firmware_version.dart'; diff --git a/lib/src/models/devices/wearable.dart b/lib/src/models/devices/wearable.dart index fdc2ac99..f965f5f9 100644 --- a/lib/src/models/devices/wearable.dart +++ b/lib/src/models/devices/wearable.dart @@ -44,7 +44,7 @@ abstract class Wearable { } return null; } - +Stream get onError => const Stream.empty(); /// Gets a specific capability of the wearable, throwing a StateError if not supported. T requireCapability() { final capability = getCapability(); From c5c18f61c38616ff305a2b0a37b36c73883f4c9b Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 02:06:27 +0200 Subject: [PATCH 5/6] fix: add SensorError import to wearable.dart --- lib/src/models/devices/wearable.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/models/devices/wearable.dart b/lib/src/models/devices/wearable.dart index f965f5f9..79d35f75 100644 --- a/lib/src/models/devices/wearable.dart +++ b/lib/src/models/devices/wearable.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:ui'; import '../../managers/wearable_disconnect_notifier.dart'; - +import 'package:open_earable_flutter/src/models/error/sensor_error.dart'; enum WearableIconVariant { single, left, From adc3eaa24c721eb970afdd9fe7e2415315defd5d Mon Sep 17 00:00:00 2001 From: hith-1801 Date: Tue, 28 Apr 2026 10:22:54 +0200 Subject: [PATCH 6/6] Sensor streaming initialization code added --- lib/src/models/error/sensor_error.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/models/error/sensor_error.dart b/lib/src/models/error/sensor_error.dart index 1ff4b505..c3a947f1 100644 --- a/lib/src/models/error/sensor_error.dart +++ b/lib/src/models/error/sensor_error.dart @@ -31,12 +31,12 @@ class SensorError { String get errorDescription { switch (errorCode) { - case 0x01: return 'Sensor initialization failed'; + case 0x01: return 'Error streaming is initialized'; case 0x02: return 'Sensor read failed'; case 0x03: return 'SD card error'; case 0x04: return 'Audio playback failed'; case 0x05: return 'BLE notification failed'; - case 0xFF: return 'Test notification'; + case 0xFF: return 'Steaming failed the queue is full!'; default: return 'Unknown error (code: ${errorCode.toRadixString(16)})'; } }