From e282d73dcfb2bc84e6961d11ba67f349669c7096 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 25 Sep 2023 09:49:21 +0300 Subject: [PATCH] Spirometer implementation --- lib/pages/landing/landing_page.dart | 3 +- lib/pages/medical/my_trackers/spirometer.dart | 184 +++++++++++------- .../medical/my_trackers/weight_scale_ble.dart | 6 - lib/uitl/ble_utils.dart | 3 +- 4 files changed, 118 insertions(+), 78 deletions(-) diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 0a33698c..70e683ae 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -17,6 +17,7 @@ import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/landing/home_page_2.dart'; import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/spirometer.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/weight_scale_ble.dart'; import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -568,7 +569,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { }, onLoginClick: () { // login(); - Navigator.push(context, FadePage(page: WeightScaleBLE())); + Navigator.push(context, FadePage(page: SpirometerBLE())); }, onMedicalFileClick: () { changeCurrentTab(1); diff --git a/lib/pages/medical/my_trackers/spirometer.dart b/lib/pages/medical/my_trackers/spirometer.dart index 77925ac5..1b0bff66 100644 --- a/lib/pages/medical/my_trackers/spirometer.dart +++ b/lib/pages/medical/my_trackers/spirometer.dart @@ -19,16 +19,27 @@ class _SpirometerBLEState extends State { String connectionStatus = "disconnected"; BluetoothDevice currentConnectedDevice; + StreamSubscription bleDevicesStream; + + BluetoothCharacteristic spirometerReadCharacteristicFf0a; + BluetoothCharacteristic spirometerWriteCharacteristicFf0b; + + final bleConnectionStatus = ValueNotifier("Disconnected"); + Timer _timer; Timer _timerRead; + bool isHistoryCommandWritten = false; + @override void dispose() { super.dispose(); if (currentConnectedDevice != null) currentConnectedDevice.disconnect(); if (_timer != null && _timer.isActive) _timer.cancel(); if (_timerRead != null && _timerRead.isActive) _timerRead.cancel(); + bleConnectionStatus.dispose(); + if (bleDevicesStream != null) bleDevicesStream.cancel(); } @override @@ -36,7 +47,7 @@ class _SpirometerBLEState extends State { return AppScaffold( appBarTitle: TranslationBase.of(context).spirometer, showNewAppBar: true, - isShowDecPage: true, + isShowDecPage: false, showNewAppBarTitle: true, backgroundColor: Color(0xffF8F8F8), body: SingleChildScrollView( @@ -62,7 +73,12 @@ class _SpirometerBLEState extends State { SizedBox( height: 50.0, ), - Text("Connection state: $connectionStatus"), + ValueListenableBuilder( + valueListenable: bleConnectionStatus, + builder: (context, value, _) { + return Text("Connection state: $value"); + }, + ), SizedBox( height: 50.0, ), @@ -87,77 +103,105 @@ class _SpirometerBLEState extends State { void startBLEConnection() { if (FlutterBluePlus.isScanningNow == false) { - setState(() { - connectionStatus = "Connecting..."; - }); - - FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false).then((value) { - List blueToothDevices = []; - // List blueToothDevices = value; - blueToothDevices.forEach((element) async { - if (element.device.localName.isNotEmpty) { - if (element.device.localName.toLowerCase() == "ble-msa") { - element.device.connectionState.listen((BluetoothConnectionState state) async { - setState(() { - connectionStatus = state.toString(); - }); - if (state == BluetoothConnectionState.disconnected) { - // typically, start a periodic timer that tries to periodically reconnect. - // Note: you must always re-discover services after disconnection! - if (_timer != null && _timer.isActive) _timer.cancel(); - if (_timerRead != null && _timerRead.isActive) _timerRead.cancel(); - } - if (state == BluetoothConnectionState.connected) { - currentConnectedDevice = element.device; - - List BLEToMSAWriteCharacters = []; - BLEToMSAWriteCharacters.add(int.parse("5506", radix: 16)); - - List services = await element.device.discoverServices(); - services.forEach((service) { - if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_SERVICE) { - print(service.serviceUuid); - service.characteristics.forEach((characteristic) async { - if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_CHARACTERISTIC) { - print(characteristic.characteristicUuid); - _timer = Timer.periodic(Duration(seconds: 2), (Timer timer) { - characteristic.write(BLEToMSAWriteCharacters).then((value) { - print("Characteristic response:"); - }).catchError((err) {}); - }); - } - if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.MSA100_TO_BLE_CHARACTERISTIC) { - print(characteristic.characteristicUuid); - _timerRead = Timer.periodic(Duration(seconds: 2), (Timer timer) { - characteristic.read().then((value) { - print("Characteristic Read value: "); - print(value); - }); - }); - - // characteristic.onValueReceived.listen((event) { - // print("onValueReceived Stream"); - // print(event); - // setState(() { - // currentTempInCelsius = convertIntListToHex(event); - // String currentTempInFahrenheit = ((num.parse(currentTempInCelsius) * 1.8) + 32).toStringAsFixed(1); - // currentTempInCelsius = currentTempInCelsius + "\u2103" + " / " + currentTempInFahrenheit + "\u2109"; - // }); - // }); - // await characteristic.setNotifyValue(true); + bleConnectionStatus.value = "Connecting..."; + + bleDevicesStream = FlutterBluePlus.scanResults.listen( + (results) { + List blueToothDevices = results; + blueToothDevices.forEach( + (element) { + if (element.device.localName.isNotEmpty) { + if (element.device.localName.toLowerCase() == "ble-msa") { + bleDevicesStream.cancel(); + element.device.connect(timeout: Duration(seconds: 5), autoConnect: false).then((value) async { + bleConnectionStatus.value = "Connected..."; + print("Device Connected-------"); + currentConnectedDevice = element.device; + FlutterBluePlus.stopScan(); + List services = await element.device.discoverServices(timeout: 5); + services.forEach( + (service) { + if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_SERVICE) { + print(service.serviceUuid); + service.characteristics.forEach( + (characteristic) async { + if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_READ_CHARACTERISTIC) { + spirometerReadCharacteristicFf0a = characteristic; + print(spirometerReadCharacteristicFf0a.characteristicUuid); + print(spirometerReadCharacteristicFf0a.properties.toString()); + spirometerReadCharacteristicFf0a.onValueReceived.listen((event) async { + print("onValueReceived ff0a Stream"); + print(event); + + //Sample response + // dd14d93d5c1f01a302f8de3d5c1c017302 + + if (event[0] == 170) { + _timer.cancel(); + + // Write get history command to ff0b + if (!isHistoryCommandWritten) { + await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + spirometerWriteCharacteristicFf0b.write([0x55, 0x01], withoutResponse: false).then((value) { + print("----ff0b get history command data written----"); + isHistoryCommandWritten = true; + }); + }); + + // Write get 1st history command to ff0b + await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + spirometerWriteCharacteristicFf0b.write([0x55, 0x02, 0x01, 0x00], withoutResponse: false).then((value) { + print("----ff0b get 1st history command data written----"); + isHistoryCommandWritten = true; + }); + }); + + // Write delete history command to ff0b + // await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + // spirometerWriteCharacteristicFf0b.write([0x55, 0x03], withoutResponse: false).then((value) { + // print("----ff0b delete history command data written----"); + // isHistoryCommandWritten = true; + // }); + // }); + } + } + }); + + await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + print("Delayed ff0a done"); + if (!spirometerReadCharacteristicFf0a.isNotifying) await spirometerReadCharacteristicFf0a.setNotifyValue(true).catchError((err) {}); + }); + } + + if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_WRITE_CHARACTERISTIC) { + spirometerWriteCharacteristicFf0b = characteristic; + print(spirometerWriteCharacteristicFf0b.characteristicUuid); + print(spirometerWriteCharacteristicFf0b.properties.toString()); + + // Write ACK command to ff0b every 500 ms + await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + _timer = Timer.periodic(Duration(milliseconds: 500), (Timer t) { + spirometerWriteCharacteristicFf0b.write([0x55, 0x06], withoutResponse: false).then((value) { + print("----ff0b ACK command data written----"); + }); + }); + }); + } + }, + ); } - }); - return true; - } + }, + ); }); } - }); - await element.device.connect(timeout: Duration(seconds: 35)); - return true; - } - } - }); - }); + } + }, + ); + }, + // onError(e) => print(e); + ); + + FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false); } } } diff --git a/lib/pages/medical/my_trackers/weight_scale_ble.dart b/lib/pages/medical/my_trackers/weight_scale_ble.dart index 0f966c42..8f87889e 100644 --- a/lib/pages/medical/my_trackers/weight_scale_ble.dart +++ b/lib/pages/medical/my_trackers/weight_scale_ble.dart @@ -30,10 +30,6 @@ class _WeightScaleBLEState extends State { final bleConnectionStatus = ValueNotifier("Disconnected"); - BluetoothCharacteristic ble_fff1; - BluetoothCharacteristic ble_fff2; - BluetoothCharacteristic ble_fff3; - String resultSet1 = ""; String resultSet2 = ""; @@ -140,7 +136,6 @@ class _WeightScaleBLEState extends State { print(service.serviceUuid); service.characteristics.forEach((characteristic) async { if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF1) { - ble_fff1 = characteristic; print(characteristic.characteristicUuid); print(characteristic.properties.toString()); characteristic.onValueReceived.listen((event) { @@ -181,7 +176,6 @@ class _WeightScaleBLEState extends State { } if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF2) { - ble_fff2 = characteristic; print(characteristic.characteristicUuid); print(characteristic.properties.toString()); characteristic.onValueReceived.listen((event) { diff --git a/lib/uitl/ble_utils.dart b/lib/uitl/ble_utils.dart index 8e9a4a6a..db12313e 100644 --- a/lib/uitl/ble_utils.dart +++ b/lib/uitl/ble_utils.dart @@ -9,7 +9,8 @@ class BLEUtils { //Spirometer static const String BLE_TO_MSA100_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; - static const String BLE_TO_MSA100_CHARACTERISTIC = "0000ff0b-0000-1000-8000-00805f9b34fb"; + static const String BLE_TO_MSA100_WRITE_CHARACTERISTIC = "0000ff0b-0000-1000-8000-00805f9b34fb"; + static const String BLE_TO_MSA100_READ_CHARACTERISTIC = "0000ff0a-0000-1000-8000-00805f9b34fb"; static const String MSA100_TO_BLE_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; static const String MSA100_TO_BLE_CHARACTERISTIC = "0000ff0a-0000-1000-8000-00805f9b34fb";