Added ECG chart view

dev_3.3_BLE
Faiz Hashmi 2 years ago
parent 4ec93e8609
commit 55b93feda3

@ -11,6 +11,7 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.EventChannel
import android.util.SparseArray
import android.view.View
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.ble.utils.EcgData
import com.cloud.diplomaticquarterapp.ble.utils.HexString
@ -24,6 +25,7 @@ import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.check_me_pro.bean.toJson
import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.BpInfo
import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.EcgInfo
import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.EcgWaveInfo
import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.GluInfo
import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.OxyInfo
import com.cloud.diplomaticquarterapp.utils.UiChannel
@ -55,6 +57,7 @@ import com.lepu.blepro.utils.DateUtil
import com.lepu.blepro.utils.Er1Decompress
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -98,6 +101,7 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
private const val GET_OXI_DATA_CHECK_ME_PRO = "getOxiDataFromCheckMePro"
private const val GET_TEMP_DATA_CHECK_ME_PRO = "getTempDataFromCheckMePro"
private const val GET_ECG_DATA_CHECK_ME_PRO = "getEcgDataFromCheckMePro"
private const val GET_ECG_WAVE_CHECK_ME_PRO = "getEcgWaveFromCheckMePro"
private const val GET_GLUCOSE_DATA_CHECK_ME_PRO = "getGlucoseDataFromCheckMePro"
val scan = BleScanManager()
@ -259,6 +263,8 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
getOxyDataFromCheckMePro()
} else if (methodCall.method == GET_ECG_DATA_CHECK_ME_PRO) {
getECGDataFromCheckMePro()
} else if (methodCall.method == GET_ECG_WAVE_CHECK_ME_PRO) {
getECGWaveFromCheckMePro(methodCall.arguments as String)
} else if (methodCall.method == GET_TEMP_DATA_CHECK_ME_PRO) {
getTemperatureDataFromCheckMePro()
} else if (methodCall.method == SCAN_DEVICE_EKG) {
@ -508,6 +514,31 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
}
}
private fun getECGWaveFromCheckMePro(timeString: String) {
val file = File(Constant.getPathX(timeString))
val exist = file.exists()
MainScope().launch {
if (!exist) {
// if (!MainActivity.isOffline) {
bleWorker.getFile(timeString)
// }
}
val file2 = File(Constant.getPathX(timeString))
delay(100)
BleDataWorker.fileProgressChannel.send(BleDataWorker.FileProgress(progress = 0))
delay(100)
BleDataWorker.fileProgressChannel.send(BleDataWorker.FileProgress(progress = -100))
if (file2.exists()) {
val info = EcgWaveInfo(file2.readBytes())
val json = gson.toJson(info)
Log.d("ECGWaveData", json.toString())
val returnData = mapOf("type" to "ECGWaveCheckMePro", "data" to json.toString())
eventSink?.success(returnData)
}
}
}
private fun getTemperatureDataFromCheckMePro() {
val file = File(Constant.getPathX("tmp.dat"))
if (file.exists()) {

@ -1,4 +1,5 @@
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/checkme_ecg_info_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_bp_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_ecg_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_glucose_model.dart';
@ -125,7 +126,10 @@ class CheckMeAllInOneInfoScreen extends StatelessWidget {
itemBuilder: (context, index) {
CheckMeECGModel checkMeECGModel = myTrackersVm.checkMeEcg[index];
return InkWell(
onTap: () => Navigator.pop(context),
onTap: () {
myTrackersVm.getEcgWaveDataFromCheckMePro(checkMeECGModel.timeString);
Navigator.push(context, MaterialPageRoute(builder: (context) => CheckMeECGInfoScreen(TrackerTypeEnum.ECGTracker)));
},
child: Container(
decoration: cardRadius(12),
padding: EdgeInsets.all(12.0),
@ -133,8 +137,8 @@ class CheckMeAllInOneInfoScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Date: ${checkMeECGModel.date}"),
mHeight(4.0),
Text("way: ${checkMeECGModel.way}"),
mHeight(8),
Text("TimeString: ${checkMeECGModel.timeString}"),
],
),
),
@ -249,7 +253,7 @@ class CheckMeAllInOneInfoScreen extends StatelessWidget {
itemBuilder: (context, index) {
CheckMeGlucoseModel checkMeGlucoseModel = myTrackersVm.checkMeGlucose[index];
return InkWell(
onTap: () => Navigator.pop(context),
onTap: () => null,
child: Container(
decoration: cardRadius(12),
padding: EdgeInsets.all(12.0),

@ -0,0 +1,89 @@
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_ecg_wave_model.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class CheckMeECGChartView extends StatelessWidget {
final CheckMeECGWaveModel checkMeECGWave;
CheckMeECGChartView({@required this.checkMeECGWave});
@override
Widget build(BuildContext context) {
List<int> list = checkMeECGWave.bytes;
List<List<int>> mainList = chunkIntList(list, 1250);
return ListView.separated(
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(right: MediaQuery.of(context).size.width - (MediaQuery.of(context).size.width * (mainList[index].length / 1250))),
child: SizedBox(
height: 120.0,
child: LineChart(
LineChartData(
lineTouchData: LineTouchData(handleBuiltInTouches: false),
gridData: FlGridData(
show: true,
verticalInterval: 30,
horizontalInterval: 30,
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.red[300],
strokeWidth: 0.4,
);
},
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.red[300],
strokeWidth: 0.4,
);
},
),
titlesData: FlTitlesData(show: false),
borderData: FlBorderData(
show: false,
border: Border.all(color: const Color(0xff37434d), width: 1),
),
minX: 0,
maxX: (mainList[index].length.toDouble() - 1),
minY: list.reduce((value, element) => value < element ? value : element).toDouble(),
maxY: list.reduce((value, element) => value > element ? value : element).toDouble(),
lineBarsData: [
LineChartBarData(
isCurved: false,
preventCurveOverShooting: true,
barWidth: 0.5,
dotData: FlDotData(show: false),
spots: getDataList(mainList[index]),
colors: [Colors.grey[800]],
isStrokeCapRound: true,
belowBarData: BarAreaData(show: false),
),
],
),
),
),
);
},
itemCount: mainList.length,
separatorBuilder: (context, index) => SizedBox(height: 14),
);
}
List<List<int>> chunkIntList(List<int> list, int chunkSize) {
List<List<int>> chunks = [];
for (int i = 0; i < list.length; i += chunkSize) {
int end = i + chunkSize;
chunks.add(list.sublist(i, end > list.length ? list.length : end));
}
return chunks;
}
List<FlSpot> getDataList(List<int> list) {
List<FlSpot> spotsList = [];
for (int i = 0; i < list.length; i++) {
spotsList.add(FlSpot(i.toDouble(), list[i].toDouble()));
}
return spotsList;
}
}

@ -0,0 +1,114 @@
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/checkme_ecg_chart_view.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_bp_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_ecg_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_glucose_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_oxi_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_temperature_model.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/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CheckMeECGInfoScreen extends StatelessWidget {
final TrackerTypeEnum allInOneTrackerTypeEnum;
const CheckMeECGInfoScreen(this.allInOneTrackerTypeEnum);
String getTrackerNameByEnum(TrackerTypeEnum trackerTypeEnum) {
switch (trackerTypeEnum) {
case TrackerTypeEnum.OxymeterTracker:
return "Oxymeter";
case TrackerTypeEnum.BloodPressureTracker:
return "Blood Pressure";
case TrackerTypeEnum.BloodSugarTracker:
return "Blood Glucose";
case TrackerTypeEnum.ECGTracker:
return "ECG";
case TrackerTypeEnum.WeightScale:
return "Weight Scale";
case TrackerTypeEnum.Temperature:
return "Temperature";
case TrackerTypeEnum.Spirometer:
return "Spirometer";
case TrackerTypeEnum.AllInOneTracker:
return "All in One";
}
return "All in One";
}
Widget buildECGDetailsWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
return Container(
decoration: cardRadius(12),
padding: EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("HR: ${myTrackersVm.checkMeECGWave.hr} bpm"),
Text("ST: ${myTrackersVm.checkMeECGWave.st} mV"),
Text("QRS: ${myTrackersVm.checkMeECGWave.qrs} ms"),
],
),
mHeight(4.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("PVCS: ${myTrackersVm.checkMeECGWave.pvcs} "),
Text("QTC: ${myTrackersVm.checkMeECGWave.qtc} ms"),
Text("QT: ${myTrackersVm.checkMeECGWave.qt} ms"),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: "${getTrackerNameByEnum(allInOneTrackerTypeEnum)}",
showNewAppBar: true,
isShowDecPage: false,
showNewAppBarTitle: true,
backgroundColor: Color(0xffF8F8F8),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Consumer(
builder: (BuildContext context, MyTrackersViewModel myTrackersVm, Widget child) {
if (myTrackersVm.checkMeECGWave == null) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Center(
child: Text(
"Some animation with the instruction",
style: TextStyle(fontSize: 9.0),
),
),
);
}
return Column(
children: [
buildECGDetailsWidget(myTrackersVm, context),
mHeight(20),
CheckMeECGChartView(checkMeECGWave: myTrackersVm.checkMeECGWave),
],
);
},
),
),
),
);
}
}

