bool_oxygen.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/components/dialog_number.dart';
  4. import 'package:vitalapp/managers/device_controller_manager.dart';
  5. import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
  6. import 'package:vnote_device_plugin/consts/types.dart';
  7. import 'package:vnote_device_plugin/devices/sp_o2.dart';
  8. import 'package:vnote_device_plugin/models/exams/sp_o2.dart';
  9. import 'package:vitalapp/pages/medical/widgets/exam_card.dart';
  10. import 'package:vitalapp/pages/medical/controller.dart';
  11. import 'package:vitalapp/pages/medical/models/worker.dart';
  12. import 'package:vitalapp/pages/medical/widgets/device_status.dart';
  13. import 'package:vitalapp/pages/medical/widgets/side_bar.dart';
  14. import 'package:fis_common/logger/logger.dart';
  15. class BloodOxygen extends StatefulWidget {
  16. const BloodOxygen({Key? key}) : super(key: key);
  17. @override
  18. State<BloodOxygen> createState() => _ExamBloodOxygenState();
  19. }
  20. class _ExamBloodOxygenState extends State<BloodOxygen> {
  21. final controller = Get.find<MedicalController>();
  22. DeviceControllerManager? spo2;
  23. SpO2DeviceWorker? worker;
  24. String pulse = '';
  25. String spO2 = '';
  26. bool isConnectFail = false;
  27. int errorCount = 0;
  28. WorkerStatus _connectStatus = WorkerStatus.connecting;
  29. @override
  30. void initState() {
  31. super.initState();
  32. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  33. initOxygen();
  34. });
  35. }
  36. @override
  37. void dispose() {
  38. spo2?.dispose();
  39. spo2 = null;
  40. releaseListeners();
  41. disconnect();
  42. worker?.dispose();
  43. super.dispose();
  44. }
  45. Future<void> initOxygen() async {
  46. await currentDevice();
  47. await initData();
  48. }
  49. Future<void> currentDevice() async {
  50. final device = await controller.getDevice(DeviceTypes.SPO2);
  51. if (device == null) {
  52. _connectStatus = WorkerStatus.unboundDevice;
  53. setState(() {});
  54. worker = null;
  55. return;
  56. }
  57. spo2 = DeviceControllerManager(DeviceTypes.SPO2, device.model, device.mac);
  58. worker = spo2!.worker as SpO2DeviceWorker;
  59. _connectStatus = spo2!.connectStatus;
  60. loadListeners();
  61. connect();
  62. }
  63. Future<void> initData() async {
  64. setState(() {
  65. pulse = controller.diagnosisDataValue['SpO2']?['Pulse_Frequency'] ?? '';
  66. spO2 = controller.diagnosisDataValue['SpO2']?['Spo2'] ?? '';
  67. logger.i('_ExamBloodSugarState initData pulse:$pulse spO2:$spo2');
  68. });
  69. }
  70. void loadListeners() {
  71. worker!.valueUpdateEvent.addListener(_onSuccess);
  72. worker!.connectErrorEvent.addListener(_onConnectFail);
  73. worker!.connectedEvent.addListener(_onConnectSuccess);
  74. worker!.disconnectedEvent.addListener(_onDisconnected);
  75. }
  76. void releaseListeners() {
  77. worker!.connectErrorEvent.removeListener(_onConnectFail);
  78. worker!.connectedEvent.removeListener(_onConnectSuccess);
  79. worker!.valueUpdateEvent.removeListener(_onSuccess);
  80. worker!.disconnectedEvent.removeListener(_onDisconnected);
  81. }
  82. Future<void> disconnect() async {
  83. if (worker != null) {
  84. await worker!.disconnect();
  85. }
  86. }
  87. Future<void> connect() async {
  88. if (worker != null) {
  89. await worker!.connect();
  90. }
  91. }
  92. /// 尝试重连
  93. Future<void> tryReconnect() async {
  94. if (worker != null) {
  95. await disconnect();
  96. await connect();
  97. }
  98. }
  99. void _onSuccess(_, SpO2ExamValue e) {
  100. setState(() {
  101. pulse = e.pulse.toString();
  102. spO2 = e.spO2.toString();
  103. controller.diagnosisDataValue['SpO2'] = {
  104. 'Pulse_Frequency': pulse,
  105. 'Spo2': spO2
  106. };
  107. controller.saveCachedRecord();
  108. _connectStatus = WorkerStatus.connected;
  109. });
  110. }
  111. void _onConnectFail(sender, e) {
  112. logger.i("连接设备失败:${worker!.mac}");
  113. if (errorCount < 3) {
  114. errorCount++;
  115. tryReconnect();
  116. } else {
  117. isConnectFail = true;
  118. }
  119. _connectStatus = WorkerStatus.connectionFailed;
  120. setState(() {});
  121. }
  122. void _onConnectSuccess(sender, e) {
  123. logger.i("设备连接成功:${worker!.mac}");
  124. _connectStatus = WorkerStatus.connected;
  125. errorCount = 0;
  126. isConnectFail = false;
  127. setState(() {});
  128. }
  129. void _onDisconnected(sender, e) {
  130. print('设备连接中断');
  131. logger.i("设备连接中断:${worker!.mac}");
  132. tryReconnect();
  133. errorCount = 0;
  134. _connectStatus = WorkerStatus.disconnected;
  135. setState(() {});
  136. }
  137. Future<void> _inputOxygen(String title) async {
  138. final result = await VDialogNumber(
  139. title: title,
  140. initialValue: spO2,
  141. ).show();
  142. if (result?.isNotEmpty ?? false) {
  143. spO2 = result ?? '';
  144. controller.diagnosisDataValue['SpO2'] = {
  145. 'Pulse_Frequency': pulse,
  146. 'Spo2': spO2
  147. };
  148. controller.saveCachedRecord();
  149. }
  150. setState(() {});
  151. }
  152. Future<void> _inputOxygen1(String title) async {
  153. final result = await VDialogNumber(
  154. title: title,
  155. initialValue: pulse,
  156. ).show();
  157. if (result?.isNotEmpty ?? false) {
  158. pulse = result ?? '';
  159. }
  160. controller.diagnosisDataValue['SpO2'] = {
  161. 'Pulse_Frequency': pulse,
  162. 'Spo2': spO2
  163. };
  164. controller.saveCachedRecord();
  165. setState(() {});
  166. }
  167. /// 需要封装一下
  168. Widget _buildErrorButton() {
  169. return DeviceStatusPosition(
  170. deviceStatus: Row(
  171. children: [
  172. const Text(
  173. '请确认设备是否启动',
  174. style: TextStyle(fontSize: 24, color: Colors.red),
  175. ),
  176. IconButton(
  177. onPressed: () {
  178. tryReconnect();
  179. setState(() {
  180. _connectStatus = WorkerStatus.connecting;
  181. isConnectFail = false;
  182. });
  183. },
  184. icon: const Icon(Icons.refresh),
  185. iconSize: 32,
  186. ),
  187. ],
  188. ),
  189. );
  190. }
  191. @override
  192. Widget build(BuildContext context) {
  193. return Stack(
  194. children: [
  195. ExamCard(
  196. content: Column(
  197. mainAxisAlignment: MainAxisAlignment.start,
  198. children: [
  199. SideBar(
  200. title: '血氧饱和度',
  201. value: spO2 == '0' ? '--' : spO2,
  202. unit: '%',
  203. onTap: () async {
  204. await _inputOxygen('血氧饱和度');
  205. },
  206. ),
  207. const Divider(indent: 30),
  208. SideBar(
  209. title: '脉率',
  210. value: pulse == '0' ? '--' : pulse,
  211. unit: 'bpm',
  212. onTap: () async {
  213. await _inputOxygen1('脉率');
  214. },
  215. ),
  216. ],
  217. ),
  218. ),
  219. if (!isConnectFail)
  220. DeviceStatusPosition(
  221. deviceStatus: DeviceStatus(connectStatus: _connectStatus),
  222. )
  223. else
  224. _buildErrorButton(),
  225. ],
  226. );
  227. }
  228. }