ECG Graph implemented

dev_3.3_BLE
haroon amjad 2 years ago
parent b6a3ae2380
commit 433616c7b6

@ -18,6 +18,8 @@ import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.EventChannel import io.flutter.plugin.common.EventChannel
import android.util.SparseArray import android.util.SparseArray
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.ble.utils.EcgData
import com.google.gson.Gson
//Ble //Ble
@ -28,10 +30,14 @@ import com.lepu.blepro.event.EventMsgConst.Ble.*
import com.lepu.blepro.event.InterfaceEvent import com.lepu.blepro.event.InterfaceEvent
import com.lepu.blepro.ext.BleServiceHelper import com.lepu.blepro.ext.BleServiceHelper
import com.lepu.blepro.ext.er2.DeviceInfo import com.lepu.blepro.ext.er2.DeviceInfo
import com.lepu.blepro.ext.er2.Er2EcgFile
import com.lepu.blepro.ext.er2.Er2File
import com.lepu.blepro.ext.pc60fw.RtParam import com.lepu.blepro.ext.pc60fw.RtParam
import com.lepu.blepro.objs.Bluetooth import com.lepu.blepro.objs.Bluetooth
import com.lepu.blepro.objs.BluetoothController import com.lepu.blepro.objs.BluetoothController
import com.lepu.blepro.observer.BleChangeObserver import com.lepu.blepro.observer.BleChangeObserver
import com.lepu.blepro.utils.DateUtil
import com.lepu.blepro.utils.Er1Decompress
import io.flutter.plugin.common.EventChannel.EventSink import io.flutter.plugin.common.EventChannel.EventSink
import no.nordicsemi.android.ble.observer.ConnectionObserver import no.nordicsemi.android.ble.observer.ConnectionObserver
@ -49,6 +55,7 @@ class BleBridge(
private const val SCAN_DEVICE = "scan" private const val SCAN_DEVICE = "scan"
private const val SCAN_DEVICE_EKG = "scan_ekg" private const val SCAN_DEVICE_EKG = "scan_ekg"
private const val EKG_FILES_LIST = "ekg_files_list" private const val EKG_FILES_LIST = "ekg_files_list"
private const val EKG_FILE_DETAIL = "ekg_file_detail"
private const val DISCONNECT_DEVICE = "disconnect_device" private const val DISCONNECT_DEVICE = "disconnect_device"
} }
@ -144,6 +151,9 @@ class BleBridge(
// scanDeviceEKG(methodCall, result) // scanDeviceEKG(methodCall, result)
} else if (methodCall.method == EKG_FILES_LIST) { } else if (methodCall.method == EKG_FILES_LIST) {
getEKGFilesList() getEKGFilesList()
} else if (methodCall.method == EKG_FILE_DETAIL) {
val fileName = methodCall.arguments;
getEKGFileDetail(fileName.toString())
} else { } else {
result.notImplemented() result.notImplemented()
} }
@ -211,6 +221,7 @@ class BleBridge(
} }
if (deviceName.contains("DuoEK", ignoreCase = true)) { if (deviceName.contains("DuoEK", ignoreCase = true)) {
val gson = Gson()
LiveEventBus.get<InterfaceEvent>(InterfaceEvent.ER2.EventEr2Info) LiveEventBus.get<InterfaceEvent>(InterfaceEvent.ER2.EventEr2Info)
.observe(this.mainActivity) { .observe(this.mainActivity) {
val data = it.data as DeviceInfo val data = it.data as DeviceInfo
@ -233,9 +244,23 @@ class BleBridge(
println("EventEr2SetTime") println("EventEr2SetTime")
// Get Device Info // Get Device Info
BleServiceHelper.BleServiceHelper.er2GetInfo(model) BleServiceHelper.BleServiceHelper.er2GetInfo(model)
}
//Get EKG File List LiveEventBus.get<InterfaceEvent>(InterfaceEvent.ER2.EventEr2ReadFileComplete)
// BleServiceHelper.BleServiceHelper.er2GetFileList(model) .observe(this.mainActivity) {
println("EventEr2ReadFileComplete")
val data = it.data as Er2File
val file = Er2EcgFile(data.content)
val ecgShorts = Er1Decompress.unCompressAlgECG(file.waveData)
val ecgData = EcgData()
val startTime = DateUtil.getSecondTimestamp(data.fileName.replace("R", ""))
ecgData.fileName = data.fileName
ecgData.duration = file.recordingTime
ecgData.shortData = ecgShorts
ecgData.startTime = startTime
val returnData =
mapOf("type" to "fileDetail", "data" to gson.toJson(ecgData))
// val output = gson.toJson(returnData)
eventSink?.success(returnData)
} }
} }
@ -271,9 +296,13 @@ class BleBridge(
} }
fun getEKGFilesList() { private fun getEKGFilesList() {
//Get EKG File List //Get EKG File List
BleServiceHelper.BleServiceHelper.er2GetFileList(model) BleServiceHelper.BleServiceHelper.er2GetFileList(model)
} }
private fun getEKGFileDetail(fileName: String) {
BleServiceHelper.BleServiceHelper.er2ReadFile(model, fileName)
}
} }

