Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add bluetooth backend abstraction & support devices with multiple measurements #432

Open
wants to merge 92 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
beb447f
feat: implement logging/logging package
pimlie Sep 12, 2024
a50ef6e
chore: extract some global configuration props
pimlie Sep 12, 2024
38c8aeb
feat: add bluetooth backend abstraction layers
pimlie Sep 12, 2024
ee1f931
feat: add support for bt devices that always return multiple measurem…
pimlie Sep 12, 2024
2670413
feat: implement new bluetooth backend abstraction layer
pimlie Sep 12, 2024
7f7c831
test: fix/update tests for new bluetooth logic
pimlie Sep 12, 2024
7f677f5
chore: remove some debug logs
pimlie Sep 12, 2024
9a8873b
chore: be consistent with Uuid naming
pimlie Sep 13, 2024
88fbcd5
test: add logging util tests
pimlie Sep 13, 2024
4ec6095
chore: abstract device conecct/disconnect logic as its implementation…
pimlie Sep 13, 2024
ccfc3c8
feat: add bluetooth information page
pimlie Sep 13, 2024
3f9ed1a
test: add test for ui/measurement_multiple.dart
pimlie Sep 13, 2024
080490a
chore: fix a code comment
pimlie Sep 13, 2024
7b35dcd
chore: improve bluetooth.md
pimlie Sep 13, 2024
b7870e8
chore: improve bluetooth.md
pimlie Sep 13, 2024
34194a3
chore: improve bluetooth.md
pimlie Sep 13, 2024
1b3b8ef
fix: log message if callback _was_ removed
pimlie Sep 13, 2024
467dc0c
chore: improve/fix code comments
pimlie Sep 13, 2024
30ff048
chore: extract ValueGraph as HomeScreen boolean & fix some code comments
pimlie Sep 13, 2024
1ffbf03
docs: add/change links to official bluetooth specs
pimlie Sep 13, 2024
0aa4418
chore: add blood pressure service specification to BLUETOOTH.md
pimlie Sep 16, 2024
9c16286
fix: apply suggestion
pimlie Sep 16, 2024
9b99c31
fix: improve code comment
pimlie Sep 16, 2024
b128949
chore: remove redundant code comment
pimlie Sep 16, 2024
6d6e7de
fix: cancel connection listener before listening (again)
pimlie Sep 16, 2024
3b895a6
fix: prefer using firstWhereOrNull
pimlie Sep 16, 2024
44e5990
chore: prefer inline if
pimlie Sep 16, 2024
fe14c58
chore: just use final var
pimlie Sep 16, 2024
83c1a22
chore: onDiscoveryError doesnt need to be protected anymore
pimlie Sep 16, 2024
847ee16
chore: cancel any existing discovery subscriptions
pimlie Sep 16, 2024
b849f7b
chore: update code comment
pimlie Sep 16, 2024
529f487
chore: add assert statement
pimlie Sep 16, 2024
cf03f8a
chore: remove todo as there is a ticket on github
pimlie Sep 16, 2024
c91457d
chore: remove automatic connection retry logic
pimlie Sep 16, 2024
bfee729
chore: remove unused class
pimlie Sep 16, 2024
29e2b2b
chore: prefer just using final
pimlie Sep 16, 2024
0e14180
chore: remove deprecated log methods & unneeded stacktrace parser
pimlie Sep 18, 2024
3d9e48f
chore: remove some config vars
pimlie Sep 18, 2024
5d35a69
chore: remove parts & fix test
pimlie Sep 18, 2024
05aaa14
chore: make discovered._devices a Set
pimlie Sep 19, 2024
5ed5054
Merge branch 'main' into feat-use-ble-package
derdilla Sep 20, 2024
ea74071
chore: refactor reading characateristic values + some fixes
pimlie Sep 20, 2024
06d9da5
chore: refactor BluetoothManager instantiation
derdilla Sep 20, 2024
7697c95
chore: migrate .transform to .map
derdilla Sep 20, 2024
c257878
chore(backend): revision code patterns, comments and formatting
derdilla Sep 20, 2024
2f767dc
chore: extract logging
derdilla Sep 20, 2024
aca47b7
chore(ui): revision code patterns, comments and formatting
derdilla Sep 20, 2024
92c8243
chore: remove excess nl localization
derdilla Sep 20, 2024
7cc448e
chore(logic): revision code patterns, comments and formatting
derdilla Sep 20, 2024
8a3d3e2
Update app/lib/features/bluetooth/backend/bluetooth_low_energy/ble_de…
pimlie Sep 22, 2024
2a93308
fix: forceRefresh isnt async anymore
pimlie Sep 22, 2024
c34b551
fix: passthrough state arg
pimlie Sep 22, 2024
193ca76
chore: update code comment
pimlie Sep 22, 2024
e0e21a7
fix: use onClosed instead for measreuemnt_multiple state
pimlie Sep 22, 2024
9ad866a
chore: update lock file
pimlie Sep 23, 2024
692a022
test: fix arg
pimlie Sep 23, 2024
c322eda
Merge branch 'main' into feat-use-ble-package
pimlie Sep 23, 2024
3a672f1
fix: revert change that broke uuidcomparison
pimlie Sep 23, 2024
ce139ea
fix: requesting permissions on android is required
pimlie Sep 23, 2024
e8c4cce
fix: dont implement workflow in library method
pimlie Sep 26, 2024
2c97c7d
Merge branch 'main' into feat-use-ble-package
pimlie Sep 26, 2024
df24861
fix: resolve dependency issues
pimlie Sep 26, 2024
8af76ab
fix: try building android with flutter blue plus
pimlie Sep 26, 2024
e05e26f
fix: merge duplicate logic
pimlie Sep 26, 2024
1325c45
chore: always enable bluetooth when initiating bluetooth_cubit
pimlie Sep 26, 2024
d7e5e6e
chore: revert back to only enabling when not authorized
pimlie Sep 27, 2024
6ef22c7
fix: only resolve future when connect state changed
pimlie Sep 27, 2024
881072d
chore: debug with fbp
pimlie Sep 27, 2024
30c912b
chore: add error message to uuid length assert
pimlie Sep 27, 2024
caa1bb7
fix: fbp doesnt return a 128bit uuid for guid.tostring
pimlie Sep 27, 2024
948c025
chore: always build package for now
pimlie Sep 27, 2024
0a81e1a
chore: always build package for now (2)
pimlie Sep 27, 2024
ca7df73
chore: comment out condition
pimlie Sep 27, 2024
7204563
chore: set ref in code checkout to pr head
pimlie Sep 27, 2024
1a0cc7e
fix: use char uuid for fbo charecteristics
pimlie Sep 27, 2024
012845b
feat: better device state management & implement automatic retry afte…
pimlie Oct 1, 2024
4bff687
chore: increase max retry count
pimlie Oct 1, 2024
74b470e
chore: upgrade gradle to current version
pimlie Oct 16, 2024
0db33ff
chore: update code comments & lock file
pimlie Oct 16, 2024
fe86605
chore: add vscode files
pimlie Oct 16, 2024
c8cc50f
Merge branch 'main' into feat-use-ble-package
pimlie Oct 16, 2024
d9ea3ca
chore: upgrade gradle version
pimlie Oct 16, 2024
41d9aef
chore: return nullable boolean from manager.enable to prevent closed_…
pimlie Oct 16, 2024
3bb86de
revert: changes to pr workflow
pimlie Oct 17, 2024
0796b0e
chore: rework waiting for disconnecting state logic
pimlie Oct 17, 2024
48704eb
chore: reset state to disconnected after connect error
pimlie Oct 17, 2024
4ebcfa7
chore: typo
pimlie Oct 17, 2024
e9b1c73
chore: log error
pimlie Oct 17, 2024
1e35fbd
chore: remove debug code
pimlie Oct 17, 2024
d42883b
test: fix tests
pimlie Oct 17, 2024
89c7ada
test: ensure device comparison works also in tests
pimlie Oct 18, 2024
ebe7274
chore: add code comment about device comparison
pimlie Oct 18, 2024
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
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"dart-code.flutter",
"dart-code.dart-code"
]
}
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "blood-pressure-monitor",
"type": "dart",
"request": "launch",
"cwd": "${workspaceFolder}/app",
"program": "lib/main.dart",
"args": [
"--flavor", "github"
]
}
]
}
44 changes: 44 additions & 0 deletions BLUETOOTH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Supported Bluetooth devices

