body_temperature.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/managers/device_controller_manager.dart';
  4. import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
  5. import 'package:vnote_device_plugin/consts/types.dart';
  6. import 'package:vnote_device_plugin/devices/temp.dart';
  7. import 'package:vitalapp/components/dialog_number.dart';
  8. import 'package:vitalapp/managers/interfaces/models/device.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:fis_common/logger/logger.dart';
  14. class BodyTemperature extends StatefulWidget {
  15. const BodyTemperature({
  16. super.key,
  17. });
  18. @override
  19. State<BodyTemperature> createState() => _ExamBodyTemperatureState();
  20. }
  21. class _ExamBodyTemperatureState extends State<BodyTemperature> {
  22. var controller = Get.find<MedicalController>();
  23. DeviceControllerManager? temp;
  24. TempDeviceWorker? worker;
  25. WorkerStatus connectStatus = WorkerStatus.connecting;
  26. bool isConnectFail = false;
  27. int errorCount = 0;
  28. ///重试机制
  29. late String _value =
  30. controller.diagnosisDataValue['Temp']?['Temperature'] ?? '';
  31. @override
  32. void initState() {
  33. WidgetsBinding.instance.addPostFrameCallback(
  34. (timeStamp) {
  35. initTemperature();
  36. currentDevice();
  37. },
  38. );
  39. super.initState();
  40. }
  41. Future<void> currentDevice() async {
  42. DeviceModel? device = await controller.getDevice(DeviceTypes.TEMP);
  43. if (device == null) {
  44. connectStatus = WorkerStatus.unboundDevice;
  45. worker = null;
  46. return;
  47. }
  48. temp = DeviceControllerManager(DeviceTypes.TEMP, device.model, device.mac);
  49. worker = temp!.worker as TempDeviceWorker;
  50. connectStatus = temp!.connectStatus;
  51. loadListeners();
  52. connect();
  53. }
  54. Future<void> initTemperature() async {
  55. _value = controller.diagnosisDataValue['Temp']?['Temperature'] ?? '';
  56. logger.i('_ExamBloodSugarState initData Temperature:$_value');
  57. setState(() {});
  58. }
  59. void loadListeners() {
  60. worker!.successEvent.addListener(_onSuccess);
  61. worker!.connectErrorEvent.addListener(_onConnectFail);
  62. worker!.connectedEvent.addListener(_onConnectSuccess);
  63. worker!.disconnectedEvent.addListener(_onDisconnected);
  64. worker!.tempTooLowEvent.addListener(_onTempTooLowOrTooHeigh);
  65. worker!.tempTooHighEvent.addListener(_onTempTooLowOrTooHeigh);
  66. }
  67. Future<void> disconnect() async {
  68. if (worker != null) {
  69. await worker!.disconnect();
  70. }
  71. }
  72. Future<void> connect() async {
  73. if (worker != null) {
  74. await worker!.connect();
  75. }
  76. }
  77. void releaseListeners() {
  78. if (worker != null) {
  79. worker!.connectErrorEvent.removeListener(_onConnectFail);
  80. worker!.connectedEvent.removeListener(_onConnectSuccess);
  81. worker!.successEvent.removeListener(_onSuccess);
  82. worker!.disconnectedEvent.removeListener(_onDisconnected);
  83. worker!.tempTooLowEvent.removeListener(_onTempTooLowOrTooHeigh);
  84. worker!.tempTooHighEvent.removeListener(_onTempTooLowOrTooHeigh);
  85. }
  86. // controller.deviceCloseSuccessEvent.removeListener(_onDeviceCloseSuccess);
  87. }
  88. /// 尝试重连
  89. Future<void> tryReconnect() async {
  90. if (worker != null) {
  91. await disconnect();
  92. await connect();
  93. }
  94. }
  95. @override
  96. void dispose() {
  97. if (worker != null) {
  98. temp?.dispose();
  99. temp = null;
  100. }
  101. releaseListeners();
  102. disconnect();
  103. worker?.dispose();
  104. super.dispose();
  105. }
  106. void _onSuccess(_, double e) {
  107. setState(() {
  108. _value = e.toString();
  109. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  110. controller.saveCachedRecord();
  111. connectStatus = WorkerStatus.connected;
  112. });
  113. }
  114. void _onTempTooLowOrTooHeigh(sender, e) {
  115. _value = e.toString();
  116. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  117. controller.saveCachedRecord();
  118. connectStatus = WorkerStatus.connected;
  119. setState(() {});
  120. }
  121. void _onConnectFail(sender, e) {
  122. print('连接设备失败');
  123. logger.i("连接设备失败:${worker!.mac}");
  124. if (errorCount < 3) {
  125. errorCount++;
  126. tryReconnect();
  127. } else {
  128. isConnectFail = true;
  129. }
  130. connectStatus = WorkerStatus.connectionFailed;
  131. setState(() {});
  132. }
  133. void _onConnectSuccess(sender, e) {
  134. logger.i("设备连接成功:${worker!.mac}");
  135. connectStatus = WorkerStatus.connected;
  136. errorCount = 0;
  137. isConnectFail = false;
  138. setState(() {});
  139. }
  140. void _onDisconnected(sender, e) {
  141. print('设备连接中断');
  142. logger.i("设备连接中断:${worker!.mac}");
  143. errorCount = 0;
  144. tryReconnect();
  145. connectStatus = WorkerStatus.disconnected;
  146. setState(() {});
  147. }
  148. @override
  149. Widget build(BuildContext context) {
  150. return Stack(
  151. children: [
  152. _buildTemperature(),
  153. if (!isConnectFail)
  154. DeviceStatusPosition(
  155. deviceStatus: DeviceStatus(connectStatus: connectStatus),
  156. )
  157. else
  158. _buildErrorButton(),
  159. ],
  160. );
  161. }
  162. Widget _buildErrorButton() {
  163. return DeviceStatusPosition(
  164. deviceStatus: Row(
  165. children: [
  166. const Text(
  167. '请确认设备是否启动',
  168. style: TextStyle(fontSize: 24, color: Colors.red),
  169. ),
  170. IconButton(
  171. onPressed: () {
  172. tryReconnect();
  173. setState(() {
  174. connectStatus = WorkerStatus.connecting;
  175. isConnectFail = false;
  176. });
  177. },
  178. icon: const Icon(Icons.refresh),
  179. iconSize: 32,
  180. ),
  181. ],
  182. ),
  183. );
  184. }
  185. Widget _buildTemperature() {
  186. return ExamCard(
  187. title: '',
  188. clickCard: () {
  189. _inputTemperature();
  190. },
  191. content: Row(
  192. children: [
  193. const SizedBox(
  194. width: 25,
  195. ),
  196. const Text(
  197. '体温',
  198. style: TextStyle(fontSize: 25),
  199. ),
  200. const Expanded(child: SizedBox()),
  201. Container(
  202. alignment: Alignment.bottomRight,
  203. height: 100,
  204. child: FittedBox(
  205. child: Row(
  206. mainAxisAlignment: MainAxisAlignment.end,
  207. crossAxisAlignment: CrossAxisAlignment.center,
  208. children: [
  209. Text(
  210. _value.isEmpty ? '--' : _value,
  211. style: const TextStyle(
  212. fontSize: 60,
  213. color: Colors.black,
  214. ),
  215. ),
  216. const Text(
  217. ' °C',
  218. style: TextStyle(fontSize: 25),
  219. ),
  220. const SizedBox(
  221. width: 30,
  222. )
  223. ],
  224. ),
  225. ),
  226. ),
  227. ],
  228. ),
  229. );
  230. }
  231. Future<void> _inputTemperature() async {
  232. String? result = await VDialogNumber(
  233. title: '体温',
  234. initialValue: _value,
  235. ).show();
  236. if (result?.isNotEmpty ?? false) {
  237. _value = result ?? '';
  238. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  239. controller.saveCachedRecord();
  240. }
  241. setState(() {});
  242. }
  243. }