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 android.util.SparseArray
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.ble.utils.EcgData
import com.google.gson.Gson
//Ble
@ -28,10 +30,14 @@ import com.lepu.blepro.event.EventMsgConst.Ble.*
import com.lepu.blepro.event.InterfaceEvent
import com.lepu.blepro.ext.BleServiceHelper
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.objs.Bluetooth
import com.lepu.blepro.objs.BluetoothController
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 no.nordicsemi.android.ble.observer.ConnectionObserver
@ -49,6 +55,7 @@ class BleBridge(
private const val SCAN_DEVICE = "scan"
private const val SCAN_DEVICE_EKG = "scan_ekg"
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"
}
@ -144,6 +151,9 @@ class BleBridge(
// scanDeviceEKG(methodCall, result)
} else if (methodCall.method == EKG_FILES_LIST) {
getEKGFilesList()
} else if (methodCall.method == EKG_FILE_DETAIL) {
val fileName = methodCall.arguments;
getEKGFileDetail(fileName.toString())
} else {
result.notImplemented()
}
@ -211,6 +221,7 @@ class BleBridge(
}
if (deviceName.contains("DuoEK", ignoreCase = true)) {
val gson = Gson()
LiveEventBus.get<InterfaceEvent>(InterfaceEvent.ER2.EventEr2Info)
.observe(this.mainActivity) {
val data = it.data as DeviceInfo
@ -233,9 +244,23 @@ class BleBridge(
println("EventEr2SetTime")
// Get Device Info
BleServiceHelper.BleServiceHelper.er2GetInfo(model)
//Get EKG File List
// BleServiceHelper.BleServiceHelper.er2GetFileList(model)
}
LiveEventBus.get<InterfaceEvent>(InterfaceEvent.ER2.EventEr2ReadFileComplete)
.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
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/viatom_ble/ble_connect.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.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/services.dart';
@ -37,7 +42,7 @@ class _EKG_BLEState extends State<EKG_BLE> {
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: "EKG Tracker",
appBarTitle: "ECG Tracker",
showNewAppBar: true,
isShowDecPage: false,
showNewAppBarTitle: true,
@ -63,6 +68,11 @@ class _EKG_BLEState extends State<EKG_BLE> {
if (event['type'] == "fileList") {
parseEKGFilesList(event['data']);
}
if (event['type'] == 'fileDetail') {
print("Received file data ---:");
print(event['data']);
parseEKGFileDetailObject(event['data']);
}
});
await BleChannel.getScanningResult(["oximeter", "ekg"]);
},
@ -85,38 +95,12 @@ class _EKG_BLEState extends State<EKG_BLE> {
ValueListenableBuilder(
valueListenable: ekgValueNotifier,
builder: (context, value, _) {
return Text(value);
// ? Platform.isAndroid
// ? Column(
// 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);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(value), mHeight(24.0), getFilesListWidget()],
);
},
),
mHeight(24.0),
getFilesListWidget()
],
),
),
@ -125,13 +109,36 @@ class _EKG_BLEState extends State<EKG_BLE> {
}
void parseEKGFilesList(List<dynamic> filesListArray) {
List<dynamic> filesList = filesListArray.toString().replaceAll("[", "").replaceAll("]", "").split(",");
print("received files list: $filesListArray");
ekgValueNotifier.value = filesListArray.toString().replaceAll("[", "").replaceAll("]", "");
ekgFilesList.clear();
ekgFilesList = filesListArray.toString().replaceAll("[", "").replaceAll("]", "").split(",");
ekgFilesList.removeWhere((element) => element.contains("a")); // removing analysis files from the list
ekgValueNotifier.value = ekgFilesList.toString();
}
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 {
try {
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 {
try {
print("----------Flutter Init -------");

Loading…
Cancel
Save