In general any device that supports [`Blood Pressure Service (0x1810)`](https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/service_uuids.yaml#lines-77:79) could be used. The blood pressure measurement values are stored in the characteristic [`Blood Pressure Measurement (0x2A35)`](https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/characteristic_uuids.yaml#lines-161:163)

## Reading caveats

There are some difference in how devices report their measurements.

Most devices provide 2 ways to retrieve measurements over bluetooth, but there are also difference in how those operate:

1. Immediately after taking a measurement
1. and returns all measurements stored in memory
2. and only returns the latest measurement
2. As a download mode
1. and automatically remove all locally stored measurements after a succesful download
2. and leave measurements untouched, i.e. the user needs to remove the stored measurements themselves

> :warning: At the moment situation 2.i is not well supported. Do not use this unless you are ok with loosing previously stored measurements

## Known working devices

> If your device is not listed please edit this page and add it! :bow:

|Device|Bluetooth name|Read after measurement|Download mode|Automatically disconnects after reading|
pimlie marked this conversation as resolved.
Show resolved Hide resolved
|---|---| :---: | :---: | :---: |
|HealthForYou by Silvercrest (Type SBM 69)|SBM69| :1234: | :white_check_mark: | :white_check_mark: |
|Omron X4 Smart|X4 Smart| :one: | :white_check_mark::wastebasket: | :white_check_mark: |

#### Legenda

|Icon|Description|
| :---: | --- |
| :no_entry_sign: |Not supported / No|
| :white_check_mark: |Supported / Yes|
| :one: | Returns latest measurement|
| :1234: | Returns all measurements|
| :white_check_mark::wastebasket: |Supported and removes all locally stored measurements|

## Specifications

- Blood Pressure Service: https://www.bluetooth.com/specifications/specs/blood-pressure-service-1-1-1/
- Assigned Numbers (f.e. service & characteristic UUID's): https://www.bluetooth.com/specifications/assigned-numbers/
- GATT Specification Supplement (f.e. data structures): https://www.bluetooth.com/specifications/gss/
- Current Time Service: https://www.bluetooth.com/specifications/specs/current-time-service-1-1/
4 changes: 2 additions & 2 deletions app/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
distributionSha256Sum=f30b29580fe11719087d698da23f3b0f0d04031d8995f7dd8275a31f7674dc01
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
pimlie marked this conversation as resolved.
Show resolved Hide resolved
distributionSha256Sum=2ab88d6de2c23e6adae7363ae6e29cbdd2a709e992929b48b6530fd0c7133bd6
2 changes: 1 addition & 1 deletion app/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.0" apply false
id "com.android.application" version "8.3.2" apply false
pimlie marked this conversation as resolved.
Show resolved Hide resolved
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}

Expand Down
10 changes: 10 additions & 0 deletions app/lib/config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'dart:io';

/// Whether bluetooth is supported on this platform by this app
final isPlatformSupportedBluetooth = Platform.isAndroid || Platform.isIOS || Platform.isMacOS || Platform.isLinux;

/// Whether we are running in a test environment
final isTestingEnvironment = Platform.environment['FLUTTER_TEST'] == 'true';

/// Whether the value graph should be shown as home screen in landscape mode
final showValueGraphAsHomeScreenInLandscapeMode = isTestingEnvironment || !Platform.isLinux;
4 changes: 2 additions & 2 deletions app/lib/data_util/entry_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension EntryUtils on BuildContext {
}
}
} on ProviderNotFoundException {
Log.err('createEntry($initial) was called from a context without Provider.');
log.severe('[extension.EntryUtils] createEntry($initial) was called from a context without Provider.');
} catch (e, stack) {
await ErrorReporting.reportCriticalError('Error opening add measurement dialoge', '$e\n$stack',);
}
Expand Down Expand Up @@ -93,7 +93,7 @@ extension EntryUtils on BuildContext {
),);
}
} on ProviderNotFoundException {
Log.err('deleteEntry($entry) was called from a context without Provider.');
log.severe('[extension.EntryUtils] deleteEntry($entry) was called from a context without Provider.');
}
}
}
16 changes: 16 additions & 0 deletions app/lib/features/bluetooth/backend/bluetooth_backend.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// Utility import that only exposes the bluetooth backend services that should be used.
library;

export 'package:blood_pressure_app/features/bluetooth/backend/bluetooth_device.dart' show BluetoothDevice;
export 'package:blood_pressure_app/features/bluetooth/backend/bluetooth_manager.dart' show BluetoothManager;
export 'package:blood_pressure_app/features/bluetooth/backend/bluetooth_state.dart' show BluetoothAdapterState;

/// All available bluetooth backends
enum BluetoothBackend {
pimlie marked this conversation as resolved.
Show resolved Hide resolved
/// Bluetooth Low Energy backend
bluetoothLowEnergy,
/// Flutter Blue Plus backend
flutterBluePlus,
/// Mock backend
mock;
}
8 changes: 8 additions & 0 deletions app/lib/features/bluetooth/backend/bluetooth_connection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// State of the bluetooth connection of a device
enum BluetoothConnectionState {
pimlie marked this conversation as resolved.
Show resolved Hide resolved
/// Device is connected
connected,
/// Device is disconnect
disconnected;
}

Loading