bool_oxygen.dart 6.8 KB

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