@ -199,7 +199,19 @@ class BleChannel {
try {
print("----------Flutter getEcgDataFromCheckMePro -------");
final String result = await platform.invokeMethod('getEcgDataFromCheckMePro');
print("----------Flutter getDeviceInfoCheckMePro result -------");
print("----------Flutter getEcgDataFromCheckMePro result -------");
print(result);
return result;
} catch (e) {
return "Error: $e";
}
}
static Future<String> getEcgWaveDataFromCheckMePro(String timeString) async {
try {
print("----------Flutter getEcgWaveFromCheckMePro -------");
final String result = await platform.invokeMethod('getEcgWaveFromCheckMePro', timeString);
print("----------Flutter getEcgWaveFromCheckMePro result -------");
print(result);
return result;
} catch (e) {

@ -0,0 +1,58 @@
class CheckMeECGWaveModel {
List<int> bytes;
int hr;
List<int> hrList;
int hrSize;
int pvcs;
int qrs;
int qt;
int qtc;
int result;
int st;
int total;
int waveIntSize;
List<int> waveList;
int waveSize;
int waveViewSize;
CheckMeECGWaveModel(
{this.bytes, this.hr, this.hrList, this.hrSize, this.pvcs, this.qrs, this.qt, this.qtc, this.result, this.st, this.total, this.waveIntSize, this.waveList, this.waveSize, this.waveViewSize});
CheckMeECGWaveModel.fromJson(Map<String, dynamic> json) {
bytes = json['bytes'].cast<int>();
hr = json['hr'];
hrList = json['hrList'].cast<int>();
hrSize = json['hrSize'];
pvcs = json['pvcs'];
qrs = json['qrs'];
qt = json['qt'];
qtc = json['qtc'];
result = json['result'];
st = json['st'];
total = json['total'];
waveIntSize = json['waveIntSize'];
waveList = json['waveList'].cast<int>();
waveSize = json['waveSize'];
waveViewSize = json['waveViewSize'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['bytes'] = this.bytes;
data['hr'] = this.hr;
data['hrList'] = this.hrList;
data['hrSize'] = this.hrSize;
data['pvcs'] = this.pvcs;
data['qrs'] = this.qrs;
data['qt'] = this.qt;
data['qtc'] = this.qtc;
data['result'] = this.result;
data['st'] = this.st;
data['total'] = this.total;
data['waveIntSize'] = this.waveIntSize;
data['waveList'] = this.waveList;
data['waveSize'] = this.waveSize;
data['waveViewSize'] = this.waveViewSize;
return data;
}
}

@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesf
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/ble_devices_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_bp_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_ecg_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_ecg_wave_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_glucose_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_oxi_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_temperature_model.dart';
@ -45,6 +46,7 @@ String kDevicesListCheckMe = "DevicesListCheckMe";
String kCheckMeUsersList = "CheckMeUsersList";
String kTemperatureCheckMePro = "TemperatureCheckMePro";
String kECGCheckMePro = "ECGCheckMePro";
String kECGWaveCheckMePro = "ECGWaveCheckMePro";
String kOxiCheckMePro = "OxiCheckMePro";
String kGlucoseCheckMePro = "GlucoseCheckMePro";
String kBPCheckMePro = "BPCheckMePro";
@ -1109,6 +1111,9 @@ class MyTrackersViewModel extends ChangeNotifier {
if (event['type'] == kECGCheckMePro) {
updateCheckMeEcgInfoModel(json.decode(event['data']));
}
if (event['type'] == kECGWaveCheckMePro) {
updateCheckMeEcgWaveInfoModel(json.decode(event['data']));
}
if (event['type'] == kBPCheckMePro) {
updateCheckMeBPInfoModel(json.decode(event['data']));
}
@ -1204,19 +1209,7 @@ class MyTrackersViewModel extends ChangeNotifier {
),
)
] else ...[
Material(
child: Center(
child: Text(
"No Users to show",
style: TextStyle(
fontSize: SizeConfig.textMultiplier * 1.6,
fontWeight: FontWeight.w600,
letterSpacing: -0.3,
height: 13 / 10,
),
),
),
),
getNoDataWidget(context),
]
],
);
@ -1227,6 +1220,9 @@ class MyTrackersViewModel extends ChangeNotifier {
}
Future<void> getTempDataFromCheckMePro() async {
if (checkMeTemperatures != null) {
checkMeTemperatures.clear();
}
await BleChannel.getTempDataFromCheckMePro();
}
@ -1241,6 +1237,9 @@ class MyTrackersViewModel extends ChangeNotifier {
}
Future<void> getOxiDataFromCheckMePro() async {
if (checkMeOxi != null) {
checkMeOxi.clear();
}
await BleChannel.getOxiDataFromCheckMePro();
}
@ -1255,6 +1254,9 @@ class MyTrackersViewModel extends ChangeNotifier {
}
Future<void> getECGDataFromCheckMePro() async {
if (checkMeEcg != null) {
checkMeEcg.clear();
}
await BleChannel.getEcgDataFromCheckMePro();
}
@ -1268,7 +1270,27 @@ class MyTrackersViewModel extends ChangeNotifier {
notifyListeners();
}
Future<void> getEcgWaveDataFromCheckMePro(String timeString) async {
if (checkMeECGWave != null) {
checkMeECGWave = null;
}
await BleChannel.getEcgWaveDataFromCheckMePro(timeString);
}
CheckMeECGWaveModel checkMeECGWave;
void updateCheckMeEcgWaveInfoModel(returnData) {
if (checkMeECGWave != null) {
checkMeECGWave = null;
}
checkMeECGWave = CheckMeECGWaveModel.fromJson(returnData);
notifyListeners();
}
Future<void> getBPDataFromCheckMePro(String userId) async {
if (checkMeBP != null) {
checkMeBP.clear();
}
await BleChannel.getBPDataFromCheckMePro(userId);
}
@ -1283,6 +1305,9 @@ class MyTrackersViewModel extends ChangeNotifier {
}
Future<void> getGlucoseDataFromCheckMePro(String userId) async {
if (checkMeGlucose != null) {
checkMeGlucose.clear();
}
await BleChannel.getGlucoseDataFromCheckMePro(userId);
}

Loading…
Cancel
Save