Added andesfit Spirometer

dev_3.3_BLE
Faiz Hashmi 2 years ago
parent 0967e45752
commit fd79b10f41

@ -36,7 +36,7 @@ class _AndesFitBloodSugarConnectScreenState extends State<AndesFitBloodSugarConn
super.dispose();
}
Widget buildWeightScaleUI(MyTrackersViewModel myTrackersViewModel) {
Widget buildBloodSugarUI(MyTrackersViewModel myTrackersViewModel) {
return Expanded(
child: ListView(
children: [
@ -104,7 +104,7 @@ class _AndesFitBloodSugarConnectScreenState extends State<AndesFitBloodSugarConn
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
buildWeightScaleUI(myTrackersViewModel),
buildBloodSugarUI(myTrackersViewModel),
if (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected) ...[
Row(
children: [

@ -0,0 +1,137 @@
import 'package:diplomaticquarterapp/extensions/string_extensions.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AndesFitSpirometerConnectScreen extends StatefulWidget {
final BluetoothDevice deviceModel;
const AndesFitSpirometerConnectScreen({this.deviceModel});
@override
State<AndesFitSpirometerConnectScreen> createState() => _AndesFitSpirometerConnectScreenState();
}
class _AndesFitSpirometerConnectScreenState extends State<AndesFitSpirometerConnectScreen> {
MyTrackersViewModel myTrackersVm;
@override
void initState() {
myTrackersVm = context.read<MyTrackersViewModel>();
myTrackersVm.connectAndesfitSpirometerDevice(widget.deviceModel);
super.initState();
}
@override
void dispose() {
myTrackersVm.valuePEF = null;
myTrackersVm.valueFEV = null;
myTrackersVm.isAndesfitDeviceConnected = null;
myTrackersVm.disConnectAndesfitDevice(widget.deviceModel);
super.dispose();
}
Widget buildSpirometerUI(MyTrackersViewModel myTrackersViewModel) {
return Expanded(
child: ListView(
children: [
if ((myTrackersViewModel.valuePEF == null && myTrackersViewModel.valueFEV == null) && myTrackersViewModel.isAndesfitDeviceConnected) ...[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
mHeight(24.0),
Column(
children: [
Text("Please blow gently", style: TextStyle(fontSize: 20)),
],
),
mHeight(24.0),
],
),
] else if ((myTrackersViewModel.valuePEF != null && myTrackersViewModel.valueFEV != null)) ...[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
mHeight(24.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Text("PEF", style: TextStyle(fontSize: 20)),
Text(myTrackersViewModel.valuePEF.toString(), style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
Text("", style: TextStyle(fontSize: 15)),
],
),
Column(
children: [
Text("FEV", style: TextStyle(fontSize: 20)),
Text(myTrackersViewModel.valueFEV.toString(), style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
Text("", style: TextStyle(fontSize: 15)),
],
),
],
),
],
),
] else ...[
Padding(
padding: const EdgeInsets.all(24.0),
child: Center(
child: Text(
"Some animation with the instruction",
style: TextStyle(fontSize: 9.0),
),
),
)
],
],
),
);
}
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: "${widget.deviceModel.localName}",
showNewAppBar: true,
isShowDecPage: false,
showNewAppBarTitle: true,
backgroundColor: Color(0xffF8F8F8),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Consumer(
builder: (BuildContext context, MyTrackersViewModel myTrackersViewModel, Widget child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
buildSpirometerUI(myTrackersViewModel),
if (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected) ...[
Row(
children: [
Expanded(
child: DefaultButton(
"Disconnect with ${widget.deviceModel.localName}",
() async {
myTrackersVm.disConnectAndesfitDevice(widget.deviceModel);
Navigator.pop(context);
},
textColor: Colors.white,
),
),
],
),
]
],
);
},
),
),
);
}
}

