You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
13 KiB
Dart
323 lines
13 KiB
Dart
import 'dart:async';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:diplomaticquarterapp/theme/colors.dart';
|
|
import 'package:diplomaticquarterapp/uitl/ble_utils.dart';
|
|
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
|
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
|
|
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
class BloodPressureBLE extends StatefulWidget {
|
|
@override
|
|
State<BloodPressureBLE> createState() => _BloodPressureBLEState();
|
|
}
|
|
|
|
class _BloodPressureBLEState extends State<BloodPressureBLE> {
|
|
String connectionStatus = "disconnected";
|
|
String currentBPmmHG = "0/0 mmHG";
|
|
String currentPulse = "0 PPM";
|
|
|
|
BluetoothDevice? currentConnectedDevice;
|
|
|
|
StreamSubscription? bloodPressureReadingStream;
|
|
|
|
StreamSubscription? bleDevicesStream;
|
|
StreamSubscription? bleDeviceConnectionStream;
|
|
|
|
final bleConnectionStatus = ValueNotifier<String>("Disconnected");
|
|
|
|
Timer? _timer;
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
if (bleDevicesStream != null) bleDevicesStream!.cancel();
|
|
if (currentConnectedDevice != null) currentConnectedDevice!.disconnect();
|
|
bleConnectionStatus.dispose();
|
|
if (bleDeviceConnectionStream != null) bleDeviceConnectionStream!.cancel();
|
|
if (bloodPressureReadingStream != null) bloodPressureReadingStream!.cancel();
|
|
if (currentConnectedDevice != null) currentConnectedDevice!.disconnect();
|
|
if (_timer != null && _timer!.isActive) _timer!.cancel();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AppScaffold(
|
|
appBarTitle: TranslationBase.of(context).bloodPressure,
|
|
showNewAppBar: true,
|
|
isShowDecPage: true,
|
|
showNewAppBarTitle: true,
|
|
backgroundColor: Color(0xffF8F8F8),
|
|
body: SingleChildScrollView(
|
|
child: StreamBuilder<BluetoothAdapterState>(
|
|
stream: FlutterBluePlus.adapterState,
|
|
initialData: BluetoothAdapterState.unknown,
|
|
builder: (c, snapshot) {
|
|
final adapterState = snapshot.data;
|
|
if (adapterState == BluetoothAdapterState.on) {
|
|
return Container(
|
|
margin: EdgeInsets.only(top: 200.0, left: 50.0, right: 50.0),
|
|
child: Column(
|
|
children: [
|
|
Center(
|
|
child: DefaultButton(
|
|
TranslationBase.of(context).start.toUpperCase(),
|
|
() {
|
|
checkBLEPermissions();
|
|
},
|
|
color: CustomColors.green,
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 50.0,
|
|
),
|
|
Text("Connection state: $connectionStatus"),
|
|
SizedBox(
|
|
height: 50.0,
|
|
),
|
|
Text("Current BP Level: $currentBPmmHG"),
|
|
SizedBox(
|
|
height: 20.0,
|
|
),
|
|
Text("Current Pulse: $currentPulse"),
|
|
],
|
|
),
|
|
);
|
|
} else {
|
|
FlutterBluePlus.stopScan();
|
|
return SizedBox(height: 300.0, child: BluetoothOffScreen(adapterState: adapterState!));
|
|
}
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
void checkBLEPermissions() {
|
|
[Permission.location, Permission.storage, Permission.bluetooth, Permission.bluetoothConnect, Permission.bluetoothScan].request().then((status) {
|
|
startBLEConnection();
|
|
});
|
|
}
|
|
|
|
void startBLEConnection() {
|
|
if (FlutterBluePlus.isScanningNow == false) {
|
|
bleConnectionStatus.value = "Connecting...";
|
|
|
|
bleDevicesStream = FlutterBluePlus.scanResults.listen((results) {
|
|
List<ScanResult> blueToothDevices = results;
|
|
blueToothDevices.forEach((element) async {
|
|
if (element.device.localName.isNotEmpty) {
|
|
log("blueToothDevices: ${element.device.localName}");
|
|
if (element.device.localName.toLowerCase() == "pm101897") {
|
|
bleDevicesStream!.cancel();
|
|
element.device.connect(timeout: Duration(seconds: 30), autoConnect: false).then((value) async {
|
|
bleConnectionStatus.value = "Connected...";
|
|
print("Device Connected-------");
|
|
currentConnectedDevice = element.device;
|
|
bleDeviceConnectionStream = currentConnectedDevice!.connectionState.listen((event) {
|
|
if (event == BluetoothConnectionState.disconnected) {
|
|
bleConnectionStatus.value = "Disconnected...";
|
|
print("Device Disconnected-------");
|
|
// if (_timer.isActive) _timer.cancel();
|
|
}
|
|
});
|
|
FlutterBluePlus.stopScan();
|
|
|
|
List<BluetoothService> services = await element.device.discoverServices(timeout: 30).catchError((err) {
|
|
print(err.toString());
|
|
element.device.disconnect(timeout: 15);
|
|
});
|
|
|
|
if (services != null && services.isNotEmpty) {
|
|
services.forEach((service) {
|
|
if (service.serviceUuid.toString().toLowerCase() == BLEUtils.ECG_SERVICE) {
|
|
print(service.serviceUuid);
|
|
service.characteristics.forEach((characteristic) async {
|
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ECG_READ_CHARACTERISTIC) {
|
|
print(characteristic.characteristicUuid);
|
|
print(characteristic.properties.toString());
|
|
|
|
characteristic.onValueReceived.listen((event) {
|
|
print("onValueReceived 1e4d Stream");
|
|
print(event);
|
|
});
|
|
|
|
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
print("-----Delayed 1e4d notify true done-----");
|
|
if (!characteristic.isNotifying) await characteristic.setNotifyValue(true).catchError((err) {});
|
|
});
|
|
}
|
|
|
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ECG_WRITE_CHARACTERISTIC) {
|
|
print(characteristic.characteristicUuid);
|
|
print(characteristic.properties.toString());
|
|
|
|
// Write get cases command to 8841
|
|
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
// 0x90 00 00 00 1
|
|
characteristic.write([0x90, 0x00, 0x00, 0x00, 0x01], withoutResponse: false).then((value) {
|
|
print("----8841 get device info command data written----");
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}).catchError((onError) {
|
|
print("----- ERRORRRR!!!!!! -------");
|
|
print(onError.toString());
|
|
});
|
|
}
|
|
}
|
|
|
|
});
|
|
});
|
|
FlutterBluePlus.startScan(timeout: const Duration(seconds: 15), androidUsesFineLocation: false);
|
|
}
|
|
}
|
|
|
|
void startBLEConnectionII() {
|
|
if (FlutterBluePlus.isScanningNow == false) {
|
|
setState(() {
|
|
connectionStatus = "Connecting...";
|
|
});
|
|
|
|
FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false).then((value) {
|
|
// List<ScanResult> blueToothDevices = value;
|
|
List<ScanResult> blueToothDevices = [];
|
|
blueToothDevices.forEach((element) async {
|
|
if (element.device.localName.isNotEmpty) {
|
|
if (element.device.localName.toLowerCase() == "bpm") {
|
|
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!
|
|
|
|
// _timer = Timer.periodic(Duration(seconds: 2), (Timer timer) {
|
|
// startBLEConnection();
|
|
// });
|
|
}
|
|
if (state == BluetoothConnectionState.connected) {
|
|
currentConnectedDevice = element.device;
|
|
// _timer.cancel();
|
|
List<BluetoothService> services = await element.device.discoverServices();
|
|
services.forEach((service) {
|
|
if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLOOD_PRESSURE_SERVICE) {
|
|
print(service.serviceUuid);
|
|
service.characteristics.forEach((characteristic) async {
|
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLOOD_PRESSURE_CHARACTERISTIC) {
|
|
print(characteristic.characteristicUuid);
|
|
bloodPressureReadingStream = characteristic.onValueReceived.listen((event) {
|
|
print("onValueReceived Stream");
|
|
print(event);
|
|
setState(() {
|
|
if (event.length < 12) {
|
|
currentBPmmHG = "Measuring...";
|
|
} else {
|
|
currentBPmmHG = "Measurement complete!";
|
|
Map<String, dynamic> results = handleBPResult(event, characteristic);
|
|
currentBPmmHG = results["systolic"] + "/" + results["diastolic"] + " - " + (results["isBPHigh"] == "true" ? "High BP" : "Normal BP");
|
|
currentPulse = results["pulse"] + " - " + (results["isPulseHigh"] == "true" ? "High pulse" : "Normal Pulse");
|
|
}
|
|
});
|
|
});
|
|
await characteristic.setNotifyValue(true);
|
|
}
|
|
});
|
|
return ;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
await element.device.connect(timeout: Duration(seconds: 35));
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
Map<String, dynamic> handleBPResult(List<int> byteArray, BluetoothCharacteristic characteristic) {
|
|
// [28, 0, 148, 0, 118, 0, 0, 0, 106, 0, 0, 0]
|
|
|
|
// {isBPHigh: true, systolic: 145, diastolic: 111, pulse: 109, isPulseHigh: true}
|
|
|
|
Map<String, dynamic> results = Map();
|
|
|
|
if (byteArray[1] != 0 && byteArray[3] != 0) {
|
|
results["isBPHigh"] = "false";
|
|
results["systolic"] = byteArray[1].toString();
|
|
results["diastolic"] = byteArray[3].toString();
|
|
} else {
|
|
results["isBPHigh"] = "true";
|
|
results["systolic"] = byteArray[2].toString();
|
|
results["diastolic"] = byteArray[4].toString();
|
|
}
|
|
|
|
if (byteArray[8] != 0) {
|
|
results["pulse"] = byteArray[8].toString();
|
|
results["isPulseHigh"] = "true";
|
|
} else {
|
|
results["pulse"] = byteArray[9].toString();
|
|
results["isPulseHigh"] = "false";
|
|
}
|
|
|
|
if (characteristic.isNotifying) characteristic.setNotifyValue(false);
|
|
|
|
print(results);
|
|
|
|
return results;
|
|
}
|
|
|
|
class BluetoothOffScreen extends StatelessWidget {
|
|
const BluetoothOffScreen({Key? key, required this.adapterState}) : super(key: key);
|
|
|
|
final BluetoothAdapterState adapterState;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ScaffoldMessenger(
|
|
child: Scaffold(
|
|
backgroundColor: Colors.lightBlue,
|
|
body: Center(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: <Widget>[
|
|
const Icon(
|
|
Icons.bluetooth_disabled,
|
|
size: 200.0,
|
|
color: Colors.white54,
|
|
),
|
|
Text(
|
|
'Bluetooth Adapter is ${adapterState != null ? adapterState.toString().split(".").last + ", Please turn on your bluetooth to continue." : 'not available'}.',
|
|
textAlign: TextAlign.center,
|
|
style: Theme.of(context).primaryTextTheme.titleSmall?.copyWith(color: Colors.white),
|
|
),
|
|
if (Platform.isAndroid)
|
|
ElevatedButton(
|
|
child: const Text('TURN ON'),
|
|
onPressed: () async {
|
|
try {
|
|
if (Platform.isAndroid) {
|
|
await FlutterBluePlus.turnOn();
|
|
}
|
|
} catch (e) {}
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|