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.
PatientApp-KKUMC/lib/pages/medical/my_trackers/spirometer.dart

251 lines
11 KiB
Dart

import 'dart:async';
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 SpirometerBLE extends StatefulWidget {
@override
State<SpirometerBLE> createState() => _SpirometerBLEState();
}
class _SpirometerBLEState extends State<SpirometerBLE> {
String connectionStatus = "disconnected";
BluetoothDevice currentConnectedDevice;
StreamSubscription bleDevicesStream;
BluetoothCharacteristic spirometerReadCharacteristicFf0a;
BluetoothCharacteristic spirometerWriteCharacteristicFf0b;
final bleConnectionStatus = ValueNotifier<String>("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
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: TranslationBase.of(context).spirometer,
showNewAppBar: true,
isShowDecPage: false,
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,
),
ValueListenableBuilder(
valueListenable: bleConnectionStatus,
builder: (context, value, _) {
return Text("Connection state: $value");
},
),
SizedBox(
height: 50.0,
),
// Text("Current Temp: $currentTempInCelsius"),
],
),
);
} 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) {
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<BluetoothService> 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----");
});
});
});
}
},
);
}
},
);
});
}
}
},
);
},
// onError(e) => print(e);
);
FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false);
}
}
}
class BluetoothOffScreen extends StatelessWidget {
const BluetoothOffScreen({Key key, 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) {}
},
),
],
),
),
),
);
}
}