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.
280 lines
13 KiB
Dart
280 lines
13 KiB
Dart
import 'dart:async';
|
|
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/weight_data_model.dart';
|
|
import 'package:diplomaticquarterapp/theme/colors.dart';
|
|
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
|
|
import 'package:diplomaticquarterapp/uitl/ble_utils.dart';
|
|
import 'package:diplomaticquarterapp/uitl/bluetooth_off.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 WeightScaleBLE extends StatefulWidget {
|
|
@override
|
|
State<WeightScaleBLE> createState() => _WeightScaleBLEState();
|
|
}
|
|
|
|
class _WeightScaleBLEState extends State<WeightScaleBLE> {
|
|
String connectionStatus = "disconnected";
|
|
String currentWeight = "0.0";
|
|
|
|
BluetoothDevice currentConnectedDevice;
|
|
|
|
StreamSubscription bleDevicesStream;
|
|
StreamSubscription weightValuesStream;
|
|
|
|
WeightScaleData weightScaleData = WeightScaleData();
|
|
|
|
final bleConnectionStatus = ValueNotifier<String>("Disconnected");
|
|
|
|
String resultSet1 = "";
|
|
String resultSet2 = "";
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
bleConnectionStatus.dispose();
|
|
bleDevicesStream.cancel();
|
|
weightValuesStream.cancel();
|
|
currentConnectedDevice.disconnect();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AppScaffold(
|
|
appBarTitle: TranslationBase.of(context).weight,
|
|
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();
|
|
// parseResultData();
|
|
},
|
|
color: CustomColors.green,
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 50.0,
|
|
),
|
|
ValueListenableBuilder(
|
|
valueListenable: bleConnectionStatus,
|
|
builder: (context, value, _) {
|
|
return Text("Connection state: $value");
|
|
},
|
|
),
|
|
SizedBox(
|
|
height: 50.0,
|
|
),
|
|
Column(
|
|
children: [
|
|
Text("Current Weight: ${weightScaleData.weight}" + " kg"),
|
|
Text("Current BMI: ${weightScaleData.bmi}"),
|
|
Text("Current Body Fat: ${weightScaleData.fat}" + "%"),
|
|
Text("Current Bone Weight: ${weightScaleData.bone}" + " kg"),
|
|
Text("Current Water: ${weightScaleData.water}" + "%"),
|
|
Text("Current Muscle: ${weightScaleData.muscle}" + "%"),
|
|
Text("Current BMR: ${weightScaleData.bmr}" + " calories/day"),
|
|
],
|
|
),
|
|
// })
|
|
],
|
|
),
|
|
);
|
|
} 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) {
|
|
if (element.device.localName.toLowerCase() == "sdic") {
|
|
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();
|
|
// await currentConnectedDevice.clearGattCache();
|
|
List<BluetoothService> services = await element.device.discoverServices(timeout: 5);
|
|
services.forEach((service) {
|
|
if (service.serviceUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_SERVICE) {
|
|
print(service.serviceUuid);
|
|
service.characteristics.forEach((characteristic) async {
|
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF1) {
|
|
print(characteristic.characteristicUuid);
|
|
print(characteristic.properties.toString());
|
|
characteristic.onValueReceived.listen((event) {
|
|
print("onValueReceived fff1 Stream");
|
|
print(event);
|
|
if (event[0] == 129) {
|
|
// Issue result ack command
|
|
Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
characteristic.write([0x01]).then((value) {
|
|
print("----fff1 result ack data written----");
|
|
});
|
|
});
|
|
}
|
|
// Error
|
|
else if (event[0] == 65) {
|
|
AppToast.showErrorToast(message: "Measurement Error Occurred!");
|
|
} else {
|
|
//Sample Results
|
|
// ----------Result Set 1----------: 42;0;1;0;0;0;0;65;9;b0;d2;0;7f;3;44;0;ac;1;cc;0
|
|
// ----------Result Set 2----------: 42;1;32;0;2c;0;1;3;84;9;1b;0;29;2;9c;0;10;0;e9
|
|
|
|
if (event[1] == 0) {
|
|
resultSet1 = convertResultSetToString(event);
|
|
print("----------Result Set 1----------: $resultSet1");
|
|
print("----------Result Set 2----------: $resultSet2");
|
|
} else {
|
|
resultSet2 = convertResultSetToString(event);
|
|
print("----------Result Set 1----------: $resultSet1");
|
|
print("----------Result Set 2----------: $resultSet2");
|
|
parseResultData();
|
|
}
|
|
}
|
|
});
|
|
await Future.delayed(Duration(milliseconds: 500)).then((value) async {
|
|
print("Delayed fff1 done");
|
|
if (!characteristic.isNotifying) await characteristic.setNotifyValue(true).catchError((err) {});
|
|
});
|
|
}
|
|
|
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF2) {
|
|
print(characteristic.characteristicUuid);
|
|
print(characteristic.properties.toString());
|
|
characteristic.onValueReceived.listen((event) {
|
|
print("onValueReceived fff2 Stream");
|
|
print(event);
|
|
});
|
|
|
|
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
print("Delayed fff2 done");
|
|
if (!characteristic.isNotifying) await characteristic.setNotifyValue(true).catchError((err) {});
|
|
});
|
|
|
|
// Write user data to fff2
|
|
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
characteristic.write([0x81, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x19, 0x01, 0x00, 0x00], withoutResponse: true).then((value) {
|
|
print("----fff2 user data written----");
|
|
});
|
|
|
|
// Issue get result command
|
|
await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
|
|
characteristic.write([0x41, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00], withoutResponse: true).then((value) {
|
|
print("----fff2 get result data written----");
|
|
});
|
|
});
|
|
});
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
});
|
|
});
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
// onError(e) => print(e);
|
|
);
|
|
|
|
FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false);
|
|
}
|
|
}
|
|
|
|
String adjustHexString(String value) {
|
|
return value.length == 1 ? "0" + value : value;
|
|
}
|
|
|
|
void parseResultData() {
|
|
List<String> hexStringResSet1 = resultSet1.split(";");
|
|
List<String> hexStringResSet2 = resultSet2.split(";");
|
|
|
|
String hexStringWeight = adjustHexString(hexStringResSet1[13]) + adjustHexString(hexStringResSet1[14]);
|
|
String hexStringBMI = adjustHexString(hexStringResSet1[15]) + adjustHexString(hexStringResSet1[16]);
|
|
String hexStringFat = adjustHexString(hexStringResSet2[3]) + adjustHexString(hexStringResSet2[4]);
|
|
String hexStringBone = adjustHexString(hexStringResSet2[11]) + adjustHexString(hexStringResSet2[12]);
|
|
String hexStringWater = adjustHexString(hexStringResSet2[13]) + adjustHexString(hexStringResSet2[14]);
|
|
String hexStringMuscle = adjustHexString(hexStringResSet2[7]) + adjustHexString(hexStringResSet2[8]);
|
|
String hexStringBMR = adjustHexString(hexStringResSet2[9]) + adjustHexString(hexStringResSet2[10]);
|
|
|
|
print((int.parse(hexStringWeight, radix: 16) * 0.1).toStringAsFixed(1));
|
|
print((int.parse(hexStringBMI, radix: 16) * 0.1).toStringAsFixed(1));
|
|
print((int.parse(hexStringFat, radix: 16) * 0.1).toStringAsFixed(1));
|
|
print((int.parse(hexStringMuscle, radix: 16) * 0.1).toStringAsFixed(1));
|
|
print((int.parse(hexStringBMR, radix: 16)));
|
|
print((int.parse(hexStringBone, radix: 16) * 0.1).toStringAsFixed(1));
|
|
print((int.parse(hexStringWater, radix: 16) * 0.1).toStringAsFixed(1));
|
|
|
|
setState(() {
|
|
weightScaleData.weight = (int.parse(hexStringWeight, radix: 16) * 0.1).toStringAsFixed(1);
|
|
weightScaleData.bmi = (int.parse(hexStringBMI, radix: 16) * 0.1).toStringAsFixed(1);
|
|
weightScaleData.fat = (int.parse(hexStringFat, radix: 16) * 0.1).toStringAsFixed(1);
|
|
weightScaleData.muscle = (int.parse(hexStringMuscle, radix: 16) * 0.1).toStringAsFixed(1);
|
|
weightScaleData.bmr = (int.parse(hexStringBMR, radix: 16)).toString();
|
|
weightScaleData.bone = (int.parse(hexStringBone, radix: 16) * 0.1).toStringAsFixed(1);
|
|
weightScaleData.water = (int.parse(hexStringWater, radix: 16) * 0.1).toStringAsFixed(1);
|
|
});
|
|
}
|
|
|
|
String convertResultSetToString(List<int> byteArray) {
|
|
String resSet;
|
|
resSet = (byteArray.map(
|
|
(x) {
|
|
return x.toRadixString(16);
|
|
},
|
|
)).join(";");
|
|
return resSet;
|
|
}
|
|
|
|
String convertIntListToHex(List<int> byteArray) {
|
|
String b = (byteArray.map((x) {
|
|
return x.toRadixString(16);
|
|
})).join(";");
|
|
List<String> hexString = b.split(";");
|
|
print("HexString: $hexString");
|
|
String returnString = hexString[2] + hexString[3];
|
|
print("Temp Hex String: $returnString");
|
|
final number = int.parse(returnString, radix: 16);
|
|
print("Temp Number: ${number * 0.1}");
|
|
|
|
return (number * 0.1).toStringAsFixed(1);
|
|
}
|
|
}
|