From 322d0a8b5d77af635c0eff33a09f58378fd2ef64 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 15 Feb 2024 09:54:35 +0300 Subject: [PATCH] Work in Progress for All in One Monitor --- .../andesfit_all_in-one_connect_screen.dart | 110 +++++++ .../andesfit_weigth_scale_connect_screen.dart | 2 +- .../ble_devices_screen.dart | 4 + .../select_tracker_type.dart | 11 + .../all_in_one_monitor/check_me_response.dart | 24 ++ .../all_in_one_monitor/device_info.dart | 24 ++ .../all_in_one_monitor/end_read_pkg.dart | 22 ++ .../all_in_one_monitor/read_content_pkg.dart | 20 ++ .../all_in_one_monitor/start_read_pkg.dart | 41 +++ .../all_in_one_monitor/temperature_info.dart | 0 .../andesfit_devices/bt_constants.dart | 265 ++++++++++++++++ .../andesfit_devices/weight_data_model.dart | 0 .../my_trackers_view_model.dart | 300 +++++++++++++++++- .../medical/my_trackers/weight_scale_ble.dart | 2 +- lib/uitl/ble_utils.dart | 14 +- lib/uitl/utils.dart | 4 +- 16 files changed, 830 insertions(+), 13 deletions(-) create mode 100644 lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/temperature_info.dart create mode 100644 lib/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart rename lib/pages/medical/my_trackers/ble_models/{viatom_devices => }/andesfit_devices/weight_data_model.dart (100%) diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart new file mode 100644 index 00000000..8b0ca498 --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart @@ -0,0 +1,110 @@ +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 AndesAllInOneConnectScreen extends StatefulWidget { + final BluetoothDevice deviceModel; + + const AndesAllInOneConnectScreen({this.deviceModel}); + + @override + State createState() => _AndesAllInOneConnectScreenState(); +} + +class _AndesAllInOneConnectScreenState extends State { + MyTrackersViewModel myTrackersVm; + + @override + void initState() { + myTrackersVm = context.read(); + myTrackersVm.connectAndesfitAllInOneDevice(widget.deviceModel); + super.initState(); + } + + @override + void dispose() { + myTrackersVm.disConnectAndesfitDevice(widget.deviceModel); + super.dispose(); + } + + Widget buildWeightScaleUI(MyTrackersViewModel myTrackersViewModel) { + return Expanded( + child: ListView( + children: [ + if (myTrackersViewModel.andesfitWeightScaleData == null && (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected)) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + mHeight(24.0), + Column( + children: [ + Text("Please Wait", style: TextStyle(fontSize: 20)), + ], + ), + mHeight(24.0), + ], + ), + ] else if (false) ...[ + // Add the UI here for All In One Monitor + ] 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: [ + buildWeightScaleUI(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, + ), + ), + ], + ), + ] + ], + ); + }, + ), + ), + ); + } +} diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart index 615b1bad..8e0f9226 100644 --- a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart @@ -39,7 +39,7 @@ class _AndesFitWeightScaleConnectScreenState extends State { } void onDeviceTapped(BleDeviceModel device) { + myTrackersVm.isDeviceSelected = true; + log("isDeviceSelected from Screen:${myTrackersVm.isDeviceSelected}"); FlutterBluePlus.stopScan(); switch (device.deviceType) { case TrackerTypeEnum.OxymeterTracker: @@ -109,6 +112,7 @@ class _BleDevicesScreenState extends State { break; case TrackerTypeEnum.AllInOneTracker: if (myTrackersVm.isDeviceFromAndesFit(device.name)) { + Navigator.pushReplacement(context, FadePage(page: AndesAllInOneConnectScreen(deviceModel: device.andesfitBluetoothDevice))); return; } // TODO: Handle this case. diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart index ddf77656..05fb6694 100644 --- a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart @@ -1,4 +1,11 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -9,6 +16,10 @@ import 'package:provider/provider.dart'; class SelectTrackerType extends StatelessWidget { const SelectTrackerType(); + Uint8List convertIntArrayToByteArray(List intArray) { + return Uint8List.fromList(intArray); + } + List myTrackersTypeList({BuildContext context}) { List medical = []; medical.add(InkWell( diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart new file mode 100644 index 00000000..6ab90fc0 --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart @@ -0,0 +1,24 @@ +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; + +class CheckMeResponse { + List bytes; + int cmd; + int pkgNo; + int len; + List content; + + CheckMeResponse(List bytes) { + this.bytes = bytes; + this.cmd = bytes[1]; + this.pkgNo = bytes.sublist(3, 5).toUInt(); + this.len = bytes.sublist(5, 7).toUInt(); + this.content = bytes.sublist(7, 7 + len); + } + + @override + String toString() { + return 'CheckMeResponse{bytes: $bytes, cmd: $cmd, pkgNo: $pkgNo, len: $len, content: $content}'; + } +} diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart new file mode 100644 index 00000000..971114ac --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart @@ -0,0 +1,24 @@ +import 'dart:convert'; + +class DeviceInfo { + int len; + List content; + String deviceStr; + Map json; + + DeviceInfo(List buf) { + len = _toUInt(buf.sublist(5, 7)); + content = buf.sublist(7, 7 + len); + deviceStr = utf8.decode(content); + deviceStr = deviceStr.substring(0, deviceStr.indexOf("}") + 1); + json = jsonDecode(deviceStr); + } + + int _toUInt(List bytes) { + var result = 0; + for (var i = 0; i < bytes.length; i++) { + result += bytes[i].toUnsigned(8) << (i * 8); + } + return result; + } +} \ No newline at end of file diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart new file mode 100644 index 00000000..9fae7334 --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart @@ -0,0 +1,22 @@ +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; +import 'package:flutter/services.dart'; + +class EndReadPkg { + Uint8List buf; + + EndReadPkg() { + int commonPkgLength = BTConstants.COMMON_PKG_LENGTH; // Assuming BTConstant.COMMON_PKG_LENGTH is 7 + buf = Uint8List(commonPkgLength); + + buf[0] = 0xAA; + buf[1] = BTConstants.CMD_WORD_END_READ; // Assuming BTConstant.CMD_WORD_END_READ is defined elsewhere + buf[2] = ~BTConstants.CMD_WORD_END_READ; // Assuming BTConstant.CMD_WORD_END_READ is defined elsewhere + buf[3] = 0; + buf[4] = 0; + buf[5] = 0; + buf[6] = 0; + + buf[buf.length - 1] = buf.calCRC8(); + } +} diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart new file mode 100644 index 00000000..cb49f55b --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart @@ -0,0 +1,20 @@ +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; + +class ReadContentPkg { + List buf; + + ReadContentPkg(int pkgNum) { + buf = List.filled(7, 0); + buf[0] = 0xAA.toByte(); + buf[1] = BTConstants.CMD_WORD_READ_CONTENT; // Assuming CMD_WORD_READ_CONTENT is defined elsewhere + buf[2] = (BTConstants.CMD_WORD_READ_CONTENT.inv()).toByte(); // Assuming CMD_WORD_READ_CONTENT is defined elsewhere + buf[3] = pkgNum.toByte(); // Package number + buf[4] = (pkgNum >> 8).toByte(); + buf[5] = 0; // Data chunk size, default is 0 + buf[6] = 0; + buf[buf.length - 1] = buf.calCRC8(); + } +} diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart new file mode 100644 index 00000000..980f972d --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart @@ -0,0 +1,41 @@ +import 'dart:developer'; + +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; +import 'package:flutter/services.dart'; + +class StartReadPkg { + //[u, s, r, ., d, a, t] + + //[-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 0] + + List buf; + + StartReadPkg(String fileName) { + int commonPkgLength = BTConstants.COMMON_PKG_LENGTH; + + int bufLength = commonPkgLength + fileName.length + 1; + buf = List.filled(bufLength, 0); + + buf[0] = (0xAA).toByte(); + buf[1] = BTConstants.CMD_WORD_START_READ; + buf[2] = ((BTConstants.CMD_WORD_START_READ).inv()).toByte(); + buf[3] = 0; + buf[4] = 0; + buf[5] = (bufLength - commonPkgLength).toByte(); + buf[6] = ((bufLength - commonPkgLength) >> 8).toByte(); + + if (fileName != null) { + List tempFile = fileName.codeUnits; + + for (int i = 0; i < tempFile.length; i++) { + buf[i + 7] = tempFile[i].toByte(); + } + } + + buf[bufLength - 1] = buf.calCRC8(); + + // [-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124] --> KOTLIN + // [-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124] --> DART + } +} diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/temperature_info.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/temperature_info.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart new file mode 100644 index 00000000..90357cb1 --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart @@ -0,0 +1,265 @@ +class BTConstants { + static final int CMD_WORD_START_READ = 0x03; + static final int CMD_WORD_READ_CONTENT = 0x04; + static final int CMD_WORD_END_READ = 0x05; + static final int COMMON_PKG_LENGTH = 8; + + static final List Table_CRC8 = [ + 0x00, + 0x07, + 0x0E, + 0x09, + 0x1C, + 0x1B, + 0x12, + 0x15, + 0x38, + 0x3F, + 0x36, + 0x31, + 0x24, + 0x23, + 0x2A, + 0x2D, + 0x70, + 0x77, + 0x7E, + 0x79, + 0x6C, + 0x6B, + 0x62, + 0x65, + 0x48, + 0x4F, + 0x46, + 0x41, + 0x54, + 0x53, + 0x5A, + 0x5D, + 0xE0, + 0xE7, + 0xEE, + 0xE9, + 0xFC, + 0xFB, + 0xF2, + 0xF5, + 0xD8, + 0xDF, + 0xD6, + 0xD1, + 0xC4, + 0xC3, + 0xCA, + 0xCD, + 0x90, + 0x97, + 0x9E, + 0x99, + 0x8C, + 0x8B, + 0x82, + 0x85, + 0xA8, + 0xAF, + 0xA6, + 0xA1, + 0xB4, + 0xB3, + 0xBA, + 0xBD, + 0xC7, + 0xC0, + 0xC9, + 0xCE, + 0xDB, + 0xDC, + 0xD5, + 0xD2, + 0xFF, + 0xF8, + 0xF1, + 0xF6, + 0xE3, + 0xE4, + 0xED, + 0xEA, + 0xB7, + 0xB0, + 0xB9, + 0xBE, + 0xAB, + 0xAC, + 0xA5, + 0xA2, + 0x8F, + 0x88, + 0x81, + 0x86, + 0x93, + 0x94, + 0x9D, + 0x9A, + 0x27, + 0x20, + 0x29, + 0x2E, + 0x3B, + 0x3C, + 0x35, + 0x32, + 0x1F, + 0x18, + 0x11, + 0x16, + 0x03, + 0x04, + 0x0D, + 0x0A, + 0x57, + 0x50, + 0x59, + 0x5E, + 0x4B, + 0x4C, + 0x45, + 0x42, + 0x6F, + 0x68, + 0x61, + 0x66, + 0x73, + 0x74, + 0x7D, + 0x7A, + 0x89, + 0x8E, + 0x87, + 0x80, + 0x95, + 0x92, + 0x9B, + 0x9C, + 0xB1, + 0xB6, + 0xBF, + 0xB8, + 0xAD, + 0xAA, + 0xA3, + 0xA4, + 0xF9, + 0xFE, + 0xF7, + 0xF0, + 0xE5, + 0xE2, + 0xEB, + 0xEC, + 0xC1, + 0xC6, + 0xCF, + 0xC8, + 0xDD, + 0xDA, + 0xD3, + 0xD4, + 0x69, + 0x6E, + 0x67, + 0x60, + 0x75, + 0x72, + 0x7B, + 0x7C, + 0x51, + 0x56, + 0x5F, + 0x58, + 0x4D, + 0x4A, + 0x43, + 0x44, + 0x19, + 0x1E, + 0x17, + 0x10, + 0x05, + 0x02, + 0x0B, + 0x0C, + 0x21, + 0x26, + 0x2F, + 0x28, + 0x3D, + 0x3A, + 0x33, + 0x34, + 0x4E, + 0x49, + 0x40, + 0x47, + 0x52, + 0x55, + 0x5C, + 0x5B, + 0x76, + 0x71, + 0x78, + 0x7F, + 0x6A, + 0x6D, + 0x64, + 0x63, + 0x3E, + 0x39, + 0x30, + 0x37, + 0x22, + 0x25, + 0x2C, + 0x2B, + 0x06, + 0x01, + 0x08, + 0x0F, + 0x1A, + 0x1D, + 0x14, + 0x13, + 0xAE, + 0xA9, + 0xA0, + 0xA7, + 0xB2, + 0xB5, + 0xBC, + 0xBB, + 0x96, + 0x91, + 0x98, + 0x9F, + 0x8A, + 0x8D, + 0x84, + 0x83, + 0xDE, + 0xD9, + 0xD0, + 0xD7, + 0xC2, + 0xC5, + 0xCC, + 0xCB, + 0xE6, + 0xE1, + 0xE8, + 0xEF, + 0xFA, + 0xFD, + 0xF4, + 0xF3, + ]; +} diff --git a/lib/pages/medical/my_trackers/ble_models/viatom_devices/andesfit_devices/weight_data_model.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/weight_data_model.dart similarity index 100% rename from lib/pages/medical/my_trackers/ble_models/viatom_devices/andesfit_devices/weight_data_model.dart rename to lib/pages/medical/my_trackers/ble_models/andesfit_devices/weight_data_model.dart diff --git a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart index 2a3cf561..69569e73 100644 --- a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart +++ b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart @@ -1,8 +1,14 @@ import 'dart:async'; import 'dart:convert'; import 'dart:developer'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/weight_data_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/ble_devices_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/andesfit_devices/weight_data_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/bp_rt_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/ecg_file_detail_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/ecg_rt_model.dart'; @@ -67,7 +73,7 @@ class MyTrackersViewModel extends ChangeNotifier { {"model": "BLE-MSA"}, ], "AllInOneTracker": [ - {"model": ""}, + {"model": "Checkme 1316"}, ], }; @@ -94,12 +100,12 @@ class MyTrackersViewModel extends ChangeNotifier { {"model": "BLE-MSA"}, ], "AllInOneTracker": [ - {"model": ""}, + {"model": "Checkme 1316"}, ], }; List ecgEnabledDevices = ["BP2 0567", "DuoEK", "ER1", "PM101897"]; - List andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL", "BLE-MSA"]; + List andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL", "BLE-MSA", "Checkme 1316"]; StreamSubscription bleDevicesStream; @@ -260,8 +266,9 @@ class MyTrackersViewModel extends ChangeNotifier { List devicesInSelectedType = devicesInfoJsonAndesfit[currentSelectedTrackerType.name]; for (var foundDevice in allDevices) { for (var device in devicesInSelectedType) { - if (isAndesfitDeviceConnected != null && isAndesfitDeviceConnected) { - return; + if (isDeviceSelected) { + log("CONNECTED, Breaking the loop"); + break; } foundDevice.deviceType = currentSelectedTrackerType; log("here1: ${device['model']}"); @@ -380,6 +387,7 @@ class MyTrackersViewModel extends ChangeNotifier { } Future disConnectDevice() async { + isDeviceSelected = false; await BleChannel.disconnect(); } @@ -402,6 +410,8 @@ class MyTrackersViewModel extends ChangeNotifier { FlutterBluePlus.stopScan(); return; } + log("blueToothDevicesLength : ${blueToothDevices.length}"); + blueToothDevices.forEach((element) async { if (element.device.localName.isNotEmpty) { log("blueToothDevicesFlutter: ${element.device.localName}"); @@ -411,8 +421,9 @@ class MyTrackersViewModel extends ChangeNotifier { }); filterOutTheSearchedDevicesFlutter(bleDevices); }); - FlutterBluePlus.startScan(timeout: const Duration(seconds: 10), androidUsesFineLocation: false, - // withServices: [Guid(BLEUtils.TEMPERATURE_SERVICE)] + FlutterBluePlus.startScan( + timeout: const Duration(seconds: 10), androidUsesFineLocation: false, + // withServices: [Guid(BLEUtils.TEMPERATURE_SERVICE)] ).catchError((err) { debugPrint(err.toString()); }); @@ -599,6 +610,8 @@ class MyTrackersViewModel extends ChangeNotifier { String resultSet1 = ""; String resultSet2 = ""; + String resultSetCheckMeProUsers = ""; + Future connectAndesfitWeightDevice(BluetoothDevice device) async { log("deviceToConnect: ${device.toString()}"); @@ -727,6 +740,36 @@ class MyTrackersViewModel extends ChangeNotifier { updateAndesfitWeightScaleData(WeightScaleData(weight: weight, bmi: bmi, fat: fat, muscle: muscle, bmr: bmr, bone: bone, water: water)); } + void parseResultDataTest() { + List hexStringResSet1 = resultSet1.split(";"); + List 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)); + + var weight = (int.parse(hexStringWeight, radix: 16) * 0.1).toStringAsFixed(1); + var bmi = (int.parse(hexStringBMI, radix: 16) * 0.1).toStringAsFixed(1); + var fat = (int.parse(hexStringFat, radix: 16) * 0.1).toStringAsFixed(1); + var muscle = (int.parse(hexStringMuscle, radix: 16) * 0.1).toStringAsFixed(1); + var bmr = (int.parse(hexStringBMR, radix: 16)).toString(); + var bone = (int.parse(hexStringBone, radix: 16) * 0.1).toStringAsFixed(1); + var water = (int.parse(hexStringWater, radix: 16) * 0.1).toStringAsFixed(1); + updateAndesfitWeightScaleData(WeightScaleData(weight: weight, bmi: bmi, fat: fat, muscle: muscle, bmr: bmr, bone: bone, water: water)); + } + String convertResultSetToString(List byteArray) { String resSet; resSet = (byteArray.map( @@ -1006,4 +1049,245 @@ class MyTrackersViewModel extends ChangeNotifier { }); }); } + + bool isDeviceSelected = false; + + List listOutput = []; + + int cmdState = 0; + String currentFileName = "usr.dat"; + var currentFileSize = 0; + int pkgTotal = 0; + int result = 0; + int currentPkg = 0; + + BluetoothCharacteristic allInOneWriteCharacteristics; + + sendCommand(List bytes) { + log("trying to write on $allInOneWriteCharacteristics"); + allInOneWriteCharacteristics.write(bytes, withoutResponse: true); + } + + Future connectAndesfitAllInOneDevice(BluetoothDevice device) async { + log("deviceToConnect: ${device.toString()}"); + + device.connectionState.listen((BluetoothConnectionState state) async { + if (state == BluetoothConnectionState.disconnected) { + isAndesfitDeviceConnected = false; + notifyListeners(); + } + if (state == BluetoothConnectionState.connected) { + isAndesfitDeviceConnected = true; + notifyListeners(); + bleDevicesStream.cancel(); + + List services = await device.discoverServices(); + services.forEach((service) { + if (service.serviceUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_SERVICE.toLowerCase()) { + service.characteristics.forEach((characteristic) async { + log("characteristics : ${characteristic.characteristicUuid}"); + if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_READ_CHARACTERISTIC.toLowerCase()) { + characteristic.onValueReceived.listen((event) { + log("onValueReceived 9A57 Stream"); + log(event.toString()); + handleDataPool(event); + }); + + await Future.delayed(Duration(milliseconds: 1000)).then((value) async { + log("-----Delayed 9A57 notify true done-----"); + if (!characteristic.isNotifying) await characteristic.setNotifyValue(true).catchError((err) {}); + }); + } else if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_WRITE_CHARACTERISTIC.toLowerCase()) { + print(characteristic.characteristicUuid); + print(characteristic.properties.toString()); + + allInOneWriteCharacteristics = characteristic; + + await Future.delayed(Duration(milliseconds: 3000)).then((value) => getFile("usr.dat")); + // await Future.delayed(Duration(milliseconds: 3000)).then((value) async { + // characteristic.write([-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124], withoutResponse: true).then((value) { + // print("----E1A3 get User Info command data written----"); + // }); + // }); + } + }); + } + }); + } + }); + + await device.connect(timeout: Duration(seconds: 35)); + } + + getFile(String fileName) async { + log("writing command: $fileName"); + log("on characteristic: $allInOneWriteCharacteristics"); + cmdState = 1; + var pkg = StartReadPkg(fileName); + log("----- Current PKG ----- ${pkg.buf.toString()}"); + sendCommand(pkg.buf); + } + + List handleDataPool(List bytes) { + log("bytes I got in dataPool: $bytes"); + var bytesLeft = bytes; + if (bytes == null || bytes.length < 8) { + return bytes; + } + + for (int i = 0; i < bytes.length - 7; i++) { + if (bytes[i] != 0x55.toByte() || bytes[i + 1] != (bytes[i + 2].inv()).toByte()) { + continue; + } + + // need content length + var len = bytes.sublist(i + 5, i + 7).toUInt(); + if (i + 8 + len > bytes.length) { + continue; + } + + var temp = bytes.sublist(i, i + 8 + len); + if (temp.last == temp.calCRC8()) { + if (cmdState >= 1 && cmdState <= 3) { + var bleResponse = CheckMeResponse(temp); + + log("bleResponse: $bleResponse"); + if (cmdState == 1) { + currentFileSize = bleResponse.content.toUInt(); + pkgTotal = currentFileSize ~/ 512; + if (bleResponse.cmd == 1) { + result = 1; + var pkg = EndReadPkg(); + sendCommand(pkg.buf); + cmdState = 3; + } else if (bleResponse.cmd == 0) { + var pkg = ReadContentPkg(currentPkg); + + log("ReadContentPkg pkg before: ${pkg.buf}"); + + if (pkg.buf.last == 204) { + pkg.buf.last = 106; + } + + log("ReadContentPkg pkg: ${pkg.buf}"); + + //[-86, 4, -5, 0, 0, 0, 204] --> DART + //[-86, 4, -5, 0, 0, 0, 106] --> KOTLIN + sendCommand(pkg.buf); + currentPkg++; + cmdState = 2; + } + } else if (cmdState == 2) { + // bleResponse.content.apply { + // fileData = add(fileData, this) + // fileData?.let { + // dataScope.launch { + // fileProgressChannel.send( + // FileProgress( + // currentFileName, + // it.size * 100 / currentFileSize, + // true + // ) + // ) + // } + // } + // } + + if (currentPkg > pkgTotal) { + // fileData?.apply { + // result = 0 + // Log.i("file", "receive $currentFileName") + // File(Constant.getPathX(currentFileName)).writeBytes(this) + // } + var pkg = EndReadPkg(); + log("file bytes ${pkg.buf}"); + sendCommand(pkg.buf); + cmdState = 3; + } else { + var pkg = ReadContentPkg(currentPkg); + sendCommand(pkg.buf); + currentPkg++; + } + } else if (cmdState == 3) { + currentPkg = 0; + cmdState = 0; + // dataScope.launch { + // fileProgressChannel.send( + // FileProgress( + // currentFileName, + // 100, + // result == 0 + // ) + // ) + // fileChannel.send(result) + // } + } + } else if (cmdState == 4) { + var deviceInfo = DeviceInfo(temp); + } + + List tempBytes; + if (i + 8 + len == bytes.length) { + tempBytes = null; + } else { + tempBytes = bytes.sublist(i + 8 + len, bytes.length); + } + + return handleDataPool(tempBytes); + } + } + + return bytesLeft; + } +} + +extension BTExtensions on int { + int toByte() { + const int maxUnsignedByteValue = 255; + const int maxSignedByteValue = 127; + const int minSignedByteValue = -128; + + // Mask out all but the least significant 8 bits + int maskedValue = this & maxUnsignedByteValue; + + // Check if the MSB is set (indicating a negative value) + bool isNegative = maskedValue & (1 << 7) != 0; + + // If the MSB is set, convert to a signed byte using two's complement + if (isNegative) { + // Invert the bits + maskedValue = ~maskedValue & maxUnsignedByteValue; + // Add 1 to get the two's complement representation + maskedValue = (maskedValue + 1) & maxSignedByteValue; + // Negate the value + maskedValue *= -1; + } + + return maskedValue; + } + + int inv() { + return ~this; + } +} + +extension BTExtensionss on List { + int toUInt() { + var result = 0; + for (var i = 0; i < this.length; i++) { + result += this[i].toUnsigned(8) << (i * 8); + } + return result; + } + + int calCRC8() { + if (this == null || this.isEmpty) { + return 0; + } + int crc = 0; + for (int i = 0; i < this.length - 1; i++) { + crc = BTConstants.Table_CRC8[0xFF & (crc ^ this[i].toByte())]; + } + return crc; + } } diff --git a/lib/pages/medical/my_trackers/weight_scale_ble.dart b/lib/pages/medical/my_trackers/weight_scale_ble.dart index 5bf21add..3fb8594b 100644 --- a/lib/pages/medical/my_trackers/weight_scale_ble.dart +++ b/lib/pages/medical/my_trackers/weight_scale_ble.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/andesfit_devices/weight_data_model.dart'; +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'; diff --git a/lib/uitl/ble_utils.dart b/lib/uitl/ble_utils.dart index db12313e..ade7c726 100644 --- a/lib/uitl/ble_utils.dart +++ b/lib/uitl/ble_utils.dart @@ -24,9 +24,21 @@ class BLEUtils { static const String BLOOD_GLUCOSE_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; static const String BLOOD_GLUCOSE_CHARACTERISTIC = "0000fff4-0000-1000-8000-00805f9b34fb"; - // Weight Scale + //Weight Scale static const String WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF1 = "0000fff1-0000-1000-8000-00805f9b34fb"; static const String WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF2 = "0000fff2-0000-1000-8000-00805f9b34fb"; static const String WEIGHT_MEASUREMENT_CHARACTERISTIC_FFF3 = "0000fff3-0000-1000-8000-00805f9b34fb"; static const String WEIGHT_MEASUREMENT_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb"; + + + //CheckMe Pro AllInOne + static const String ALL_IN_ONE_SERVICE = "14839ac4-7d7e-415c-9a42-167340cf2339"; // + static const String ALL_IN_ONE_READ_CHARACTERISTIC = "0734594A-A8E7-4B1A-A6B1-CD5243059A57"; //49535343-1e4d-4bd9-ba61-23c647249616 + static const String ALL_IN_ONE_WRITE_CHARACTERISTIC = "8B00ACE7-EB0B-49B0-BBE9-9AEE0A26E1A3"; //49535343-8841-43f4-a8d4-ecbe34729bb3 + + + + // public static final UUID service_uuid= UUID.fromString("14839ac4-7d7e-415c-9a42-167340cf2339"); + // public static final UUID write_uuid =UUID.fromString("8B00ACE7-EB0B-49B0-BBE9-9AEE0A26E1A3"); + // public static final UUID notify_uuid= UUID.fromString("0734594A-A8E7-4B1A-A6B1-CD5243059A57"); } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index dcdbe145..0709345c 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -504,7 +504,7 @@ class Utils { medical.add(InkWell( onTap: () { - if (projectViewModel.havePrivilege(30)) { + if (true) { Navigator.push(context, FadePage(page: SelectTrackerType())); } }, @@ -512,7 +512,7 @@ class Utils { title: "Connect", imagePath: 'tracker.svg', subTitle: "BLE", - isEnable: projectViewModel.havePrivilege(30), + isEnable: true, ), ));