StartMain.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. using Google.Protobuf.WellKnownTypes;
  2. using ivf_tl_Com;
  3. using IvfTl.Control.Entity.DTO;
  4. using IvfTl.Control.Entity.DTO.ApiRequestDTO;
  5. using IvfTl.Control.Entity.DTO.ControllerResults;
  6. using IvfTl.Control.Entity.GlobalEntitys;
  7. using IvfTl.Control.Entity.GlobalEnums;
  8. using IvfTl.Control.Entity.InitEntitys;
  9. using ivf_tl_UtilHelper;
  10. using Newtonsoft.Json;
  11. using System.Diagnostics;
  12. using System.Runtime.InteropServices;
  13. using System.Text;
  14. using System.Windows;
  15. namespace ivf_tl_Control
  16. {
  17. public class StartMain
  18. {
  19. AppData AppData { get; set; }
  20. public int CamNum { get; set; } = 0;
  21. public StartMain()
  22. {
  23. //HouseBin houseBin = new HouseBin();
  24. //houseBin.ComBin._channel.ErrorLogEvent += AppData.logControl.TLLog;
  25. //houseBin.ComBin._channel.ExceptionLogEvent += AppData.logControl.ExceptionLog;
  26. //houseBin.ComBin._channel.CommandLogEvent += AppData.logControl.HouseLog;
  27. }
  28. public string StartRun()
  29. {
  30. try
  31. {
  32. string errorInfo = "";
  33. AppData = AppData.Instance;
  34. AppData.LogService.TLLog($"程序开始启动", LogEnum.RunRecord);
  35. var initTLResult = InitTL(ref errorInfo);
  36. if (!string.IsNullOrEmpty(errorInfo)) return errorInfo;
  37. if (errorInfo == "结束") return errorInfo;
  38. AppData.TLSetting = initTLResult.Item1.TLSetting;
  39. PathHelper.pan = initTLResult.Item1.TLSetting.tmpDir;
  40. AppData.LogService.Pan = initTLResult.Item1.TLSetting.tmpDir;
  41. if (!InitHouse(initTLResult.Item1, initTLResult.Item2, ref errorInfo)) return errorInfo;
  42. // 舱室故障隔离:好舱继续后,把完整启动坏舱清单(扫口期 + InitHouse 构造期)经现有 reportAlarm
  43. // 报警闭环上报一次(alarm 表/双端列表/短信电话/可消警);失败不影响启动。
  44. try { AppData.ReportStartupFaults(); } catch { }
  45. AppData.StartAsync().Wait();
  46. return null;
  47. }
  48. catch (Exception ex)
  49. {
  50. AppData.LogService.ExceptionLog(ex, "仪器初始化", null, LogEnum.RunException);
  51. return ex.Message;
  52. }
  53. }
  54. /// <summary>
  55. /// TL数据初始化
  56. /// </summary>
  57. /// <returns></returns>
  58. public (TLInitControllerResult, List<int>) InitTL(ref string errora)
  59. {
  60. try
  61. {
  62. SerialBin serialBin = new SerialBin();
  63. serialBin.TLLogEvent += AppData.LogService.TLLog;
  64. serialBin.ExceptionLogEvent += AppData.LogService.ExceptionLog;
  65. serialBin.HouseLogEvent += AppData.LogService.HouseLog;
  66. var errorList = serialBin.UpdataCamera();
  67. AppData.LogService.TLLog($"相机信息:{JsonConvert.SerializeObject(serialBin.CCDidSn)}", LogEnum.RunRecord);
  68. if (errorList.Any())
  69. {
  70. // 舱室故障隔离:相机枚举异常不再整机中止,只记日志;受影响舱稍后在 CCDSN 配对时落坏舱被剔除。
  71. AppData.LogService.TLLog($"相机枚举有异常(不中止,受影响舱将按坏舱剔除):{JsonConvert.SerializeObject(errorList)}", LogEnum.RunRecord);
  72. }
  73. CamNum = serialBin.CCDidSn.Where(x => x.Value != null).Count();
  74. errorList = serialBin.Start();
  75. AppData.LogService.TLLog($"仓室信息:{JsonConvert.SerializeObject(serialBin.SerialModels)}", LogEnum.RunRecord);
  76. AppData.LogService.TLLog($"E方数据:{JsonConvert.SerializeObject(serialBin.HouseEEPROInfos)}", LogEnum.RunRecord);
  77. if (errorList.Any())
  78. {
  79. // 舱室故障隔离:扫口异常不再整机中止,剔除坏舱后用好舱继续(见下方 RunnableHouses)。
  80. AppData.LogService.TLLog($"扫口有异常(将剔除坏舱后继续):{JsonConvert.SerializeObject(errorList)}", LogEnum.RunRecord);
  81. }
  82. var modelCount = serialBin.SerialModels.Count;
  83. if (modelCount != 11)
  84. {
  85. // M1-01 步骤2:合并后是单进程无人值守前台,不能弹模态框。
  86. // 原 hack(MessageBox + Task.Delay(3000) + FindWindow/EnumChildWindows/SendMessage(BM_CLICK) 自动点 Yes)
  87. // 改为静默 + 日志记录;是否继续由配置项 ContinueOnModuleCountMismatch 控制(默认继续)。
  88. // 相关 [DllImport] 声明(FindWindow/SendMessage/EnumChildWindows/GetClassName/GetWindowText)按代码隔离原则保留为死代码,仅停止调用。
  89. bool continueOnMismatch = true;
  90. try
  91. {
  92. string cfg = System.Configuration.ConfigurationManager.AppSettings["ContinueOnModuleCountMismatch"];
  93. if (!string.IsNullOrEmpty(cfg) && bool.TryParse(cfg, out bool parsed)) continueOnMismatch = parsed;
  94. }
  95. catch { /* 读取配置失败时按默认(继续)处理 */ }
  96. AppData.LogService.TLLog($"检测到 {modelCount} 个模块(期望 11),ContinueOnModuleCountMismatch={continueOnMismatch},按配置策略{(continueOnMismatch ? "继续运行" : "中止初始化")}", LogEnum.RunRecord);
  97. if (!continueOnMismatch)
  98. {
  99. errora = "结束";
  100. return (new TLInitControllerResult(), new List<int>());
  101. }
  102. }
  103. // 舱室故障隔离:坏舱 = 故障清单中已知舱号;可跑舱 = 发现的舱 − 坏舱;仅零可跑才整机中止。
  104. var discovered = serialBin.SerialModels.Select(x => x.houseSn).ToList();
  105. List<int> listIntRunHoues = StartupFaultPolicy.RunnableHouses(discovered, serialBin.Faults);
  106. foreach (var f in serialBin.Faults) if (f.HouseSn > 0) f.Isolated = true;
  107. AppData.StartupFaults = serialBin.Faults;
  108. if (serialBin.Faults.Any())
  109. AppData.LogService.TLLog($"启动坏舱清单:{JsonConvert.SerializeObject(serialBin.Faults)};可跑舱:{string.Join(",", listIntRunHoues)}", LogEnum.RunRecord);
  110. if (StartupFaultPolicy.IsFatal(listIntRunHoues))
  111. {
  112. errora = "所有舱室初始化失败,无可运行舱室";
  113. AppData.LogService.TLLog(errora, LogEnum.RunRecord);
  114. return (new TLInitControllerResult(), new List<int>());
  115. }
  116. TLInitData tLInitData = new TLInitData();
  117. tLInitData.tlSn = $"NEO-1-{serialBin.TLNum}";
  118. tLInitData.dayLighting = serialBin.dayLighting;
  119. tLInitData.softwareVersion = "V2.0.0";
  120. tLInitData.verticalMotorPulseMax = 125000;
  121. tLInitData.houseLinkDataList = serialBin.SerialModels.OrderBy(x => x.houseSn).ToList();
  122. foreach (var item in serialBin.HouseEEPROInfos)
  123. {
  124. item.tlSn = tLInitData.tlSn;
  125. }
  126. tLInitData.houseEEPROInitDTOList = serialBin.HouseEEPROInfos.OrderBy(x => x.houseSn).ToList();
  127. AppData.LogService.TLLog($"【CamNum:{CamNum}】设备基础数据:{JsonConvert.SerializeObject(tLInitData)}", LogEnum.RunRecord);
  128. TLInitControllerResult tLInitControllerResult = AppData.SerialBinController.UpdateTLInfoController(tLInitData);
  129. if (tLInitControllerResult == null)
  130. {
  131. errora = "获取TL设置失败";
  132. AppData.LogService.TLLog(errora, LogEnum.RunRecord);
  133. return (new TLInitControllerResult(), new List<int>());
  134. }
  135. //AppData.LogService.TLLog($"TL初始化结果:{JsonConvert.SerializeObject(tLInitControllerResult)};{string.Join("_", listIntRunHoues)}", LogEnum.RunRecord);
  136. return (tLInitControllerResult, listIntRunHoues);
  137. }
  138. catch (Exception ex)
  139. {
  140. errora = ex.Message;
  141. AppData.LogService.ExceptionLog(ex, "数据初始化", null, LogEnum.RunException);
  142. return (new TLInitControllerResult(), new List<int>());
  143. }
  144. }
  145. /// <summary>
  146. /// 仓室初始化
  147. /// </summary>
  148. /// <param name="tLInitControllerResult"></param>
  149. /// <param name="runHouses"></param>
  150. /// <param name="errorInfo"></param>
  151. /// <returns></returns>
  152. private bool InitHouse(TLInitControllerResult tLInitControllerResult, List<int> runHouses, ref string errorInfo)
  153. {
  154. try
  155. {
  156. TLSetting tLSetting = tLInitControllerResult.TLSetting;
  157. AppData.TLSetting = tLSetting;
  158. var allList = AppData.SerialBinController.GetDishAndBalanceDataController(tLSetting.tlSn);
  159. // 舱室故障隔离:单舱构造/启动各自兜底——抛异常只登记坏舱 + 跳过该舱,绝不拖垮其余舱(spec §35)。
  160. void Build(int sn, Action build)
  161. {
  162. try { build(); }
  163. catch (Exception ex)
  164. {
  165. AppData.LogService.ExceptionLog(ex, $"舱{sn}构造失败(已隔离,其余舱继续)", null, LogEnum.RunException);
  166. AppData.StartupFaults?.Add(new HouseFault
  167. {
  168. HouseSn = sn,
  169. Type = HouseFaultType.InitException,
  170. Reason = $"舱{sn}构造异常:{ex.Message}",
  171. Stage = "舱初始化",
  172. At = DateTime.UtcNow,
  173. Isolated = true
  174. });
  175. }
  176. }
  177. void Start(int sn, Action start)
  178. {
  179. try { start(); }
  180. catch (Exception ex)
  181. {
  182. AppData.LogService.ExceptionLog(ex, $"舱{sn} StartTask 失败(已隔离)", null, LogEnum.RunException);
  183. }
  184. }
  185. Build(11, () =>
  186. {
  187. AppData.BufferBottleBin = new BufferBottleBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 11), AppData.Instance.guanbiTime);
  188. AppData.InitBufferBottleBinEvent(AppData.BufferBottleBin);
  189. });
  190. Build(1, () => { AppData.HouseBin1 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 1), allList.Dishes.FirstOrDefault(x => x.houseSn == 1), allList.BalanceList.FirstOrDefault(x => x.houseSn == 1), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 1).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin1); });
  191. Build(2, () => { AppData.HouseBin2 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 2), allList.Dishes.FirstOrDefault(x => x.houseSn == 2), allList.BalanceList.FirstOrDefault(x => x.houseSn == 2), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 2).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin2); });
  192. Build(3, () => { AppData.HouseBin3 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 3), allList.Dishes.FirstOrDefault(x => x.houseSn == 3), allList.BalanceList.FirstOrDefault(x => x.houseSn == 3), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 3).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin3); });
  193. Build(4, () => { AppData.HouseBin4 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 4), allList.Dishes.FirstOrDefault(x => x.houseSn == 4), allList.BalanceList.FirstOrDefault(x => x.houseSn == 4), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 4).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin4); });
  194. Build(5, () => { AppData.HouseBin5 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 5), allList.Dishes.FirstOrDefault(x => x.houseSn == 5), allList.BalanceList.FirstOrDefault(x => x.houseSn == 5), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 5).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin5); });
  195. Build(6, () => { AppData.HouseBin6 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 6), allList.Dishes.FirstOrDefault(x => x.houseSn == 6), allList.BalanceList.FirstOrDefault(x => x.houseSn == 6), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 6).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin6); });
  196. Build(7, () => { AppData.HouseBin7 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 7), allList.Dishes.FirstOrDefault(x => x.houseSn == 7), allList.BalanceList.FirstOrDefault(x => x.houseSn == 7), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 7).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin7); });
  197. Build(8, () => { AppData.HouseBin8 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 8), allList.Dishes.FirstOrDefault(x => x.houseSn == 8), allList.BalanceList.FirstOrDefault(x => x.houseSn == 8), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 8).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin8); });
  198. Build(9, () => { AppData.HouseBin9 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 9), allList.Dishes.FirstOrDefault(x => x.houseSn == 9), allList.BalanceList.FirstOrDefault(x => x.houseSn == 9), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 9).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin9); });
  199. Build(10, () => { AppData.HouseBin10 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == 10), allList.Dishes.FirstOrDefault(x => x.houseSn == 10), allList.BalanceList.FirstOrDefault(x => x.houseSn == 10), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == 10).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin10); });
  200. if (AppData.HouseBin1 != null) AppData.HouseBin1.CamNum = CamNum;
  201. if (AppData.HouseBin2 != null) AppData.HouseBin2.CamNum = CamNum;
  202. if (AppData.HouseBin3 != null) AppData.HouseBin3.CamNum = CamNum;
  203. if (AppData.HouseBin4 != null) AppData.HouseBin4.CamNum = CamNum;
  204. if (AppData.HouseBin5 != null) AppData.HouseBin5.CamNum = CamNum;
  205. if (AppData.HouseBin6 != null) AppData.HouseBin6.CamNum = CamNum;
  206. if (AppData.HouseBin7 != null) AppData.HouseBin7.CamNum = CamNum;
  207. if (AppData.HouseBin8 != null) AppData.HouseBin8.CamNum = CamNum;
  208. if (AppData.HouseBin9 != null) AppData.HouseBin9.CamNum = CamNum;
  209. if (AppData.HouseBin10 != null) AppData.HouseBin10.CamNum = CamNum;
  210. if (!AppData.MvcTest)
  211. {
  212. if (runHouses.Contains(1) && AppData.HouseBin1 != null) Start(1, () => AppData.HouseBin1.StartTask());
  213. if (runHouses.Contains(2) && AppData.HouseBin2 != null) Start(2, () => AppData.HouseBin2.StartTask());
  214. if (runHouses.Contains(3) && AppData.HouseBin3 != null) Start(3, () => AppData.HouseBin3.StartTask());
  215. if (runHouses.Contains(4) && AppData.HouseBin4 != null) Start(4, () => AppData.HouseBin4.StartTask());
  216. if (runHouses.Contains(6) && AppData.HouseBin6 != null) Start(6, () => AppData.HouseBin6.StartTask());
  217. if (runHouses.Contains(7) && AppData.HouseBin7 != null) Start(7, () => AppData.HouseBin7.StartTask());
  218. if (runHouses.Contains(8) && AppData.HouseBin8 != null) Start(8, () => AppData.HouseBin8.StartTask());
  219. if (runHouses.Contains(9) && AppData.HouseBin9 != null) Start(9, () => AppData.HouseBin9.StartTask());
  220. if (runHouses.Contains(10) && AppData.HouseBin10 != null) Start(10, () => AppData.HouseBin10.StartTask());
  221. }
  222. if (runHouses.Contains(5) && AppData.HouseBin5 != null) Start(5, () => AppData.HouseBin5.StartTask());
  223. if (runHouses.Contains(11) && AppData.BufferBottleBin != null) Start(11, () => AppData.BufferBottleBin.StartTask());
  224. return true;
  225. }
  226. catch (Exception ex)
  227. {
  228. AppData.LogService.ExceptionLog(ex, "仓室初始化", null, LogEnum.RunException);
  229. errorInfo = ex.Message;
  230. return false;
  231. }
  232. }
  233. public void testc()
  234. {
  235. AppData = AppData.Instance;
  236. string body1 = AppData.ReadText(@"C:\Users\jxb\Desktop\work\10 时差\8 开发文档\6 服务器架构\link接口请求参数.txt");
  237. string body2 = AppData.ReadText(@"C:\Users\jxb\Desktop\work\10 时差\8 开发文档\6 服务器架构\init接口请求参数.txt");
  238. //AppData.SerialBinController.TLInitController(body1, body2);
  239. }
  240. public void testGetAutoFocusController()
  241. {
  242. AppData = AppData.Instance;
  243. PositionRequestDTO autoFocusDTO = new PositionRequestDTO
  244. {
  245. tlSn = "NEO-1-20230101",
  246. houseSn = 1,
  247. };
  248. AppData.HouseBinController.GetAutoFocusController(autoFocusDTO);
  249. }
  250. public void TestGetCCDPositionController()
  251. {
  252. AppData = AppData.Instance;
  253. PositionRequestDTO autoFocusDTO = new PositionRequestDTO
  254. {
  255. tlSn = "NEO-1-20230101",
  256. houseSn = 1,
  257. };
  258. AppData.HouseBinController.GetCCDPositionController(autoFocusDTO);
  259. }
  260. public void TestGetDishAndBalanceDataController()
  261. {
  262. AppData = AppData.Instance;
  263. //AppData.HouseBinController.GetDishAndBalanceDataController("NEO-1-20230101");
  264. }
  265. [DllImport("user32.dll", SetLastError = true)]
  266. static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  267. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  268. static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
  269. delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
  270. [DllImport("user32.dll")]
  271. static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
  272. [DllImport("user32.dll")]
  273. static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
  274. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  275. static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
  276. const uint WM_CLOSE = 0x0010;
  277. const uint BM_CLICK = 0x00F5;
  278. }
  279. }