Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2a89702
renamed tau ring to OpenRing
TobiasRoeddiger Feb 11, 2026
6885afb
renamed folder
TobiasRoeddiger Feb 11, 2026
4a263eb
added missing file
TobiasRoeddiger Feb 11, 2026
b829a6d
renamed value parser
TobiasRoeddiger Feb 11, 2026
adc39e2
Add OpenRing PPG sensor parsing and configuration
TobiasRoeddiger Feb 11, 2026
7fa086e
small changes
TobiasRoeddiger Feb 11, 2026
277cb31
Add OpenRing payload-based config and PPG streaming command
TobiasRoeddiger Feb 11, 2026
332c470
updates
TobiasRoeddiger Feb 11, 2026
1e7b09b
Fix OpenRing IMU frame parsing and add PPG packet decoding
TobiasRoeddiger Feb 11, 2026
ab7d0de
Swap OpenRing PPG start/stop control byte
TobiasRoeddiger Feb 11, 2026
3ee81b1
Harden OpenRing IMU stream handling for mixed packets
TobiasRoeddiger Feb 11, 2026
8910300
Make OpenRing parser tolerant to partial/mixed packets
TobiasRoeddiger Feb 11, 2026
7749e03
Decode OpenRing PPG packet type 0x02 frames
TobiasRoeddiger Feb 11, 2026
e7844f2
Fix OpenRing IMU payload offset and flexible waveform logs
TobiasRoeddiger Feb 11, 2026
3f889a6
Fix OpenRing sample timestamps to be strictly monotonic
TobiasRoeddiger Feb 11, 2026
4b4eda6
Trace OpenRing parsed/emitted values and decouple timestamps by cmd
TobiasRoeddiger Feb 11, 2026
a9a981e
Estimate IMU sample rate from packet timing for timestamp spacing
TobiasRoeddiger Feb 11, 2026
cbec162
Use fixed IMU sample spacing for timestamps
TobiasRoeddiger Feb 11, 2026
dc6659a
Align IMU accel parsing with SDK sub-opcode behavior
TobiasRoeddiger Feb 11, 2026
5d27a59
Ignore OpenRing accel-only IMU packets and parse accel+gyro only
TobiasRoeddiger Feb 11, 2026
b17f621
fully implemented imu
TobiasRoeddiger Feb 11, 2026
1cbd375
added PPG support
TobiasRoeddiger Feb 11, 2026
8dd8009
all sensors working
TobiasRoeddiger Feb 11, 2026
d63b889
implemented wall clock time sync for OpenRing
TobiasRoeddiger Feb 11, 2026
c3e2f95
implemented regular battery polling
TobiasRoeddiger Feb 11, 2026
1ff1b23
ensure timing logic while battery and time sync
TobiasRoeddiger Feb 11, 2026
8732950
implemented openring
TobiasRoeddiger Feb 13, 2026
296ece6
added off state and default states for openring
TobiasRoeddiger Feb 15, 2026
6104138
added openring image
TobiasRoeddiger Feb 16, 2026
c609255
more gracefully handle sensor states and data targets for openring
TobiasRoeddiger Feb 17, 2026
ca46909
more gracefully handle sensor states and data targets for openring
TobiasRoeddiger Feb 17, 2026
da76861
streamlined the system devices and bluetooth devices (ring-only split)
DennisMoschina Feb 18, 2026
a0ad987
made the openring implementation more stable
TobiasRoeddiger Feb 17, 2026
e3e8ebd
made the openring implementation more stable
TobiasRoeddiger Feb 17, 2026
a0494de
improved the state handling
TobiasRoeddiger Feb 18, 2026
3fd8746
rely on the 0x32 characharteristic only
TobiasRoeddiger Feb 18, 2026
40cb014
simplified the logic to pure software disable because everything else…
TobiasRoeddiger Feb 18, 2026
ff9ab41
fixed a little bug in the battery logic
TobiasRoeddiger Feb 18, 2026
5e7b55e
fixed a little bug in the battery logic
TobiasRoeddiger Feb 18, 2026
aa98746
lib/src/models/devices/open_ring_factory.dart: changed units of senso…
DennisMoschina Feb 18, 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
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.3.3

* renamed TauRing to OpenRing
* added support for OpenRing temperature sensors (`temp0`, `temp1`, `temp2`) as one 3-channel `Temperature` sensor (`°C`) with software-only on/off control

## 2.3.2

* fixed some bugs with Esense devices
Expand Down Expand Up @@ -73,4 +78,4 @@ Connecting to earable now retries after first failure.

## 0.0.1

* TODO: Describe initial release.
* TODO: Describe initial release.
Binary file added assets/wearable_icons/open_ring/openring.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion example/lib/widgets/sensor_configuration_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class _SensorConfigurationViewState extends State<SensorConfigurationView> {
@override
void initState() {
super.initState();
_selectedValue = widget.configuration.values.first;
_selectedValue =
widget.configuration.offValue ?? widget.configuration.values.first;
}

@override
Expand Down
49 changes: 43 additions & 6 deletions lib/open_earable_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import 'src/managers/wearable_disconnect_notifier.dart';
import 'src/models/capabilities/stereo_device.dart';
import 'src/models/capabilities/system_device.dart';
import 'src/models/devices/discovered_device.dart';
import 'src/models/devices/tau_ring_factory.dart';
import 'src/models/devices/open_ring_factory.dart';
import 'src/models/devices/wearable.dart';

export 'src/models/devices/discovered_device.dart';
Expand Down Expand Up @@ -111,7 +111,7 @@ class WearableManager {
CosinussOneFactory(),
PolarFactory(),
DevKitFactory(),
TauRingFactory(),
OpenRingFactory(),
EsenseFactory(),
];

Expand Down Expand Up @@ -262,16 +262,53 @@ class WearableManager {
}

String deviceErrorMessage(dynamic e, String deviceName) {
final normalizedDeviceName = _formatDisplayDeviceName(deviceName);
return switch (e) {
UnsupportedDeviceException _ => 'Device "$deviceName" is not supported.',
UnsupportedDeviceException _ =>
'Device "$normalizedDeviceName" is not supported.',
AlreadyConnectedException _ =>
'Device "$deviceName" is already connected.',
'Device "$normalizedDeviceName" is already connected.',
ConnectionFailedException _ =>
'Failed to connect to device "$deviceName". Please try again.',
_ => e.toString(),
'Failed to connect to device "$normalizedDeviceName". Please try again.',
_ => _normalizeDeviceNameInMessage(
message: e.toString(),
rawDeviceName: deviceName,
normalizedDeviceName: normalizedDeviceName,
),
};
}

String _formatDisplayDeviceName(String rawName) {
final trimmed = rawName.trim();
if (trimmed.isEmpty) {
return trimmed;
}

final replaced = trimmed.replaceFirst(
RegExp(r'^bcl[-_\s]*', caseSensitive: false),
'OpenRing-',
);

if (replaced == 'OpenRing-') {
return 'OpenRing';
}

return replaced;
}

String _normalizeDeviceNameInMessage({
required String message,
required String rawDeviceName,
required String normalizedDeviceName,
}) {
if (rawDeviceName.isEmpty ||
rawDeviceName == normalizedDeviceName ||
message.isEmpty) {
return message;
}
return message.replaceAll(rawDeviceName, normalizedDeviceName);
}

void addPairingRule(PairingRule rule) {
_pairingManager.addRule(rule);
}
Expand Down
Loading