|
@@ -4,7 +4,6 @@ import 'dart:convert';
|
|
|
import 'package:fis_common/logger/logger.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:get/get.dart';
|
|
|
-import 'package:vitalapp/managers/device_controller_manager.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/data_convert.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/models/device.dart';
|
|
|
import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_card.dart';
|
|
@@ -53,250 +52,6 @@ class _HeartRateState extends State<HeartRate> {
|
|
|
List<int>? initEcgData;
|
|
|
|
|
|
String _deviceError = '';
|
|
|
- @override
|
|
|
- void initState() {
|
|
|
- WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
|
- initHeart();
|
|
|
- });
|
|
|
- super.initState();
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> connect() async {
|
|
|
- await worker.connect();
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> disconnect() async {
|
|
|
- if (!(worker == null)) {
|
|
|
- await worker.disconnect();
|
|
|
- releaseListeners();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void releaseListeners() {
|
|
|
- worker.connectErrorEvent.removeListener(_onConnectFail);
|
|
|
- worker.connectedEvent.removeListener(_onConnectSuccess);
|
|
|
- // worker.successEvent.removeListener(_onSuccess);
|
|
|
- worker.disconnectedEvent.removeListener(_onDisconnected);
|
|
|
- worker.hrValueUpdateEvent.removeListener(_onHrValueUpdate);
|
|
|
- worker.ecgValueUpdateEvent.removeListener(_onEcgValueUpdate);
|
|
|
- worker.resultReceivedEvent.removeListener(_onRCesultReceived);
|
|
|
- worker.errorEvent.removeListener(_onError);
|
|
|
- }
|
|
|
-
|
|
|
- @override
|
|
|
- void dispose() {
|
|
|
- disconnect();
|
|
|
- super.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- void loadListeners() {
|
|
|
- // worker.successEvent.addListener(_onSuccess);
|
|
|
- worker.connectErrorEvent.addListener(_onConnectFail);
|
|
|
- worker.connectedEvent.addListener(_onConnectSuccess);
|
|
|
- worker.disconnectedEvent.addListener(_onDisconnected);
|
|
|
- worker.hrValueUpdateEvent.addListener(_onHrValueUpdate);
|
|
|
- worker.ecgValueUpdateEvent.addListener(_onEcgValueUpdate);
|
|
|
- worker.resultReceivedEvent.addListener(_onRCesultReceived);
|
|
|
- worker.errorEvent.addListener(_onError);
|
|
|
- worker.connect();
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> currentDevice() async {
|
|
|
- DeviceModel? device = await controller.getDevice(DeviceTypes.HEART);
|
|
|
- if (device == null) {
|
|
|
- _connectStatus = WorkerStatus.unboundDevice;
|
|
|
- setState(() {});
|
|
|
- return;
|
|
|
- }
|
|
|
- heart = HeartDeviceController(device.model, device.mac);
|
|
|
- worker = heart.worker;
|
|
|
- _connectStatus = heart.connectStatus;
|
|
|
-
|
|
|
- loadListeners();
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> initHeart() async {
|
|
|
- currentDevice();
|
|
|
-
|
|
|
- await initData();
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> initData() async {
|
|
|
- // await Future.delayed(const Duration(milliseconds: 800));
|
|
|
- await controller.readCachedRecord();
|
|
|
- if (controller.diagnosisDataValue['Heart'] == null) {
|
|
|
- controller.diagnosisDataValue['Heart'] = {};
|
|
|
- }
|
|
|
-
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- void _onHrValueUpdate(_, int e) {
|
|
|
- logger.i('心率更新:$e');
|
|
|
-
|
|
|
- if (_deviceError.isNotEmpty || _assess.isNotEmpty) {
|
|
|
- _deviceError = '';
|
|
|
- _assess = '';
|
|
|
- ecgReset();
|
|
|
- print('object');
|
|
|
- }
|
|
|
- setState(() {
|
|
|
- _heart = e.toString();
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- void _onError(_, String e) {
|
|
|
- logger.i('心率更新失败:$e');
|
|
|
- _deviceError = e;
|
|
|
- ecgReset();
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- void ecgReset() {
|
|
|
- try {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
- ecgPoint = [];
|
|
|
- ecgViewController.reset();
|
|
|
- } catch (e) {
|
|
|
- logger.i('心率图测量失败:$e');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> setEcgData() async {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
- controller.diagnosisDataValue['Heart']?['ECG'] =
|
|
|
- await ecgViewController.getFullDataImageBase64();
|
|
|
- controller.diagnosisDataValue['Heart']?['ECG_POINT'] =
|
|
|
- jsonEncode(ecgViewController.allPoints);
|
|
|
- }
|
|
|
-
|
|
|
- void _onRCesultReceived(_, HeartExamResult e) async {
|
|
|
- logger.i('心率更新接收结果:${e.heartRate}');
|
|
|
- print(ecgPoint.toString());
|
|
|
- // _heart = e.toString();
|
|
|
- _assess = e.analysis.first;
|
|
|
- _heart = e.heartRate.toString();
|
|
|
- controller.diagnosisDataValue['Heart']?['HEART'] = e.heartRate.toString();
|
|
|
- controller.diagnosisDataValue['Heart']?['ASSESS'] =
|
|
|
- dataConvertManager.heartRateConversion(int.parse(heartRate));
|
|
|
-
|
|
|
- await setEcgData();
|
|
|
- controller.saveCachedRecord();
|
|
|
- print(controller.diagnosisDataValue);
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- void _onEcgValueUpdate(_, List<int> e) {
|
|
|
- try {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
- ecgPoint.addAll(e);
|
|
|
- if (ecgPoint.length > 125 * 3) {
|
|
|
- ecgViewController.addData(e);
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- print(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void _onConnectFail(sender, e) {
|
|
|
- logger.i("设备连接失败:${worker.mac}");
|
|
|
- if (errorCount < 3) {
|
|
|
- errorCount++;
|
|
|
- disconnect();
|
|
|
- loadListeners();
|
|
|
- } else {
|
|
|
- isConnectFail = true;
|
|
|
- }
|
|
|
- _connectStatus = WorkerStatus.connectionFailed;
|
|
|
-
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- void _onDisconnected(sender, e) {
|
|
|
- print('设备连接中断');
|
|
|
- logger.i("设备连接中断:${worker.mac}");
|
|
|
- if (errorCount < 3) {
|
|
|
- errorCount++;
|
|
|
- disconnect();
|
|
|
- loadListeners();
|
|
|
- } else {
|
|
|
- isConnectFail = true;
|
|
|
- }
|
|
|
- _connectStatus = WorkerStatus.disconnected;
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- void _onConnectSuccess(sender, e) {
|
|
|
- logger.e('_HeartRateState ${worker.mac}, 设备连接成功');
|
|
|
- isConnectFail = false;
|
|
|
- errorCount = 0;
|
|
|
- _connectStatus = WorkerStatus.connected;
|
|
|
- setState(() {});
|
|
|
- }
|
|
|
-
|
|
|
- Future<String> createEcgImageBase64(List<int> points) async {
|
|
|
- final int width = points.length ~/ 2;
|
|
|
- const int height = 240;
|
|
|
- final ui.PictureRecorder recorder = ui.PictureRecorder();
|
|
|
- final Canvas canvas = Canvas(recorder);
|
|
|
- final Path path = Path();
|
|
|
- final Paint paint = Paint();
|
|
|
- const double strokeWidth = 1.5;
|
|
|
-
|
|
|
- paint.color = Colors.green;
|
|
|
- paint.style = PaintingStyle.stroke;
|
|
|
- paint.isAntiAlias = true;
|
|
|
- paint.strokeWidth = strokeWidth;
|
|
|
-
|
|
|
- path.reset();
|
|
|
- int pointCount = points.length;
|
|
|
- if (pointCount > 0) {
|
|
|
- path.moveTo(0, points[0].toDouble());
|
|
|
- int i = 0;
|
|
|
- int j = pointCount ~/ 2;
|
|
|
- while (i < j) {
|
|
|
- path.lineTo(i.toDouble(), points[i].toDouble());
|
|
|
- path.lineTo((i + 1).toDouble(), points[i + 1].toDouble());
|
|
|
- i += 2;
|
|
|
- }
|
|
|
- canvas.drawPath(path, paint);
|
|
|
- }
|
|
|
-
|
|
|
- final ui.Picture picture = recorder.endRecording();
|
|
|
- final ui.Image image = await picture.toImage(width, height);
|
|
|
- final ByteData? byteData =
|
|
|
- await image.toByteData(format: ui.ImageByteFormat.png);
|
|
|
- final Uint8List pngBytes = byteData!.buffer.asUint8List();
|
|
|
-
|
|
|
- final String base64Image = base64Encode(pngBytes);
|
|
|
- return base64Image;
|
|
|
- }
|
|
|
-
|
|
|
- /// 需要封装一下
|
|
|
- Widget _buildErrorButton() {
|
|
|
- return DeviceStatusPosition(
|
|
|
- deviceStatus: Row(
|
|
|
- children: [
|
|
|
- const Text(
|
|
|
- '请确认设备是否启动',
|
|
|
- style: TextStyle(fontSize: 24, color: Colors.red),
|
|
|
- ),
|
|
|
- IconButton(
|
|
|
- onPressed: () {
|
|
|
- worker.connect();
|
|
|
- setState(() {
|
|
|
- _connectStatus = WorkerStatus.connecting;
|
|
|
- isConnectFail = false;
|
|
|
- });
|
|
|
- },
|
|
|
- icon: const Icon(Icons.refresh),
|
|
|
- iconSize: 32,
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Stack(
|