@ -2,6 +2,7 @@ import 'dart:developer';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_pressure_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_sugar_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_spirometer_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_temperature_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/lepu_device_types/bloodpressure_connect_screen.dart';
@ -95,6 +96,14 @@ class _BleDevicesScreenState extends State<BleDevicesScreen> {
return;
}
break;
case TrackerTypeEnum.Spirometer:
if (myTrackersVm.isDeviceFromAndesFit(device.name)) {
myTrackersVm.currentTempInCelsius = null;
Navigator.pushReplacement(context, FadePage(page: AndesFitSpirometerConnectScreen(deviceModel: device.andesfitBluetoothDevice)));
return;
}
break;
case TrackerTypeEnum.AllInOneTracker:
if (myTrackersVm.isDeviceFromAndesFit(device.name)) {
return;

@ -83,6 +83,18 @@ class SelectTrackerType extends StatelessWidget {
isEnable: true,
),
));
medical.add(InkWell(
onTap: () {
context.read<MyTrackersViewModel>().updateSelectedTrackerType(TrackerTypeEnum.Spirometer);
Navigator.of(context).push(FadePage(page: BleDevicesScreen()));
},
child: MedicalProfileItem(
title: "Spirometer",
imagePath: 'tracker.svg',
subTitle: "Tracker",
isEnable: true,
),
));
medical.add(InkWell(
onTap: () {
context.read<MyTrackersViewModel>().updateSelectedTrackerType(TrackerTypeEnum.AllInOneTracker);

@ -20,7 +20,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart';
import 'package:flutter/material.dart';
enum TrackerTypeEnum { OxymeterTracker, BloodPressureTracker, BloodSugarTracker, ECGTracker, WeightScale, Temperature, AllInOneTracker }
enum TrackerTypeEnum { OxymeterTracker, BloodPressureTracker, BloodSugarTracker, ECGTracker, WeightScale, Temperature, Spirometer, AllInOneTracker }
//NativeEventNames
@ -63,6 +63,9 @@ class MyTrackersViewModel extends ChangeNotifier {
"Temperature": [
{"model": ""},
],
"Spirometer": [
{"model": "BLE-MSA"},
],
"AllInOneTracker": [
{"model": ""},
],
@ -87,13 +90,16 @@ class MyTrackersViewModel extends ChangeNotifier {
"Temperature": [
{"model": "TEMP"},
],
"Spirometer": [
{"model": "BLE-MSA"},
],
"AllInOneTracker": [
{"model": ""},
],
};
List<String> ecgEnabledDevices = ["BP2 0567", "DuoEK", "ER1", "PM101897"];
List<String> andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL"];
List<String> andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL", "BLE-MSA"];
StreamSubscription bleDevicesStream;
@ -847,4 +853,138 @@ class MyTrackersViewModel extends ChangeNotifier {
return results;
}
BluetoothCharacteristic spirometerReadCharacteristicFf0a;
BluetoothCharacteristic spirometerWriteCharacteristicFf0b;
String valuePEF;
String valueFEV;
Timer timerForSpirometer;
bool isHistoryCommandWritten = false;
Future<void> connectAndesfitSpirometerDevice(BluetoothDevice device) async {
device.connectionState.listen((BluetoothConnectionState state) async {
if (state == BluetoothConnectionState.disconnected) {
isAndesfitDeviceConnected = false;
notifyListeners();
}
if (state == BluetoothConnectionState.connected) {
isAndesfitDeviceConnected = true;
notifyListeners();
bleDevicesStream.cancel();
List<BluetoothService> services = await 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);
//response received
if (event[0] == 221) {
convertIntListToHexForSpirometer(event);
}
if (event[0] == 170) {
timerForSpirometer.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) async {
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) async {
print("----ff0b delete history command data written----");
isHistoryCommandWritten = true;
await Future.delayed(Duration(milliseconds: 500)).then((value) async {
isHistoryCommandWritten = false;
// Write ACK command to ff0b every 500 ms
startACKCommandToMSA100();
});
});
});
});
});
}
}
});
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
startACKCommandToMSA100();
}
},
);
}
},
);
}
});
await device.connect(timeout: Duration(seconds: 35));
}
void convertIntListToHexForSpirometer(List<int> byteArray) {
String b = (byteArray.map((x) {
return x.toRadixString(16);
})).join(";");
List<String> hexString = b.split(";");
print("HexString: $hexString");
String returnStringPEF = hexString[8] + hexString[7];
String returnStringFEV = hexString[6] + hexString[5];
print("Temp Hex String PEF: $returnStringPEF");
print("Temp Hex String FEV: $returnStringFEV");
final numberPEF = int.parse(returnStringPEF, radix: 16);
final numberFEV = int.parse(returnStringFEV, radix: 16);
print("Temp Number FEV: ${numberFEV * 0.01}");
print("Temp Number PEF: $numberPEF");
valueFEV = (numberFEV * 0.01).toStringAsFixed(2);
valuePEF = numberPEF.toString();
notifyListeners();
}
void startACKCommandToMSA100() async {
// Write ACK command to ff0b every 500 ms
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
timerForSpirometer = Timer.periodic(Duration(milliseconds: 500), (Timer t) {
spirometerWriteCharacteristicFf0b.write([0x55, 0x06], withoutResponse: false).then((value) {
print("----ff0b ACK command data written----");
});
});
});
}
}

Loading…
Cancel
Save