@ -0,0 +1,25 @@
class EKGFileDetailResponseModel {
int duration;
String fileName;
List<int> shortData;
int startTime;
EKGFileDetailResponseModel(
{this.duration, this.fileName, this.shortData, this.startTime});
EKGFileDetailResponseModel.fromJson(Map<String, dynamic> json) {
duration = json['duration'];
fileName = json['fileName'];
shortData = json['shortData'].cast<int>();
startTime = json['startTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['duration'] = this.duration;
data['fileName'] = this.fileName;
data['shortData'] = this.shortData;
data['startTime'] = this.startTime;
return data;
}
}

@ -0,0 +1,110 @@
import 'package:diplomaticquarterapp/models/ble_devices/viatom_devices/ekg_file_detail_response_model.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class EKGChartView extends StatefulWidget {
EKGFileDetailResponseModel ekgFileDetailResponseModel;
EKGChartView({@required this.ekgFileDetailResponseModel});
@override
State<EKGChartView> createState() => _EKGChartViewState();
}
class _EKGChartViewState extends State<EKGChartView> {
@override
void initState() {
super.initState();
print(widget.ekgFileDetailResponseModel.fileName);
}
@override
Widget build(BuildContext context) {
List<int> list = widget.ekgFileDetailResponseModel.shortData;
List<List<int>> mainList = chunkIntList(list, 1250);
return AppScaffold(
appBarTitle: "ECG",
showNewAppBar: true,
isShowDecPage: false,
showNewAppBarTitle: true,
backgroundColor: Color(0xffF8F8F8),
body: 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;
}
}

@ -1,7 +1,12 @@
import 'dart:convert';
import 'package:diplomaticquarterapp/models/ble_devices/viatom_devices/ekg_file_detail_response_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/viatom_devices/ekg_chart_view.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/viatom_ble/ble_connect.dart'; import 'package:diplomaticquarterapp/viatom_ble/ble_connect.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -37,7 +42,7 @@ class _EKG_BLEState extends State<EKG_BLE> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppScaffold( return AppScaffold(
appBarTitle: "EKG Tracker", appBarTitle: "ECG Tracker",
showNewAppBar: true, showNewAppBar: true,
isShowDecPage: false, isShowDecPage: false,
showNewAppBarTitle: true, showNewAppBarTitle: true,
@ -63,6 +68,11 @@ class _EKG_BLEState extends State<EKG_BLE> {
if (event['type'] == "fileList") { if (event['type'] == "fileList") {
parseEKGFilesList(event['data']); parseEKGFilesList(event['data']);
} }
if (event['type'] == 'fileDetail') {
print("Received file data ---:");
print(event['data']);
parseEKGFileDetailObject(event['data']);
}
}); });
await BleChannel.getScanningResult(["oximeter", "ekg"]); await BleChannel.getScanningResult(["oximeter", "ekg"]);
}, },
@ -85,38 +95,12 @@ class _EKG_BLEState extends State<EKG_BLE> {
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: ekgValueNotifier, valueListenable: ekgValueNotifier,
builder: (context, value, _) { builder: (context, value, _) {
return Text(value); return Column(
// ? Platform.isAndroid crossAxisAlignment: CrossAxisAlignment.start,
// ? Column( children: [Text(value), mHeight(24.0), getFilesListWidget()],
// children: [ );
// Text(
// getSPO2(
// value.toString().replaceAll("RtParam", ""),
// ),
// ),
// Text(
// getPR(
// value.toString().replaceAll("RtParam", ""),
// ),
// ),
// // Text(
// // getPI(
// // value.toString().replaceAll("RtParam", ""),
// // ),
// // ),
// ],
// )
// : Column(
// children: [
// Text(getSPO2iOS(value.toString())),
// Text(getPRiOS(value.toString())),
// ],
// )
// : Text(value);
}, },
), ),
mHeight(24.0),
getFilesListWidget()
], ],
), ),
), ),
@ -125,13 +109,36 @@ class _EKG_BLEState extends State<EKG_BLE> {
} }
void parseEKGFilesList(List<dynamic> filesListArray) { void parseEKGFilesList(List<dynamic> filesListArray) {
List<dynamic> filesList = filesListArray.toString().replaceAll("[", "").replaceAll("]", "").split(","); ekgFilesList.clear();
print("received files list: $filesListArray"); ekgFilesList = filesListArray.toString().replaceAll("[", "").replaceAll("]", "").split(",");
ekgValueNotifier.value = filesListArray.toString().replaceAll("[", "").replaceAll("]", ""); ekgFilesList.removeWhere((element) => element.contains("a")); // removing analysis files from the list
ekgValueNotifier.value = ekgFilesList.toString();
} }
Widget getFilesListWidget() { Widget getFilesListWidget() {
return Container(); return ListView.separated(
shrinkWrap: true,
physics: ScrollPhysics(),
reverse: true,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
getEKGFileDetails(ekgFilesList[index]);
},
child: Text(ekgFilesList[index]));
},
itemCount: ekgFilesList.length,
separatorBuilder: (context, index) => SizedBox(height: 14),
);
} }
void getEKGFileDetails(String fileName) async {
print("received file name: $fileName");
await BleChannel.getEKGFileDetails(fileName);
}
void parseEKGFileDetailObject(dynamic returnData) {
EKGFileDetailResponseModel ekgFileDetailResponseModel = EKGFileDetailResponseModel.fromJson(json.decode(returnData));
Navigator.push(context, FadePage(page: EKGChartView(ekgFileDetailResponseModel: ekgFileDetailResponseModel)));
}
} }

@ -17,18 +17,6 @@ class BleChannel {
} }
} }
// static Future<String> getScanningResultEKG(List<String> deviceType) async {
// try {
// print("----------Flutter Init -------");
// final String result = await platform.invokeMethod('scan_ekg', deviceType);
// print("----------Flutter Result -------");
// print(result);
// return result;
// } catch (e) {
// return "Error: $e";
// }
// }
static Future<String> getEKGFilesList(List<String> deviceType) async { static Future<String> getEKGFilesList(List<String> deviceType) async {
try { try {
print("----------Flutter Init -------"); print("----------Flutter Init -------");
@ -41,6 +29,18 @@ class BleChannel {
} }
} }
static Future<String> getEKGFileDetails(String fileName) async {
try {
print("----------Flutter Init -------");
final String result = await platform.invokeMethod('ekg_file_detail', fileName);
print("----------Flutter Result -------");
print(result);
return result;
} catch (e) {
return "Error: $e";
}
}
static Future<String> disconnect() async { static Future<String> disconnect() async {
try { try {
print("----------Flutter Init -------"); print("----------Flutter Init -------");

Loading…
Cancel
Save