BufferDebugViewModel.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using CommunityToolkit.Mvvm.ComponentModel;
  2. using ivf_tl_Entity.ComEntitys;
  3. using ivf_tl_Entity.DebugEntitys;
  4. using ivf_tl_Entity.DTO;
  5. using ivf_tl_Entity.GlobalEnums;
  6. using IvfTl.Hardware;
  7. using IvfTl.Hardware.Impl;
  8. using Newtonsoft.Json;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Configuration;
  13. using System.DirectoryServices.ActiveDirectory;
  14. using System.Linq;
  15. using System.Security.Principal;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows;
  19. namespace ivf_tl_Operate.ViewModel
  20. {
  21. public partial class BufferDebugViewModel : ObservableObject
  22. {
  23. public event Action<string> MessageEvent;
  24. // M1-B2:缓冲瓶调试页不再 new ComBin 开第二个物理串口——走借用到的 HAL 句柄(同采集端实例)。
  25. /// <summary>M1-B2 HAL 前台借用凭证(缓冲瓶舱 houseSn=11)。</summary>
  26. private IvfTl.Hardware.IHardwareLease _halLease = null;
  27. /// <summary>借用到的串口句柄;未持借用时为 null。</summary>
  28. private IvfTl.Hardware.ISerialChannel Serial => _halLease?.Serial;
  29. /// <summary>
  30. /// 仪器设置
  31. /// </summary>
  32. public TLSetting tLSetting = new TLSetting();
  33. [ObservableProperty]
  34. private HouseInfo currentHouse = null;
  35. /// <summary>
  36. /// 仪器温度1
  37. /// </summary>
  38. [ObservableProperty]
  39. private decimal temperature1 = 0m;
  40. /// <summary>
  41. /// 仪器温度2
  42. /// </summary>
  43. [ObservableProperty]
  44. private decimal temperature2 = 0m;
  45. /// <summary>
  46. /// 压力
  47. /// </summary>
  48. [ObservableProperty]
  49. private decimal bufferBottlePressure = 0m;
  50. [ObservableProperty]
  51. private int ledLight = 0;
  52. [ObservableProperty]
  53. private ObservableCollection<string> messageInfoList = new ObservableCollection<string>();
  54. private void ExLog(Exception ex, string name)
  55. {
  56. AppData.Instance.LogHelper.ExceptionLog(ex, $"HouseDebugPageViewModel.{name}", LogEnum.RunException);
  57. }
  58. private void ErrorLog(string message, LogEnum logType)
  59. {
  60. AppData.Instance.LogHelper.TLLog($"HouseDebugPageViewModel.{message}", logType);
  61. }
  62. public void Start(ref string errora)
  63. {
  64. try
  65. {
  66. SerialBin serialBin = new SerialBin();
  67. serialBin.TLLogEvent += AppData.Instance.LogHelper.TLLog;
  68. serialBin.ExceptionLogEvent += AppData.Instance.LogHelper.ExceptionLog;
  69. serialBin.HouseLogEvent += AppData.Instance.LogHelper.HouseLog;
  70. var errorList = serialBin.UpdataCamera();
  71. AppData.Instance.LogHelper.TLLog($"ccdidsn:{JsonConvert.SerializeObject(serialBin.CCDidSn)}", LogEnum.RunRecord);
  72. if (errorList.Any())
  73. {
  74. errora = $"获取相机Id和CCDSN错误{JsonConvert.SerializeObject(errorList)}";
  75. AppData.Instance.LogHelper.TLLog(errora, LogEnum.RunRecord);
  76. return;
  77. }
  78. errorList = serialBin.Start(ConfigurationManager.AppSettings["autoFocus"].ToString());
  79. AppData.Instance.LogHelper.TLLog($"舱室信息:{JsonConvert.SerializeObject(serialBin.SerialModels)}", LogEnum.RunRecord);
  80. AppData.Instance.LogHelper.TLLog($"E方数据:{JsonConvert.SerializeObject(serialBin.HouseEEPROInfos)}", LogEnum.RunRecord);
  81. if (errorList.Any())
  82. {
  83. errora = $"获取串口信息错误{JsonConvert.SerializeObject(errorList)}";
  84. AppData.Instance.LogHelper.TLLog(errora, LogEnum.RunRecord);
  85. return;
  86. }
  87. var modelCount = serialBin.SerialModels.Count;
  88. if (modelCount != 11)
  89. {
  90. string messageinfo = $"检测到{modelCount}个模块,是否继续运行?";
  91. MessageBoxResult aaa = MessageBox.Show(messageinfo, "提示", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No, MessageBoxOptions.DefaultDesktopOnly);
  92. if (aaa != MessageBoxResult.Yes)
  93. {
  94. errora = "结束";
  95. return;
  96. }
  97. }
  98. List<int> listIntRunHoues = serialBin.SerialModels.Select(x => x.houseSn).ToList();
  99. TLInitData tLInitData = new TLInitData();
  100. tLInitData.tlSn = $"NEO-1-{serialBin.TLNum}";
  101. tLInitData.dayLighting = serialBin.dayLighting;
  102. tLInitData.softwareVersion = "V2.0.0";
  103. tLInitData.verticalMotorPulseMax = 125000;
  104. tLInitData.houseLinkDataList = serialBin.SerialModels.OrderBy(x => x.houseSn).ToList();
  105. foreach (var item in serialBin.HouseEEPROInfos)
  106. {
  107. item.tlSn = tLInitData.tlSn;
  108. }
  109. tLInitData.houseEEPROInitDTOList = serialBin.HouseEEPROInfos.OrderBy(x => x.houseSn).ToList();
  110. AppData.Instance.LogHelper.TLLog($"舱室信息:{JsonConvert.SerializeObject(tLInitData)}", LogEnum.RunRecord);
  111. SettingDataApiData settingDataApiData = AppData.Instance.HttpHelper.GetSettingDataApi(tLInitData);
  112. if (settingDataApiData == null)
  113. {
  114. errora = $"{tLInitData.tlSn}获取仪器设置失败";
  115. return;
  116. }
  117. AppData.Instance.LogHelper.TLLog(JsonConvert.SerializeObject(settingDataApiData), LogEnum.RunRecord);
  118. tLSetting = AppData.Instance.ConvertHelper.ConvertToTLSetting(settingDataApiData.tlInfo, settingDataApiData.tlSetting);
  119. CurrentHouse = settingDataApiData.houseList.FirstOrDefault(x => x.houseSn == 11);
  120. if (CurrentHouse == null)
  121. {
  122. errora = $"{tLInitData.tlSn}获取缓冲瓶信息失败";
  123. return;
  124. }
  125. }
  126. catch (Exception ex)
  127. {
  128. AppData.Instance.LogHelper.ExceptionLog(ex, $"缓冲瓶调试模式初始化", LogEnum.RunException);
  129. errora = $"缓冲瓶调试模式初始化异常:{ex.Message}";
  130. }
  131. }
  132. public async Task ComHouseInit()
  133. {
  134. await Task.Run(async () =>
  135. {
  136. try
  137. {
  138. // M1-B2:向 HAL 申请缓冲瓶舱(11)前台借用,复用采集端同一物理串口句柄,不再 new ComBin 开第二个口。
  139. try
  140. {
  141. var gate = HardwareAccessLayer.Instance.GetHouseGate(CurrentHouse.houseSn);
  142. _halLease = gate.Acquire(HardwareUser.OperateDebug);
  143. if (_halLease == null)
  144. {
  145. AddMessageInfo($"[{CurrentHouse.houseSn}]缓冲瓶舱正被占用,借用超时,稍后重试");
  146. return;
  147. }
  148. }
  149. catch (Exception le)
  150. {
  151. AddMessageInfo($"[{CurrentHouse.houseSn}]HAL 借用异常:{le.Message}");
  152. return;
  153. }
  154. if (Serial == null)
  155. {
  156. AddMessageInfo($"[{CurrentHouse.houseSn}]借用到的串口句柄为空(HAL 未扫描到缓冲瓶舱?)");
  157. return;
  158. }
  159. if (!Serial.IsOpen && !Serial.Open())
  160. {
  161. AddMessageInfo($"[{currentHouse.houseSn}][{currentHouse.housePort}]借用串口未打开且兜底打开失败");
  162. return;
  163. }
  164. AddMessageInfo($"[{currentHouse.houseSn}][{currentHouse.housePort}]缓冲瓶调试已复用采集端串口句柄");
  165. Serial.ShakeHandsWait();
  166. RedL();
  167. var a = Serial.BufferBottleStateWait();
  168. BufferBottlePressure = a.pressure;
  169. Temperature1 = a.t1;
  170. Temperature2 = a.t2;
  171. return;
  172. }
  173. catch (Exception ex)
  174. {
  175. AppData.Instance.LogHelper.ExceptionLog(ex, "缓冲瓶调试模式初始化", LogEnum.RunException);
  176. AddMessageInfo($"初始化异常:{ex.Message}");
  177. return;
  178. }
  179. });
  180. }
  181. public bool ComHouseUnit()
  182. {
  183. try
  184. {
  185. // M1-B2:物理口归采集端持有;调试只归还借用,不 ClosePort。
  186. if (_halLease != null)
  187. {
  188. try { _halLease.Dispose(); } catch { }
  189. _halLease = null;
  190. AddMessageInfo($"[{currentHouse.houseSn}]缓冲瓶已归还借用,恢复后台采集");
  191. }
  192. return true;
  193. }
  194. catch (Exception ex)
  195. {
  196. AppData.Instance.LogHelper.ExceptionLog(ex, "缓冲瓶卸载", LogEnum.RunException);
  197. AddMessageInfo($"缓冲瓶卸载异常:{ex.Message}");
  198. return false;
  199. }
  200. }
  201. public void BufferState()
  202. {
  203. if (Serial == null) return;
  204. var a = Serial.BufferBottleStateWait();
  205. BufferBottlePressure = a.pressure;
  206. Temperature1 = a.t1;
  207. Temperature2 = a.t2;
  208. }
  209. public void Are()
  210. {
  211. if (Serial == null) return;
  212. // M8-G3-1:缓冲瓶补气为串口设备命令入口,补操作日志埋点(module=缓冲瓶调试)。
  213. Aivfo.OperationLog.OperationLogger.Run("缓冲瓶调试", "缓冲瓶补气",
  214. () => Serial.BufferBottleAerationWait(),
  215. input: new { houseSn = CurrentHouse?.houseSn });
  216. }
  217. /// <summary>
  218. /// 进气阀打开时间
  219. /// </summary>
  220. /// <param name="newValue"></param>
  221. public void writeE(int newValue)
  222. {
  223. if (Serial == null) return;
  224. // M1-B2:走 lease.Serial→control ComBin 缓冲瓶进气阀时间写(builder 与 operate 逐字节一致)。⚠ 待真机 V-010。
  225. // M8-G3-1:写进气阀时间为"写 EEPROM 串口命令 + HTTP 持久化"打包操作,用 Begin scope 给父操作名串联子埋点(module=缓冲瓶调试)。
  226. using var _op = Aivfo.OperationLog.OperationLogger.Begin("缓冲瓶调试", "保存缓冲瓶进气阀时间",
  227. houseSn: CurrentHouse?.houseSn);
  228. try { _op.Input(new { houseSn = CurrentHouse?.houseSn, newValue }); } catch { }
  229. Serial.WriteOpenIntakeTimeWait(newValue, isBuffer: true);
  230. CurrentHouse.inletValveOpeningTime = newValue;
  231. AddMessageInfo($"进气阀打开时间保存服务器结果:{AppData.Instance.HttpHelper.LightsUpdateApi(tLSetting.tlSn, LedLight, CurrentHouse.inletValveOpeningTime)}");
  232. }
  233. /// <summary>
  234. /// 设置灯光亮度
  235. /// </summary>
  236. /// <param name="newValue"></param>
  237. public void writeL(int newValue)
  238. {
  239. if (Serial == null) return;
  240. // M-03 已补:control 端补齐写灯光亮度 E方命令(builder 地址 00 05 34,与合并前 operate 逐字节一致),
  241. // 经 lease.Serial→control ComBin 真正写灯光 EEPROM;同时仍记录服务器。
  242. // M8-G3-1:设置灯光亮度为"写 EEPROM 串口命令 + HTTP 持久化"打包操作,用 Begin scope 给父操作名串联子埋点(module=缓冲瓶调试)。
  243. using var _op = Aivfo.OperationLog.OperationLogger.Begin("缓冲瓶调试", "保存缓冲瓶灯光亮度",
  244. houseSn: CurrentHouse?.houseSn);
  245. try { _op.Input(new { houseSn = CurrentHouse?.houseSn, newValue }); } catch { }
  246. if (!Serial.WriteLightBrightnessWait(newValue))
  247. {
  248. AddMessageInfo($"[灯光亮度]下发失败,仅本地暂存{newValue}");
  249. }
  250. LedLight = newValue;
  251. AddMessageInfo($"灯光亮度保存服务器结果:{AppData.Instance.HttpHelper.LightsUpdateApi(tLSetting.tlSn, LedLight, CurrentHouse.inletValveOpeningTime)}");
  252. }
  253. public void RedL()
  254. {
  255. if (Serial == null) return;
  256. LedLight = Serial.ReadLightBrightnessWait();
  257. }
  258. private void ComBin_ExceptionLogEvent(Exception exception, string arg2, string arg3, LogEnum @enum)
  259. {
  260. AppData.Instance.LogHelper.ExceptionLog(exception, $"{arg2}{arg3}", @enum);
  261. }
  262. private void ComBin_ErrorLogEvent(string arg1, LogEnum @enum)
  263. {
  264. AppData.Instance.LogHelper.TLLog(arg1, @enum);
  265. }
  266. private void ComBin_CommandLogEvent(int arg1, DateTime time, string arg3, LogEnum @enum)
  267. {
  268. AppData.Instance.LogHelper.HouseLog(arg1, time, arg3, @enum);
  269. }
  270. public void AddMessageInfo(string mess)
  271. {
  272. MessageEvent?.Invoke(mess);
  273. }
  274. }
  275. }