AppData.cs 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  1. using DBEntity;
  2. using Google.Protobuf;
  3. using ivf_tl_Com;
  4. using ivf_tl_Controller;
  5. using IvfTl.Control.Entity.DBEntitys;
  6. using IvfTl.Control.Entity.DTO;
  7. using IvfTl.Control.Entity.DTO.ApiRequestDTO;
  8. using IvfTl.Control.Entity.DTO.ApiResultDTO;
  9. using IvfTl.Control.Entity.GlobalEntitys;
  10. using IvfTl.Control.Entity.GlobalEnums;
  11. using IvfTl.Control.Services;
  12. using IvfTl.Control.Services.HttpServices;
  13. using ivf_tl_ServicesImpl.DBServices;
  14. using ivf_tl_ServicesImpl.HttpServices;
  15. using ivf_tl_ServicesImpl.KafkaServices;
  16. using ivf_tl_ServicesImpl.LogServices;
  17. using ivf_tl_ServicesImpl.MqttServices;
  18. using ivf_tl_UtilHelper;
  19. using IvfTl.AutoFocus.Storage;
  20. using NetTaste;
  21. using Newtonsoft.Json;
  22. using Newtonsoft.Json.Linq;
  23. using Npgsql.TypeHandlers.GeometricHandlers;
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Configuration;
  27. using System.Diagnostics;
  28. using System.IO;
  29. using System.Text.Json.Nodes;
  30. using System.Windows;
  31. using System.Windows.Markup;
  32. namespace ivf_tl_Control
  33. {
  34. public class AppData
  35. {
  36. public static AppData Instance = new Lazy<AppData>(() => new AppData(), LazyThreadSafetyMode.ExecutionAndPublication).Value;
  37. public int guanbiTime = 0, csTime = 120, houseVentNum = 10, houseVentPre = 20, houseVentWaitTimeB = 1500, houseVentWaitTimeD = 5000, houseAutoWaitTime = 10, houseCCDAutoWaitTime = 5, houseCCDError = 0, houseCCDFailedNumber = 3, houseCCDFailedWaitTime = 15, queuAir = 0;
  38. public event Action StopProEvent;
  39. public bool MvcTest { get; set; } = false;
  40. public string TakePhotoString = string.Empty;
  41. private AppData()
  42. {
  43. _urlIp = $"{ConfigurationManager.AppSettings["urlIp"]}:{ConfigurationManager.AppSettings["urlPort"]}/";
  44. kfkaIP = $"{ConfigurationManager.AppSettings["kfkaIP"]}:{ConfigurationManager.AppSettings["kfkaPort"]}";
  45. MqttIp = ConfigurationManager.AppSettings["mqttIp"].ToString();
  46. MqttPort = int.Parse(ConfigurationManager.AppSettings["mqttPort"]);
  47. if (int.TryParse(ConfigurationManager.AppSettings["gbTime"].ToString(), out int newTime1)) guanbiTime = newTime1;
  48. if (int.TryParse(ConfigurationManager.AppSettings["csTime"].ToString(), out int newTime2)) csTime = newTime2;
  49. if (int.TryParse(ConfigurationManager.AppSettings["VentNum"].ToString(), out int newTime3)) houseVentNum = newTime3;
  50. if (int.TryParse(ConfigurationManager.AppSettings["VentPre"].ToString(), out int newTime4)) houseVentPre = newTime4;
  51. if (int.TryParse(ConfigurationManager.AppSettings["VentWaitTimeB"].ToString(), out int newTime5)) houseVentWaitTimeB = newTime5;
  52. if (int.TryParse(ConfigurationManager.AppSettings["VentWaitTimeD"].ToString(), out int newTime6)) houseVentWaitTimeD = newTime6;
  53. if (int.TryParse(ConfigurationManager.AppSettings["AutoWaitTime"].ToString(), out int newTime7)) houseAutoWaitTime = newTime7;
  54. if (int.TryParse(ConfigurationManager.AppSettings["CCDAutoWaitTime"].ToString(), out int newTime8)) houseCCDAutoWaitTime = newTime8;
  55. if (int.TryParse(ConfigurationManager.AppSettings["CCDError"].ToString(), out int newTime9)) houseCCDError = newTime9;
  56. if (int.TryParse(ConfigurationManager.AppSettings["CCDFailedNumber"].ToString(), out int newTime10)) houseCCDFailedNumber = newTime10;
  57. if (int.TryParse(ConfigurationManager.AppSettings["CCDFailedWaitTime"].ToString(), out int newTime11)) houseCCDFailedWaitTime = newTime11;
  58. if (int.TryParse(ConfigurationManager.AppSettings["QueuAir"].ToString(), out int newTime12)) queuAir = newTime12;
  59. TakePhotoString = GetLanguageStringByKey("D0010");
  60. //_urlIp = "http://gateway.aivfo.com:36000/";
  61. //MqttIp = "211.149.139.131";
  62. //MqttPort = 61883;
  63. //_urlIp = "http://test-gateway.aivfo.com:36000/";
  64. //MqttIp = "211.149.139.131";
  65. //MqttPort = 62883;
  66. ImageDTODic = new Dictionary<string, ImageDTO>();
  67. sqlitePath = $"{Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"DependFile\DB\aivfoTL.db")}";
  68. LogService = new LogServiceImpl() { Pan = "C" };
  69. HttpService = new HttpService(_urlIp);
  70. HttpService.ErrorLogEvent += LogService.TLLog;
  71. HttpService.ExceptionLogEvent += LogService.ExceptionLog;
  72. DBService = new DBService();
  73. DBService.ErrorLogEvent += LogService.TLLog;
  74. DBService.ExceptionLogEvent += LogService.ExceptionLog;
  75. DBService.StartDbService(sqlitePath);
  76. // M2-04 标定结果存储:calibration.json 真相源 + 镜像 house_autofocus_calibration。
  77. // JSON 路径走部署工作目录(DependFile\AutoFocus),不写死 autofocustool 测试外壳常量路径。
  78. // DbMirror 绑定到 DBService.SaveAutofocusCalibration(scene 0 upsert / 1 append);
  79. // 任一步骤异常 CalibrationStore 内部已吞掉并经 Log 记录,不崩对焦/采集线程。
  80. string calibJsonPath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"DependFile\AutoFocus\calibration.json");
  81. AutofocusStore = new CalibrationStore
  82. {
  83. JsonPath = calibJsonPath,
  84. Source = "LOCAL_JSON",
  85. Log = msg => LogService.TLLog(msg, LogEnum.RunError),
  86. DbMirror = (tlSn, houseSn, wellSn, scene, focusZ, exposure, horizontalPulse, peakRatio, circleFound, centerOffsetPct, note, source) =>
  87. DBService.SaveAutofocusCalibration(tlSn, houseSn, wellSn, scene, focusZ, exposure, horizontalPulse, peakRatio, circleFound, centerOffsetPct, note, source),
  88. // M2-06 安全门降级:关闭本地对焦时按 scene=0 基准位置拍照,由此回调读基准 FocusZ。
  89. BaselineReader = (tlSn, houseSn, wellSn) => DBService.GetBaselineFocusZ(tlSn, houseSn, wellSn),
  90. };
  91. KafkaService = new KafkaService(kafkaTopic, kfkaIP);
  92. KafkaService.ErrorLogEvent += LogService.TLLog;
  93. KafkaService.ExceptionLogEvent += LogService.ExceptionLog;
  94. MqttService = new MqttService(MqttIp, MqttPort, MqttUserName, MqttPassword);
  95. MqttService.ErrorLogEvent += LogService.TLLog;
  96. MqttService.ExceptionLogEvent += LogService.ExceptionLog;
  97. MqttService.MessEvent += MqttMessage;
  98. MqttService.MqttAlarm += MqttAlarm;
  99. SerialBinController = new SerialBinController(HttpService, DBService);
  100. SerialBinController.LogEvent += LogService.TLLog;
  101. SerialBinController.ExceptionLogEvent += LogService.ExceptionLog;
  102. HouseBinController = new HouseBinController(HttpService, DBService);
  103. HouseBinController.LogEvent += LogService.TLLog;
  104. HouseBinController.ExceptionLogEvent += LogService.ExceptionLog;
  105. }
  106. public void TestEvent()
  107. {
  108. //string messageinfo = $"{GetLanguageStringByKey("D0007")}1{GetLanguageStringByKey("D0008")}";
  109. //MessageBox.Show(messageinfo);
  110. //string ss = GetLanguageStringByKey("D0001");
  111. //return;
  112. StopProEvent?.Invoke();
  113. }
  114. public string _urlIp = "http://192.168.31.89:10010/";
  115. //public string _urlIp = "http://gateway.aivfo.com:36000/";
  116. private string kafkaTopic = "jiangxuebingPicTestTopic";
  117. private string kfkaIP = "192.168.31.89:9092";
  118. private string MqttIp = "211.149.139.131";
  119. private int MqttPort = 1883;
  120. private string MqttUserName = "aivfo";
  121. private string MqttPassword = "aivfo";
  122. private string MqttClientId = "TL/DATA/tlSn";
  123. private string MqttTopicName = "TL/DATA/tlSn";
  124. private string sqlitePath = "";
  125. private bool isSetZiDong = false;
  126. public Dictionary<string, ImageDTO> ImageDTODic { get; set; }
  127. // ── M5-04-3:图片补传补强 ──
  128. // (a) 去重防重传:StartUpLoadImage 每 5s 重扫落盘目录,单文件一次上传可能跨多个 5s 周期(慢链/超时),
  129. // 用 in-flight 集合标记「正在上传」,重扫时跳过,避免同名文件被两轮并发重传(现 ImageDTODic lock 只护缓存)。
  130. private readonly HashSet<string> _uploadingFiles = new HashSet<string>();
  131. // (b) 断网累积兜底告警阈值:落盘待传数超过此值视为断网堆积,置位告警(只读暴露给监控/提示),不静默堆积。
  132. // [D10] 具体阈值留 M7 校准;此处为占位默认值。
  133. public int PendingImageAlarmThreshold { get; set; } = 500;
  134. // 断网累积告警状态(只读):true=待传堆积超阈值。供 GetMonitorSnapshot/断线提示呈现,不触发删图。
  135. public bool ImageBacklogAlarm { get; private set; }
  136. public int LastPendingImageCount { get; private set; }
  137. public SerialBinController SerialBinController { get; set; }
  138. public HouseBinController HouseBinController { get; set; }
  139. public ILogService LogService { get; set; }
  140. public HttpService HttpService { get; set; }
  141. public DBService DBService { get; set; }
  142. /// <summary>M2-04 标定结果存储入口(calibration.json 真相源 + house_autofocus_calibration 镜像)。</summary>
  143. public CalibrationStore AutofocusStore { get; set; }
  144. public KafkaService KafkaService { get; set; }
  145. public MqttService MqttService { get; set; }
  146. public UserInfo CurrentUser { get; set; }
  147. public TLSetting TLSetting;
  148. public HouseBin HouseBin1;
  149. public HouseBin HouseBin2;
  150. public HouseBin HouseBin3;
  151. public HouseBin HouseBin4;
  152. public HouseBin HouseBin5;
  153. public HouseBin HouseBin6;
  154. public HouseBin HouseBin7;
  155. public HouseBin HouseBin8;
  156. public HouseBin HouseBin9;
  157. public HouseBin HouseBin10;
  158. public BufferBottleBin BufferBottleBin;
  159. // ── M5-03-2:各链路「最后成功通讯时间」只读时间戳 ──
  160. // 仅在已有的成功分支里赋值(不改上报逻辑/不改报文),供 GetMonitorSnapshot 只读呈现「不假装实时」。
  161. // LastHttpOkAt 由 operate 侧 HTTP 轮询(M5-04-4)写入,control 这里只持有/透传。
  162. public DateTime? LastMqttOkAt { get; private set; }
  163. public DateTime? LastKafkaOkAt { get; private set; }
  164. public DateTime? LastHttpOkAt { get; set; }
  165. /// <summary>
  166. /// M5-03-1:聚合 control 内存/事件的当前状态为只读快照(需求 7/10)。
  167. /// 纯读取 + 拷贝到值类型 DTO,不修改任何 control 状态、不暴露可写引用,监控页据此只读呈现。
  168. /// 任一字段取值异常被吞掉(监控页不应因取数失败而崩),缺失项以默认值呈现。
  169. /// </summary>
  170. public MonitorSnapshot GetMonitorSnapshot()
  171. {
  172. var snap = new MonitorSnapshot { SnapshotAt = DateTime.Now, ControlHosted = true };
  173. try
  174. {
  175. // MQTT 连接态(来源 MqttService.MqttIsConnected())
  176. try { snap.MqttConnected = MqttService != null && MqttService.MqttIsConnected(); } catch { snap.MqttConnected = false; }
  177. snap.LastMqttOkAt = LastMqttOkAt;
  178. try { snap.MqttLastConnectedAt = MqttService?.LastConnectedAt; } catch { }
  179. try { snap.MqttLastDisconnectedAt = MqttService?.LastDisconnectedAt; } catch { }
  180. snap.LastKafkaOkAt = LastKafkaOkAt;
  181. snap.LastHttpOkAt = LastHttpOkAt;
  182. // 服务器接口基址(脱敏展示,仅地址不含凭据)
  183. snap.ServerUrl = _urlIp;
  184. // 上传队列:内存缓存数 + 落盘目录待传数
  185. try { lock (ImageDTODic) snap.ImageCacheCount = ImageDTODic == null ? 0 : ImageDTODic.Count; } catch { }
  186. try { snap.PendingDiskImageCount = CountPendingDiskImages(); } catch { }
  187. snap.ImageBacklogAlarm = ImageBacklogAlarm;
  188. snap.PendingImageAlarmThreshold = PendingImageAlarmThreshold;
  189. // 磁盘(来源 GetDiskInfo(缓存盘))
  190. try
  191. {
  192. string pan = TLSetting != null && !string.IsNullOrEmpty(TLSetting.tmpDir) ? TLSetting.tmpDir : PathHelper.pan;
  193. if (!string.IsNullOrEmpty(pan))
  194. {
  195. var disk = GetDiskInfo(pan);
  196. snap.DiskPath = disk.diskPath;
  197. snap.DiskExist = disk.diskExist == 0;
  198. snap.DiskFreeGb = disk.diskSpace;
  199. }
  200. }
  201. catch { }
  202. // 各舱室只读态
  203. var bins = new HouseBin[] { HouseBin1, HouseBin2, HouseBin3, HouseBin4, HouseBin5, HouseBin6, HouseBin7, HouseBin8, HouseBin9, HouseBin10 };
  204. int sn = 0;
  205. foreach (var bin in bins)
  206. {
  207. sn++;
  208. if (bin == null) continue;
  209. try
  210. {
  211. snap.Houses.Add(new HouseMonitorRow
  212. {
  213. HouseSn = sn,
  214. PortName = bin.PortName,
  215. RunState = bin.RunState,
  216. Temperature = bin.Temperature,
  217. Pressure = bin.Pressure,
  218. HouseState = bin.IsDoorOpen.ToString(),
  219. ComState = bin.ComBin != null ? "已连接" : "未连接",
  220. CcdState = bin.CCDError ? "异常" : "正常",
  221. CcdError = bin.CCDError,
  222. });
  223. }
  224. catch { }
  225. }
  226. }
  227. catch (Exception ex)
  228. {
  229. ExLog(ex, "GetMonitorSnapshot");
  230. }
  231. return snap;
  232. }
  233. /// <summary>落盘目录(自动对焦 + CCD)待传 *.jpg 计数(只读,不删不改)。</summary>
  234. private int CountPendingDiskImages()
  235. {
  236. int count = 0;
  237. try
  238. {
  239. string autoPath = PathHelper.GetAutoFocusSaveDirectory();
  240. if (Directory.Exists(autoPath)) count += Directory.GetFiles(autoPath, "*.jpg").Length;
  241. }
  242. catch { }
  243. try
  244. {
  245. string ccdPath = PathHelper.GetEmbryoPicSaveDirectory();
  246. if (Directory.Exists(ccdPath)) count += Directory.GetFiles(ccdPath, "*.jpg").Length;
  247. }
  248. catch { }
  249. return count;
  250. }
  251. private void ExLog(Exception ex, string name)
  252. {
  253. LogService.ExceptionLog(ex, $"AppData.{name}", null, LogEnum.RunException);
  254. }
  255. public bool Login(string _account, string _password)
  256. {
  257. try
  258. {
  259. CurrentUser = HttpService.Login(_account, _password);
  260. return CurrentUser != null;
  261. }
  262. catch (Exception ex)
  263. {
  264. ExLog(ex, "Login");
  265. return false;
  266. }
  267. }
  268. /// <summary>
  269. /// 开启kafka、mqtt、历史记录上报
  270. /// </summary>
  271. /// <returns></returns>
  272. public async Task StartAsync()
  273. {
  274. KafkaService.KafkaSetNameAndIp(TLSetting.kafkaTopic, kfkaIP);
  275. var kafkaSuccess = await KafkaService.CreateTopicAsync(3);
  276. if (kafkaSuccess)
  277. {
  278. if (!MvcTest) StartUpLoadImage();
  279. }
  280. else
  281. {
  282. LogService.TLLog($"kafka创建分区失败", LogEnum.RunError);
  283. }
  284. MqttClientId = $"TL/DATA/{TLSetting.tlSn}";
  285. MqttService.StartMqtt(TLSetting.mqttQueue, MqttClientId);
  286. StartSendMqttMsg();
  287. StartSendHistoryMsg();
  288. StartPushMessageThread();
  289. Task.Run(() => DeleteLog());
  290. }
  291. /// <summary>
  292. /// 重启kafka、mqtt
  293. /// </summary>
  294. private void UpdataKafkaAndMqtt()
  295. {
  296. if (KafkaService.KafkaSetNameAndIp(TLSetting.kafkaTopic, kfkaIP))
  297. {
  298. var kafkaSuccess = KafkaService.CreateTopicAsync(3).Result;
  299. if (!kafkaSuccess)
  300. {
  301. LogService.TLLog($"kafka创建分区失败", LogEnum.RunError);
  302. }
  303. }
  304. if (!MqttService.IsXiangTong(TLSetting.mqttQueue, $"TL/DATA/{TLSetting.tlSn}"))
  305. {
  306. MqttService.IsDispose = true;
  307. MqttService = new MqttService(MqttIp, MqttPort, MqttUserName, MqttPassword);
  308. MqttService.ErrorLogEvent += LogService.TLLog;
  309. MqttService.ExceptionLogEvent += LogService.ExceptionLog;
  310. MqttService.MessEvent += MqttMessage;
  311. MqttClientId = $"TL/DATA/{TLSetting.tlSn}";
  312. MqttService.StartMqtt(TLSetting.mqttQueue, MqttClientId);
  313. }
  314. }
  315. /// <summary>
  316. /// 开启图片上传线程
  317. /// </summary>
  318. public void StartUpLoadImage()
  319. {
  320. LogService.TLLog($"开始运行kafka线程", LogEnum.KafkaRecord);
  321. Task.Factory.StartNew(async () =>
  322. {
  323. while (true)
  324. {
  325. try
  326. {
  327. string autoPath = PathHelper.GetAutoFocusSaveDirectory();
  328. if (Directory.Exists(autoPath))
  329. {
  330. var autoFileList = Directory.GetFiles(autoPath, "*.jpg");
  331. foreach (var item in autoFileList)
  332. {
  333. await KafkaUploadImageAsync(item);
  334. }
  335. }
  336. string ccdPath = PathHelper.GetEmbryoPicSaveDirectory();
  337. if (Directory.Exists(ccdPath))
  338. {
  339. var ccdFileList = Directory.GetFiles(ccdPath, "*.jpg");
  340. foreach (var item in ccdFileList)
  341. {
  342. await KafkaUploadImageAsync(item);
  343. }
  344. }
  345. // M5-04-3(b):断网累积兜底——每轮重扫后统计落盘待传数,超阈值置位告警(只读,供监控/断线提示)。
  346. // 不删图、不丢图,只把「堆积」显性暴露,避免静默撑爆磁盘(配合 M5-03 磁盘水位)。
  347. try
  348. {
  349. int pending = CountPendingDiskImages();
  350. LastPendingImageCount = pending;
  351. bool backlog = pending > PendingImageAlarmThreshold;
  352. if (backlog && !ImageBacklogAlarm)
  353. LogService.TLLog($"图片待传堆积告警:落盘待传 {pending} 张已超阈值 {PendingImageAlarmThreshold},疑似上传链路断开", LogEnum.RunError);
  354. ImageBacklogAlarm = backlog;
  355. }
  356. catch { }
  357. await Task.Delay(1000 * 5);
  358. }
  359. catch (Exception ex)
  360. {
  361. LogService.ExceptionLog(ex, "上传图片", null, LogEnum.RunException);
  362. }
  363. }
  364. }, TaskCreationOptions.LongRunning);
  365. }
  366. /// <summary>
  367. /// 开启mqtt消息上报线程
  368. /// </summary>
  369. public void StartSendMqttMsg()
  370. {
  371. LogService.TLLog($"Mqtt开始上报", LogEnum.MqttClient);
  372. Task.Factory.StartNew(async () =>
  373. {
  374. while (true)
  375. {
  376. try
  377. {
  378. if (!MqttService.MqttIsConnected())
  379. {
  380. await Task.Delay(3000);
  381. continue;
  382. }
  383. List<HouseMqttData> houseMqttDataList = new List<HouseMqttData>();
  384. var a = GetHouseMqttData(HouseBin1);
  385. if (a != null) houseMqttDataList.Add(a);
  386. a = GetHouseMqttData(HouseBin2);
  387. if (a != null) houseMqttDataList.Add(a);
  388. a = GetHouseMqttData(HouseBin3);
  389. if (a != null) houseMqttDataList.Add(a);
  390. a = GetHouseMqttData(HouseBin4);
  391. if (a != null) houseMqttDataList.Add(a);
  392. a = GetHouseMqttData(HouseBin5);
  393. if (a != null) houseMqttDataList.Add(a);
  394. a = GetHouseMqttData(HouseBin6);
  395. if (a != null) houseMqttDataList.Add(a);
  396. a = GetHouseMqttData(HouseBin7);
  397. if (a != null) houseMqttDataList.Add(a);
  398. a = GetHouseMqttData(HouseBin8);
  399. if (a != null) houseMqttDataList.Add(a);
  400. a = GetHouseMqttData(HouseBin9);
  401. if (a != null) houseMqttDataList.Add(a);
  402. a = GetHouseMqttData(HouseBin10);
  403. if (a != null) houseMqttDataList.Add(a);
  404. a = GetHouseMqttData(BufferBottleBin);
  405. if (a != null) houseMqttDataList.Add(a);
  406. if (houseMqttDataList.Any() && MqttService.MqttIsConnected())
  407. {
  408. string mqttMsg = JsonConvert.SerializeObject(houseMqttDataList);
  409. await MqttService.PublishAsync(mqttMsg);
  410. LastMqttOkAt = DateTime.Now; // M5-03-2:MQTT 上报成功时间戳(只读监控用,不改上报逻辑)
  411. }
  412. await Task.Delay(1000);
  413. }
  414. catch (Exception ex)
  415. {
  416. LogService.ExceptionLog(ex, "实时数据上报", null, LogEnum.RunException);
  417. }
  418. }
  419. }, TaskCreationOptions.LongRunning);
  420. }
  421. /// <summary>
  422. /// 开启仓时历史记录上报线程
  423. /// </summary>
  424. public void StartSendHistoryMsg()
  425. {
  426. LogService.TLLog($"开启仓时历史记录上报线程", LogEnum.KafkaRecord);
  427. Task.Factory.StartNew(async () =>
  428. {
  429. await Task.Delay(1000 * 60);
  430. List<HouseHistoryData> houseMqttDataList = new List<HouseHistoryData>();
  431. HouseHistoryData a = null;
  432. while (true)
  433. {
  434. try
  435. {
  436. //只上报缓冲瓶的历史记录
  437. houseMqttDataList.Clear();
  438. a = GetHouseHistoryData(BufferBottleBin);
  439. if (a != null) houseMqttDataList.Add(a);
  440. if (houseMqttDataList.Any()) SerialBinController.ReportDataController(JsonConvert.SerializeObject(houseMqttDataList));
  441. //List<HouseHistoryData> houseMqttDataList = new List<HouseHistoryData>();
  442. //var a = GetHouseHistoryData(HouseBin1);
  443. //if (a != null) houseMqttDataList.Add(a);
  444. //a = GetHouseHistoryData(HouseBin2);
  445. //if (a != null) houseMqttDataList.Add(a);
  446. //a = GetHouseHistoryData(HouseBin3);
  447. //if (a != null) houseMqttDataList.Add(a);
  448. //a = GetHouseHistoryData(HouseBin4);
  449. //if (a != null) houseMqttDataList.Add(a);
  450. //a = GetHouseHistoryData(HouseBin5);
  451. //if (a != null) houseMqttDataList.Add(a);
  452. //a = GetHouseHistoryData(HouseBin6);
  453. //if (a != null) houseMqttDataList.Add(a);
  454. //a = GetHouseHistoryData(HouseBin7);
  455. //if (a != null) houseMqttDataList.Add(a);
  456. //a = GetHouseHistoryData(HouseBin8);
  457. //if (a != null) houseMqttDataList.Add(a);
  458. //a = GetHouseHistoryData(HouseBin9);
  459. //if (a != null) houseMqttDataList.Add(a);
  460. //a = GetHouseHistoryData(HouseBin10);
  461. //if (a != null) houseMqttDataList.Add(a);
  462. //a = GetHouseHistoryData(BufferBottleBin);
  463. //if (a != null) houseMqttDataList.Add(a);
  464. //if (houseMqttDataList.Any())
  465. //{
  466. // string mqttMsg = JsonConvert.SerializeObject(houseMqttDataList);
  467. // SerialBinController.ReportDataController(mqttMsg);
  468. //}
  469. //await Task.Delay(1000 * TLSetting.historyCurveInterval);
  470. }
  471. catch (Exception ex)
  472. {
  473. LogService.ExceptionLog(ex, "仓时历史记录上报", null, LogEnum.RunException);
  474. }
  475. finally
  476. {
  477. await Task.Delay(1000 * TLSetting.historyCurveInterval);
  478. }
  479. }
  480. }, TaskCreationOptions.LongRunning);
  481. }
  482. /// <summary>
  483. /// 开启心跳线程
  484. /// </summary>
  485. public void StartPushMessageThread()
  486. {
  487. int time = 1000 * 60 * 10;
  488. Task.Factory.StartNew(() =>
  489. {
  490. while (true)
  491. {
  492. try
  493. {
  494. SerialBinController.PushMessageController(TLSetting.tlSn, 1, GetDiskInfo(TLSetting.tmpDir));
  495. if (DateTime.Now.Hour != TLSetting.autoFocusTime)
  496. {
  497. if (isSetZiDong) isSetZiDong = false;
  498. continue;
  499. }
  500. if (isSetZiDong) continue;
  501. Task.Run(() => DeleteLog());
  502. isSetZiDong = true;
  503. if (HouseBin1 != null)
  504. {
  505. HouseBin1.FirstClearest = true;
  506. HouseBin1.ReCa = true;
  507. }
  508. if (HouseBin2 != null)
  509. {
  510. HouseBin2.FirstClearest = true;
  511. HouseBin2.ReCa = true;
  512. }
  513. if (HouseBin3 != null)
  514. {
  515. HouseBin3.FirstClearest = true;
  516. HouseBin3.ReCa = true;
  517. }
  518. if (HouseBin4 != null)
  519. {
  520. HouseBin4.FirstClearest = true;
  521. HouseBin4.ReCa = true;
  522. }
  523. if (HouseBin5 != null)
  524. {
  525. HouseBin5.FirstClearest = true;
  526. HouseBin5.ReCa = true;
  527. }
  528. if (HouseBin6 != null)
  529. {
  530. HouseBin6.FirstClearest = true;
  531. HouseBin6.ReCa = true;
  532. }
  533. if (HouseBin7 != null)
  534. {
  535. HouseBin7.FirstClearest = true;
  536. HouseBin7.ReCa = true;
  537. }
  538. if (HouseBin8 != null)
  539. {
  540. HouseBin8.FirstClearest = true;
  541. HouseBin8.ReCa = true;
  542. }
  543. if (HouseBin9 != null)
  544. {
  545. HouseBin9.FirstClearest = true;
  546. HouseBin9.ReCa = true;
  547. }
  548. if (HouseBin10 != null)
  549. {
  550. HouseBin10.FirstClearest = true;
  551. HouseBin10.ReCa = true;
  552. }
  553. }
  554. catch (Exception ex)
  555. {
  556. LogService.ExceptionLog(ex, "心跳线程", null, LogEnum.RunException);
  557. }
  558. finally
  559. {
  560. Thread.Sleep(time);
  561. }
  562. }
  563. }, TaskCreationOptions.LongRunning);
  564. }
  565. #region 仓室事件设置
  566. /// <summary>
  567. /// 仓室事件初始化
  568. /// </summary>
  569. /// <param name="BufferBottleBin"></param>
  570. public void InitHouseBinEvent(HouseBin houseBin)
  571. {
  572. houseBin.TLLogEvent += LogService.TLLog;
  573. houseBin.HouseLogEvent += LogService.HouseLog;
  574. houseBin.ExceptionLogEvent += LogService.ExceptionLog;
  575. houseBin.GetAutoFocusServiceEvent += HouseBin_GetAutoFocusServiceEvent;
  576. houseBin.GetAutoFocusDBEvent += HouseBin_GetAutoFocusDBEvent;
  577. // M2-04:注入标定结果存储入口(写 JSON 真相源 + 镜像库),对焦逐 well 标定后调用。
  578. houseBin.AutofocusStore = AutofocusStore;
  579. houseBin.GetCCDServiceEvent += HouseBin_GetCCDServiceEvent;
  580. houseBin.GetCCDDBEvent += HouseBin_GetCCDDBEvent;
  581. houseBin.UploadImageEvent += HouseBin_UploadImageEvent;
  582. houseBin.UpdateAutofocusStateEvent += HouseBin_UpdateAutofocusStateEvent;
  583. houseBin.SavePicDbEvent += HouseBin_SavePicDbEvent;
  584. houseBin.HouseStateEvent += HouseBin_HouseStateEvent;
  585. houseBin.CCDStateEvent += HouseBinPhotoStateEvent;
  586. houseBin.OnHistoryEvent += HouseBin_OnHistoryEvent;
  587. houseBin.ChangeBufferBottleBinEvent += HouseBin_ChangeBufferBottleBinEvent;
  588. houseBin.HouseBinChangeBufferBottleBinEvent += HouseBin_HouseBinChangeBufferBottleBinEvent;
  589. //houseBin.CCDStateEvent += HouseBin_CCDStateEvent;
  590. houseBin.TongQi = csTime * 1000;
  591. houseBin.VentPre = houseVentPre;
  592. houseBin.VentNum = houseVentNum;
  593. houseBin.VentWaitTimeB = houseVentWaitTimeB;
  594. houseBin.VentWaitTimeD = houseVentWaitTimeD;
  595. houseBin.AutoWaitTime = houseAutoWaitTime * 60000;
  596. houseBin.CCDAutoWaitTime = houseCCDAutoWaitTime * 60000;
  597. houseBin.CCDFailedNumber = houseCCDFailedNumber;
  598. houseBin.CCDFailedWaitTime = houseCCDFailedWaitTime * 1000;
  599. if (houseCCDError == 1)
  600. {
  601. houseBin.CCDError = true;
  602. }
  603. else
  604. {
  605. houseBin.CCDError = false;
  606. }
  607. if (queuAir == 0)
  608. {
  609. houseBin.IsPai = false;
  610. }
  611. else
  612. {
  613. houseBin.IsPai = true;
  614. }
  615. houseBin.TakePhotoFailed = TakePhotoString;
  616. }
  617. private void HouseBin_CCDStateEvent(int houseSn, int ccdState)
  618. {
  619. if (ccdState == 1)
  620. {
  621. LogService.TLLog($"{houseSn}号舱室拍照异常,停止拍照", LogEnum.RunRecord);
  622. }
  623. else
  624. {
  625. LogService.TLLog($"{houseSn}号舱室拍照恢复正常", LogEnum.RunRecord);
  626. }
  627. }
  628. private bool HouseBin_HouseBinChangeBufferBottleBinEvent(HouseBin arg1, int arg2)
  629. {
  630. if (BufferBottleBin == null)
  631. {
  632. LogService.TLLog($"缓冲瓶为空,无法操作进气阀:{arg1}、{arg2}", LogEnum.RunError);
  633. return false;
  634. }
  635. if (arg2 == 0)
  636. {
  637. BufferBottleBin.HuanQiEnd(arg1);
  638. return true;
  639. }
  640. else if (arg2 == 1)
  641. {
  642. BufferBottleBin.HuanQiStart(arg1);
  643. return true;
  644. }
  645. else
  646. {
  647. LogService.TLLog($"状态码错误,无法操作进气阀:{arg1}、{arg2}", LogEnum.RunError);
  648. return false;
  649. }
  650. }
  651. private bool HouseBin_ChangeBufferBottleBinEvent(int arg1, int arg2)
  652. {
  653. if (BufferBottleBin == null)
  654. {
  655. LogService.TLLog($"缓冲瓶为空,无法操作进气阀:{arg1}、{arg2}", LogEnum.RunError);
  656. return false;
  657. }
  658. if (arg2 == 0)
  659. {
  660. BufferBottleBin.CloseIntakeValve(arg1);
  661. return true;
  662. }
  663. else if (arg2 == 1)
  664. {
  665. BufferBottleBin.OpenIntakeValve(arg1);
  666. return true;
  667. }
  668. else
  669. {
  670. LogService.TLLog($"状态码错误,无法操作进气阀:{arg1}、{arg2}", LogEnum.RunError);
  671. return false;
  672. }
  673. }
  674. private void HouseBin_OnHistoryEvent(HouseHistoryData obj)
  675. {
  676. SerialBinController.ReportDataController(JsonConvert.SerializeObject(new List<HouseHistoryData> { obj }));
  677. }
  678. private void HouseBin_HouseStateEvent(int housesn, int houseState, int comState, int photoState, int wellSN, int airSwapState)
  679. {
  680. SerialBinController.ReportAlarmController(TLSetting.tlSn, housesn, houseState, comState, photoState, wellSN, airSwapState);
  681. //if (photoState != 0)
  682. //{
  683. // SerialBinController.ReportAlarmController(TLSetting.tlSn, housesn, houseState, comState, photoState, wellSN, airSwapState);
  684. // return;
  685. //}
  686. //for (int i = 1; i <= 16; i++)
  687. //{
  688. // SerialBinController.ReportAlarmController(TLSetting.tlSn, housesn, houseState, comState, photoState, i, airSwapState);
  689. //}
  690. }
  691. private void HouseBinPhotoStateEvent(int housesn, int photoState, int wellSN)
  692. {
  693. if (photoState != 0)
  694. {
  695. SerialBinController.ReportAlarmController(TLSetting.tlSn, housesn, -1, -1, photoState, wellSN, -1);
  696. StopProEvent?.Invoke();
  697. return;
  698. }
  699. for (int i = 1; i <= 16; i++)
  700. {
  701. SerialBinController.ReportAlarmController(TLSetting.tlSn, housesn, -1, -1, photoState, i, -1);
  702. }
  703. }
  704. /// <summary>
  705. /// 仓室图片保存到数据库
  706. /// </summary>
  707. /// <param name="obj"></param>
  708. /// <exception cref="NotImplementedException"></exception>
  709. private void HouseBin_SavePicDbEvent(ImageDTO obj)
  710. {
  711. if (obj == null) return;
  712. SerialBinController.SavePictreController(obj);
  713. }
  714. /// <summary>
  715. /// 仓室上传图片
  716. /// </summary>
  717. /// <param name="obj"></param>
  718. private void HouseBin_UploadImageEvent(ImageDTO obj)
  719. {
  720. if (obj == null) return;
  721. lock (ImageDTODic)
  722. {
  723. if (ImageDTODic.Count > 50)
  724. {
  725. LogService.TLLog($"内存当中保存的图片已经超过50张了{obj.HouseSn}、{obj.WellSn}、{obj.SourceImageName}", LogEnum.RunError);
  726. return;
  727. }
  728. if (!ImageDTODic.ContainsKey(obj.SourceImageName))
  729. {
  730. ImageDTODic.Add(obj.SourceImageName, obj);
  731. }
  732. }
  733. }
  734. /// <summary>
  735. /// 从服务器获取自动对焦位置
  736. /// </summary>
  737. /// <param name="arg1"></param>
  738. /// <param name="arg2"></param>
  739. /// <param name="arg3"></param>
  740. /// <returns></returns>
  741. private List<HouseWellPhoto> HouseBin_GetAutoFocusServiceEvent(int arg1, Dictionary<int, DateTime?> arg3)
  742. {
  743. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  744. foreach (var item in arg3)
  745. {
  746. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  747. {
  748. well = item.Key,
  749. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  750. });
  751. }
  752. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  753. {
  754. houseSn = arg1,
  755. tlSn = TLSetting.tlSn,
  756. wellSnList = wellSnAndAutoTimes,
  757. };
  758. return HouseBinController.GetAutoFocusController(positionRequestDTO);
  759. }
  760. /// <summary>
  761. /// 从数据库获取自动对焦位置
  762. /// </summary>
  763. /// <param name="arg1"></param>
  764. /// <param name="arg2"></param>
  765. /// <param name="arg3"></param>
  766. /// <returns></returns>
  767. private List<HouseWellPhoto> HouseBin_GetAutoFocusDBEvent(int arg1, Dictionary<int, DateTime?> arg3)
  768. {
  769. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  770. foreach (var item in arg3)
  771. {
  772. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  773. {
  774. well = item.Key,
  775. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  776. });
  777. }
  778. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  779. {
  780. houseSn = arg1,
  781. tlSn = TLSetting.tlSn,
  782. wellSnList = wellSnAndAutoTimes,
  783. };
  784. return HouseBinController.DbGetPositionData(positionRequestDTO.wellSnList.Select(x => x.well).ToList(), positionRequestDTO.houseSn, positionRequestDTO.tlSn, 0);
  785. }
  786. /// <summary>
  787. /// 服务器获取仓室拍照位置
  788. /// </summary>
  789. /// <param name="arg1"></param>
  790. /// <param name="arg2"></param>
  791. /// <param name="arg3"></param>
  792. /// <returns></returns>
  793. private PositionInfoResultDTO HouseBin_GetCCDServiceEvent(int arg1, Dictionary<int, DateTime?> arg3)
  794. {
  795. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  796. foreach (var item in arg3)
  797. {
  798. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  799. {
  800. well = item.Key,
  801. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  802. });
  803. }
  804. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  805. {
  806. houseSn = arg1,
  807. wellSnList = wellSnAndAutoTimes,
  808. tlSn = TLSetting.tlSn,
  809. };
  810. var result = HouseBinController.GetCCDPositionController(positionRequestDTO);
  811. if (result != null && result.complete == 0)//完成
  812. {
  813. List<HouseWellPhoto> CCDPositionList = new List<HouseWellPhoto>();
  814. foreach (var item in result.positionVOList)
  815. {
  816. CCDPositionList.Add(ConvertHelper.ConvertToHouseWellPhoto(item));
  817. }
  818. HouseBinController.DbUpdatePositionData(CCDPositionList, positionRequestDTO.houseSn, positionRequestDTO.tlSn, 1);
  819. }
  820. return result;
  821. }
  822. /// <summary>
  823. /// 数据库获取仓室拍照位置
  824. /// </summary>
  825. /// <param name="arg1"></param>
  826. /// <param name="arg2"></param>
  827. /// <param name="arg3"></param>
  828. /// <returns></returns>
  829. private List<HouseWellPhoto> HouseBin_GetCCDDBEvent(int arg1, Dictionary<int, DateTime?> arg3)
  830. {
  831. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  832. foreach (var item in arg3)
  833. {
  834. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  835. {
  836. well = item.Key,
  837. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  838. });
  839. }
  840. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  841. {
  842. houseSn = arg1,
  843. wellSnList = wellSnAndAutoTimes,
  844. tlSn = TLSetting.tlSn,
  845. };
  846. return HouseBinController.DbGetPositionData(positionRequestDTO.wellSnList.Select(x => x.well).ToList(), positionRequestDTO.houseSn, positionRequestDTO.tlSn, 1);
  847. }
  848. private void HouseBin_UpdateAutofocusStateEvent(bool newValue, int housesn)
  849. {
  850. int autoFocus = 0;
  851. if (newValue)
  852. {
  853. autoFocus = 1;
  854. }
  855. SerialBinController.UpdateAutofocusStateController(TLSetting.tlSn, housesn, autoFocus);
  856. }
  857. /// <summary>
  858. /// 缓冲瓶事件初始化
  859. /// </summary>
  860. /// <param name="BufferBottleBin"></param>
  861. public void InitBufferBottleBinEvent(BufferBottleBin BufferBottleBin)
  862. {
  863. BufferBottleBin.TLLogEvent += LogService.TLLog;
  864. BufferBottleBin.HouseLogEvent += LogService.HouseLog;
  865. BufferBottleBin.ExceptionLogEvent += LogService.ExceptionLog;
  866. BufferBottleBin.HouseStateEvent += HouseBin_HouseStateEvent;
  867. }
  868. #endregion
  869. #region mqtt消息处理
  870. /// <summary>
  871. /// mqtt接受消息
  872. /// </summary>
  873. /// <param name="message"></param>
  874. public void MqttMessage(string message)
  875. {
  876. if (string.IsNullOrEmpty(message)) return;
  877. MqttResult mqttResult = null;
  878. bool isSuccess = true;
  879. string uuid = null;
  880. try
  881. {
  882. mqttResult = JsonConvert.DeserializeObject<MqttResult>(message);
  883. if (mqttResult == null)
  884. {
  885. LogService.TLLog($"AppData.MqttMessage,mqtt消息反序列化失败,消息:{message}", LogEnum.MqttClient);
  886. return;
  887. }
  888. switch (mqttResult.type)
  889. {
  890. case (int)MqttEnum.StartBalance:
  891. isSuccess = StartBalance(mqttResult.data);
  892. break;
  893. case (int)MqttEnum.EndBalance:
  894. isSuccess = EndBalance(mqttResult.data);
  895. break;
  896. case (int)MqttEnum.StartDish:
  897. isSuccess = StartDish(mqttResult.data);
  898. break;
  899. case (int)MqttEnum.EndDish:
  900. isSuccess = EndDish(mqttResult.data);
  901. break;
  902. case (int)MqttEnum.EmbryoState:
  903. isSuccess = EmbryoState(mqttResult.data);
  904. break;
  905. case (int)MqttEnum.Update:
  906. isSuccess = UpDataSettingMqtt(mqttResult.data);
  907. break;
  908. case (int)MqttEnum.DebugStart:
  909. isSuccess = DebugStart(mqttResult.data, ref uuid);
  910. break;
  911. case (int)MqttEnum.HouseAutoFocus:
  912. isSuccess = HouseAutoFocus(mqttResult.data);
  913. break;
  914. case (int)MqttEnum.WellAutoFocus:
  915. isSuccess = WellAutoFocus(mqttResult.data);
  916. break;
  917. }
  918. }
  919. catch (Exception ex)
  920. {
  921. LogService.ExceptionLog(ex, "mqtt消息处理", null, LogEnum.RunException);
  922. isSuccess = false;
  923. }
  924. finally
  925. {
  926. if (mqttResult != null)
  927. {
  928. if (string.IsNullOrEmpty(uuid))
  929. {
  930. SerialBinController.MqttResultController(isSuccess ? 200 : 400, isSuccess, mqttResult.messageId);
  931. }
  932. else
  933. {
  934. SerialBinController.MqttResultController(isSuccess ? 200 : 400, isSuccess, mqttResult.messageId, uuid);
  935. }
  936. }
  937. }
  938. }
  939. /// <summary>
  940. /// 开始平衡
  941. /// </summary>
  942. /// <param name="data"></param>
  943. /// <returns></returns>
  944. private bool StartBalance(object data)
  945. {
  946. try
  947. {
  948. Balance balance = JsonConvert.DeserializeObject<Balance>(data.ToString());
  949. DBService.AddBalance(balance);
  950. HouseBin currentHouseBin = HouseSnToHouseBin(balance.houseSn);
  951. if (currentHouseBin == null) return false;
  952. currentHouseBin.StartBlance(balance);
  953. return true;
  954. }
  955. catch (Exception ex)
  956. {
  957. ExLog(ex, "StartBalance");
  958. return false;
  959. }
  960. }
  961. private bool EndBalance(object data)
  962. {
  963. try
  964. {
  965. Balance balance = JsonConvert.DeserializeObject<Balance>(data.ToString());
  966. HouseBin currentHouseBin = HouseSnToHouseBin(balance.houseSn);
  967. if (currentHouseBin == null) return false;
  968. DBService.EndBalance(balance.id, balance.endTime);
  969. currentHouseBin.StopBlance();
  970. return true;
  971. }
  972. catch (Exception ex)
  973. {
  974. ExLog(ex, "EndBalance");
  975. return false;
  976. }
  977. }
  978. private bool StartDish(object data)
  979. {
  980. try
  981. {
  982. Dish dish = JsonConvert.DeserializeObject<Dish>(data.ToString());
  983. DBService.AddDish(dish, dish.tlSn);
  984. HouseBin currentHouseBin = HouseSnToHouseBin(dish.houseSn);
  985. if (currentHouseBin == null) return false;
  986. currentHouseBin.StartDish(dish);
  987. return true;
  988. }
  989. catch (Exception ex)
  990. {
  991. ExLog(ex, "StartDish");
  992. return false;
  993. }
  994. }
  995. private bool EndDish(object data)
  996. {
  997. try
  998. {
  999. Dish dish = JsonConvert.DeserializeObject<Dish>(data.ToString());
  1000. DBService.EndDish(dish.id, dish.endTime.Value, dish.tlSn);
  1001. HouseBin currentHouseBin = HouseSnToHouseBin(dish.houseSn);
  1002. if (currentHouseBin == null) return false;
  1003. currentHouseBin.StopDish();
  1004. return true;
  1005. }
  1006. catch (Exception ex)
  1007. {
  1008. ExLog(ex, "EndDish");
  1009. return false;
  1010. }
  1011. }
  1012. private bool DebugStart(object data, ref string uuid)
  1013. {
  1014. try
  1015. {
  1016. //System.Collections.IList list = param["list"] as System.Collections.IList;
  1017. //JArray itemObject = (JArray)keyValuePair.Value;
  1018. //foreach (KeyValuePair<string, JToken> keyValuePair in jobject)
  1019. if (data == null) return false;
  1020. if (string.IsNullOrEmpty(data.ToString())) return false;
  1021. JObject jObject = JObject.Parse(data.ToString());
  1022. string tlsn = jObject["tlSn"].ToString();
  1023. uuid = jObject["uuid"].ToString();
  1024. int housesn = int.Parse(jObject["houseSn"].ToString());
  1025. switch (housesn)
  1026. {
  1027. case 1:
  1028. HouseBin1.IsDebug = true;
  1029. break;
  1030. case 2:
  1031. HouseBin2.IsDebug = true;
  1032. break;
  1033. case 3:
  1034. HouseBin3.IsDebug = true;
  1035. break;
  1036. case 4:
  1037. HouseBin4.IsDebug = true;
  1038. break;
  1039. case 5:
  1040. HouseBin5.IsDebug = true;
  1041. break;
  1042. case 6:
  1043. HouseBin6.IsDebug = true;
  1044. break;
  1045. case 7:
  1046. HouseBin7.IsDebug = true;
  1047. break;
  1048. case 8:
  1049. HouseBin8.IsDebug = true;
  1050. break;
  1051. case 9:
  1052. HouseBin9.IsDebug = true;
  1053. break;
  1054. case 10:
  1055. HouseBin10.IsDebug = true;
  1056. break;
  1057. }
  1058. bool IsDebugOk = false;
  1059. do
  1060. {
  1061. switch (housesn)
  1062. {
  1063. case 1:
  1064. IsDebugOk = HouseBin1.isDebugOk;
  1065. break;
  1066. case 2:
  1067. IsDebugOk = HouseBin2.isDebugOk;
  1068. break;
  1069. case 3:
  1070. IsDebugOk = HouseBin3.isDebugOk;
  1071. break;
  1072. case 4:
  1073. IsDebugOk = HouseBin4.isDebugOk;
  1074. break;
  1075. case 5:
  1076. IsDebugOk = HouseBin5.isDebugOk;
  1077. break;
  1078. case 6:
  1079. IsDebugOk = HouseBin6.isDebugOk;
  1080. break;
  1081. case 7:
  1082. IsDebugOk = HouseBin7.isDebugOk;
  1083. break;
  1084. case 8:
  1085. IsDebugOk = HouseBin8.isDebugOk;
  1086. break;
  1087. case 9:
  1088. IsDebugOk = HouseBin9.isDebugOk;
  1089. break;
  1090. case 10:
  1091. IsDebugOk = HouseBin10.isDebugOk;
  1092. break;
  1093. }
  1094. if (IsDebugOk)
  1095. {
  1096. break;
  1097. }
  1098. Thread.Sleep(1000);
  1099. } while (true);
  1100. return true;
  1101. }
  1102. catch (Exception ex)
  1103. {
  1104. LogService.ExceptionLog(ex, "mqtt.DebugStart", null, LogEnum.RunException);
  1105. return false;
  1106. }
  1107. }
  1108. private bool EmbryoState(object data)
  1109. {
  1110. try
  1111. {
  1112. Embryo embryo = JsonConvert.DeserializeObject<Embryo>(data.ToString());
  1113. DBService.ChangeEmbryoState(embryo);
  1114. HouseBin currentHouseBin = HouseSnToHouseBin(embryo.houseSn);
  1115. if (currentHouseBin == null) return false;
  1116. currentHouseBin.ChangeEmbryoState(embryo);
  1117. return true;
  1118. }
  1119. catch (Exception ex)
  1120. {
  1121. ExLog(ex, "EmbryoState");
  1122. return false;
  1123. }
  1124. }
  1125. private bool UpDataSettingMqtt(object data)
  1126. {
  1127. try
  1128. {
  1129. if (data == null) return false;
  1130. string dataString = data.ToString();
  1131. if (string.IsNullOrEmpty(dataString)) return false;
  1132. JObject jObject = JObject.Parse(dataString);
  1133. string tlsn = jObject["tlSn"].ToString();
  1134. string dateTime = jObject["updateTime"].ToString();
  1135. return UpdateSetting(tlsn);
  1136. }
  1137. catch (Exception ex)
  1138. {
  1139. ExLog(ex, "UpDataSettingMqtt");
  1140. return false;
  1141. }
  1142. }
  1143. public bool HouseAutoFocus(object data)
  1144. {
  1145. try
  1146. {
  1147. HouseAutoFocusMqtt houseAutoFocus = JsonConvert.DeserializeObject<HouseAutoFocusMqtt>(data.ToString());
  1148. if (houseAutoFocus == null || !houseAutoFocus.houseSnList.Any())
  1149. {
  1150. LogService.TLLog($"json转换失败,不更新配置信息{data.ToString()}", LogEnum.RunError);
  1151. return false;
  1152. }
  1153. if (!UpdateSetting(houseAutoFocus.tlSn))
  1154. {
  1155. LogService.TLLog($"更新配置信息失败,不开启自动对焦", LogEnum.RunError);
  1156. return false;
  1157. }
  1158. foreach (var houseSn in houseAutoFocus.houseSnList)
  1159. {
  1160. HouseBin currentHouseBin = HouseSnToHouseBin(houseSn);
  1161. if (currentHouseBin == null)
  1162. {
  1163. LogService.TLLog($"开启自动对焦时,获取舱室为空,{houseSn}、{data.ToString()}", LogEnum.RunError);
  1164. continue;
  1165. }
  1166. currentHouseBin.HouseAutoFocus();
  1167. }
  1168. return true;
  1169. }
  1170. catch (Exception ex)
  1171. {
  1172. ExLog(ex, "HouseAutoFocus");
  1173. return false;
  1174. }
  1175. }
  1176. public bool WellAutoFocus(object data)
  1177. {
  1178. try
  1179. {
  1180. WellAutoFocusMqtt wellAutoFocusMqtt = JsonConvert.DeserializeObject<WellAutoFocusMqtt>(data.ToString());
  1181. if (wellAutoFocusMqtt == null || !wellAutoFocusMqtt.houseSnList.Any()) return false;
  1182. if (!UpdateSetting(wellAutoFocusMqtt.tlSn))
  1183. {
  1184. LogService.TLLog($"更新配置信息失败,不开启自动对焦", LogEnum.RunError);
  1185. return false;
  1186. }
  1187. foreach (var houseSn in wellAutoFocusMqtt.houseSnList)
  1188. {
  1189. HouseBin currentHouseBin = HouseSnToHouseBin(houseSn.house);
  1190. if (currentHouseBin == null) continue;
  1191. currentHouseBin.WellAutoFocus(houseSn.well);
  1192. }
  1193. return true;
  1194. }
  1195. catch (Exception ex)
  1196. {
  1197. ExLog(ex, "WellAutoFocus");
  1198. return false;
  1199. }
  1200. }
  1201. public bool UpdateSetting(string tlsn)
  1202. {
  1203. try
  1204. {
  1205. var initTLResult = SerialBinController.UpdataSettingController(tlsn);
  1206. if (initTLResult == null)
  1207. {
  1208. LogService.TLLog($"更新设置时返回为空", LogEnum.RunError);
  1209. return false;
  1210. }
  1211. TLSetting = initTLResult.TLSetting;
  1212. PathHelper.pan = initTLResult.TLSetting.tmpDir;
  1213. LogService.Pan = initTLResult.TLSetting.tmpDir;
  1214. for (int i = 1; i <= 10; i++)
  1215. {
  1216. HouseBin currentHouseBin = HouseSnToHouseBin(i);
  1217. if (currentHouseBin == null) continue;
  1218. currentHouseBin.UpdataHouseSetting(initTLResult);
  1219. }
  1220. //UpdataKafkaAndMqtt();
  1221. return true;
  1222. }
  1223. catch (Exception ex)
  1224. {
  1225. ExLog(ex, "UpdateSetting");
  1226. return false;
  1227. }
  1228. }
  1229. #endregion
  1230. /// <summary>
  1231. /// mqtt报警
  1232. /// </summary>
  1233. /// <param name="message"></param>
  1234. public void MqttAlarm(string message)
  1235. {
  1236. try
  1237. {
  1238. HttpService.AlarmApi1(TLSetting.tlSn, "CLOUD_SLAVE_MQTT_ALARM", new List<string> { message });
  1239. }
  1240. catch (Exception ex)
  1241. {
  1242. ExLog(ex, "mqtt报警");
  1243. return;
  1244. }
  1245. }
  1246. public void KafkaAlarm(string tlsn, int housesn, ulong dishId, ulong embryoId, string imageName, int wellSn)
  1247. {
  1248. try
  1249. {
  1250. HttpService.AlarmApi(tlsn, housesn, wellSn, "CLOUD_SLAVE_KAFKA_ALARM", new List<string> { dishId.ToString(), embryoId.ToString(), imageName });
  1251. }
  1252. catch (Exception ex)
  1253. {
  1254. ExLog(ex, "图片传输失败报警");
  1255. return;
  1256. }
  1257. }
  1258. public void KafkaAlarmChaoShi(string tlsn, int housesn, ulong dishId, ulong embryoId, string imageName, int wellSn)
  1259. {
  1260. try
  1261. {
  1262. HttpService.AlarmApi(tlsn, housesn, wellSn, "CLOUD_SLAVE_PICTURE_TRANSFER_ALARM", new List<string> { dishId.ToString(), embryoId.ToString(), imageName });
  1263. }
  1264. catch (Exception ex)
  1265. {
  1266. ExLog(ex, "图片传输超时报警");
  1267. return;
  1268. }
  1269. }
  1270. private async Task KafkaUploadImageAsync(string fileFullPath)
  1271. {
  1272. // M5-04-3(a):去重防并发重传。同名文件在上一轮上传未结束(慢链/超时)时,5s 重扫会再次进入本方法,
  1273. // 此处用 in-flight 集合保证同一文件同一时刻只有一条上传在跑;释放放在 finally,不影响「成功才删」语义。
  1274. string fileName = Path.GetFileName(fileFullPath);
  1275. lock (_uploadingFiles)
  1276. {
  1277. if (_uploadingFiles.Contains(fileName)) return; // 正在上传,跳过本轮重扫的重复触发
  1278. _uploadingFiles.Add(fileName);
  1279. }
  1280. try
  1281. {
  1282. Stopwatch stopwatch = Stopwatch.StartNew();
  1283. //LogService.TLLog($"准备上传{fileFullPath}", LogEnum.KafkaRecord);
  1284. ImageDTO imageDTO = null;
  1285. lock (ImageDTODic) if (ImageDTODic.ContainsKey(fileName)) imageDTO = ImageDTODic[fileName];
  1286. if (imageDTO == null)
  1287. {
  1288. imageDTO = SerialBinController.SearchPictureController(fileName, TLSetting.tlSn);
  1289. if (imageDTO == null)
  1290. {
  1291. LogService.TLLog($"数据库获取文件失败:{fileName}、{TLSetting.tlSn}:{fileFullPath}", LogEnum.RunError);
  1292. }
  1293. else
  1294. {
  1295. var imageBytes = AivfoHelper.GetImageData1(fileFullPath);
  1296. if (imageBytes == null)
  1297. {
  1298. LogService.TLLog($"上传中止,图片不存在:{fileFullPath}", LogEnum.RunError);
  1299. }
  1300. else
  1301. {
  1302. imageDTO.ImageData = ByteString.CopyFrom(imageBytes);
  1303. }
  1304. }
  1305. }
  1306. if (imageDTO == null)
  1307. {
  1308. LogService.TLLog($"上传中止,imageDTO为空:{fileFullPath}", LogEnum.KafkaRecord);
  1309. string newDir = PathHelper.GetErrorSaveDirectory();
  1310. if (!Directory.Exists(newDir)) Directory.CreateDirectory(newDir);
  1311. File.Move(fileFullPath, Path.Combine(newDir, fileName));
  1312. return;
  1313. }
  1314. //LogService.TLLog($"fileName文件大小:{imageDTO.ImageData.Count()}", LogEnum.KafkaRecord);
  1315. var time1 = stopwatch.Elapsed;
  1316. //LogService.TLLog($"开始上传{fileFullPath},准备耗时:{time1}毫秒", LogEnum.KafkaRecord);
  1317. var uploadResult = await KafkaService.kafkaProducerAsync(imageDTO);
  1318. var time2 = stopwatch.Elapsed;
  1319. //LogService.TLLog($"上传结束{fileFullPath},耗时:{time2 - time1}毫秒", LogEnum.KafkaRecord);
  1320. if (!uploadResult)
  1321. {
  1322. KafkaAlarm(imageDTO.TlSn, imageDTO.HouseSn, imageDTO.EmbryoCultureRecordId, imageDTO.EmbryoId, imageDTO.SourceImageName, imageDTO.WellSn);
  1323. LogService.TLLog($"上传失败:{fileFullPath}", LogEnum.RunError);
  1324. return;
  1325. }
  1326. if ((time2 - time1).TotalMilliseconds > 1000)
  1327. {
  1328. KafkaAlarmChaoShi(imageDTO.TlSn, imageDTO.HouseSn, imageDTO.EmbryoCultureRecordId, imageDTO.EmbryoId, imageDTO.SourceImageName, imageDTO.WellSn);
  1329. LogService.TLLog($"kafka上传超时:{fileFullPath}", LogEnum.RunError);
  1330. }
  1331. LastKafkaOkAt = DateTime.Now; // M5-03-2:Kafka 图片上传成功时间戳(只读监控用,不改上传逻辑)
  1332. lock (ImageDTODic) if (ImageDTODic.ContainsKey(fileName)) ImageDTODic.Remove(fileName);
  1333. if (File.Exists(fileFullPath))
  1334. {
  1335. try
  1336. {
  1337. File.Delete(fileFullPath);
  1338. }
  1339. catch (Exception ex)
  1340. {
  1341. LogService.ExceptionLog(ex, "kafka上传完成删除图片", null, LogEnum.RunException);
  1342. }
  1343. //if (imageDTO.PhotographType == 1)
  1344. //{
  1345. // string newpath = @"C:\TLData\AutofocusControlBreak";
  1346. // if (!Directory.Exists(newpath)) Directory.CreateDirectory(newpath);
  1347. // File.Move(fileFullPath, Path.Combine(newpath, fileName));
  1348. //}
  1349. //else
  1350. //{
  1351. // string newpath = @"C:\TLData\EmbryosControlBreak";
  1352. // if (!Directory.Exists(newpath)) Directory.CreateDirectory(newpath);
  1353. // File.Move(fileFullPath, Path.Combine(newpath, fileName));
  1354. //}
  1355. }
  1356. SerialBinController.DeletePictrueController(fileName, TLSetting.tlSn);
  1357. //LogService.TLLog($"上传完成:{fileFullPath},总耗时:{stopwatch.ElapsedMilliseconds}毫秒", LogEnum.KafkaRecord);
  1358. }
  1359. catch (Exception ex)
  1360. {
  1361. LogService.ExceptionLog(ex, "kafka上传图片", null, LogEnum.RunException);
  1362. return;
  1363. }
  1364. finally
  1365. {
  1366. // M5-04-3(a):无论成功/失败/中止,都释放 in-flight 标记,使下一轮重扫可重试(失败文件仍在落盘 → 不丢)。
  1367. lock (_uploadingFiles) _uploadingFiles.Remove(fileName);
  1368. }
  1369. }
  1370. private HouseMqttData GetHouseMqttData(HouseBin currentHouseBin)
  1371. {
  1372. if (currentHouseBin == null) return null;
  1373. if (currentHouseBin.House == null) return null;
  1374. int cultureState = 0;
  1375. if (currentHouseBin.Balance != null && currentHouseBin.Balance.id > 0) cultureState = 2;
  1376. if (currentHouseBin.Dish != null && currentHouseBin.Dish.id > 0) cultureState = 1;
  1377. return new HouseMqttData()
  1378. {
  1379. tlSn = TLSetting.tlSn,
  1380. houseSn = currentHouseBin.House.houseSn,
  1381. pressure = currentHouseBin.Pressure,
  1382. temperature = currentHouseBin.Temperature,
  1383. houseDoorState = currentHouseBin.IsDoorOpen == State.打开 ? 1 : 0,
  1384. pressureDesc = currentHouseBin.ValveState.ToString(),
  1385. houseDesc = currentHouseBin.RunState,
  1386. cultureState = cultureState,
  1387. houseState = (int)currentHouseBin.WorkingType,
  1388. };
  1389. }
  1390. private HouseMqttData GetHouseMqttData(BufferBottleBin currentBufferBottleBin)
  1391. {
  1392. if (currentBufferBottleBin == null) return null;
  1393. if (currentBufferBottleBin.House == null) return null;
  1394. return new HouseMqttData()
  1395. {
  1396. tlSn = TLSetting.tlSn,
  1397. houseSn = 11,
  1398. pressure = currentBufferBottleBin.BufferBottlePressure,
  1399. temperature = 0,
  1400. houseDoorState = 0,
  1401. pressureDesc = currentBufferBottleBin.ValveState.ToString(),
  1402. houseDesc = currentBufferBottleBin.RunState,
  1403. };
  1404. }
  1405. private HouseHistoryData GetHouseHistoryData(HouseBin currentHouseBin)
  1406. {
  1407. if (currentHouseBin == null) return null;
  1408. if (currentHouseBin.House == null) return null;
  1409. return new HouseHistoryData()
  1410. {
  1411. tlSn = TLSetting.tlSn,
  1412. houseSn = currentHouseBin.House.houseSn,
  1413. pressure = currentHouseBin.Pressure,
  1414. temperature = currentHouseBin.Temperature,
  1415. houseDoor = currentHouseBin.IsDoorOpen == State.打开 ? 1 : 0,
  1416. airSwap = currentHouseBin.WorkingType == WorkingType.AirSwapWorking ? 1 : 0,
  1417. temperatureLowerCover = currentHouseBin.Temperature2,
  1418. temperatureUpperCover = currentHouseBin.Temperature1,
  1419. temperatureLowerGlass = currentHouseBin.Temperature3,
  1420. };
  1421. }
  1422. private HouseHistoryData GetHouseHistoryData(BufferBottleBin currentBufferBottleBin)
  1423. {
  1424. if (currentBufferBottleBin == null) return null;
  1425. if (currentBufferBottleBin.House == null) return null;
  1426. return new HouseHistoryData()
  1427. {
  1428. tlSn = TLSetting.tlSn,
  1429. houseSn = 11,
  1430. pressure = currentBufferBottleBin.BufferBottlePressure,
  1431. temperature = 0,
  1432. houseDoor = 0,
  1433. airSwap = 0,
  1434. temperatureLowerCover = currentBufferBottleBin.Temperature1,
  1435. temperatureUpperCover = currentBufferBottleBin.Temperature2,
  1436. temperatureLowerGlass = 0,
  1437. cultureState = 0,
  1438. };
  1439. }
  1440. private HouseBin HouseSnToHouseBin(int housesn)
  1441. {
  1442. HouseBin result = null;
  1443. switch (housesn)
  1444. {
  1445. case 1:
  1446. result = HouseBin1;
  1447. break;
  1448. case 2:
  1449. result = HouseBin2;
  1450. break;
  1451. case 3:
  1452. result = HouseBin3;
  1453. break;
  1454. case 4:
  1455. result = HouseBin4;
  1456. break;
  1457. case 5:
  1458. result = HouseBin5;
  1459. break;
  1460. case 6:
  1461. result = HouseBin6;
  1462. break;
  1463. case 7:
  1464. result = HouseBin7;
  1465. break;
  1466. case 8:
  1467. result = HouseBin8;
  1468. break;
  1469. case 9:
  1470. result = HouseBin9;
  1471. break;
  1472. case 10:
  1473. result = HouseBin10;
  1474. break;
  1475. }
  1476. return result;
  1477. }
  1478. public DiskInfo GetDiskInfo(string pan)
  1479. {
  1480. DiskInfo diskInfo = new DiskInfo() { diskPath = pan };
  1481. try
  1482. {
  1483. string panNew = pan.ToUpper();
  1484. diskInfo.diskExist = Directory.Exists($"{panNew}:\\") ? 0 : 1;
  1485. if (diskInfo.diskExist == 1) return diskInfo;
  1486. bool IsFind = false;
  1487. DriveInfo[] allDirves = DriveInfo.GetDrives();
  1488. foreach (DriveInfo item in allDirves)
  1489. {
  1490. if (item.IsReady)
  1491. {
  1492. if (item.Name == $"{panNew}:\\")
  1493. {
  1494. IsFind = true;
  1495. diskInfo.diskSpace = (decimal)(item.TotalFreeSpace / (1024.00 * 1024.00 * 1024.00));
  1496. break;
  1497. }
  1498. }
  1499. }
  1500. if (!IsFind) diskInfo.diskExist = 1;
  1501. return diskInfo;
  1502. }
  1503. catch (Exception ex)
  1504. {
  1505. LogService.ExceptionLog(ex, "GetDiskInfo", null, LogEnum.RunException);
  1506. diskInfo.diskExist = 1;
  1507. return diskInfo;
  1508. }
  1509. }
  1510. public void DeleteLog()
  1511. {
  1512. try
  1513. {
  1514. string newPath = $"{TLSetting.tmpDir}:\\TLData\\ivf_tl_Control_logs";
  1515. var newDir = Directory.GetDirectories(newPath, "*", SearchOption.TopDirectoryOnly);
  1516. foreach (var item in newDir)
  1517. {
  1518. var dieName = System.IO.Path.GetFileName(item);
  1519. if (DateTime.TryParse(dieName, out DateTime newTime))
  1520. {
  1521. if (DateTime.Now.Subtract(newTime).Days >= 5)
  1522. {
  1523. Directory.Delete(item, true);
  1524. }
  1525. }
  1526. }
  1527. DeleteLogFile($"C:\\TLData\\ivf_tl_Control_logs\\LogError");
  1528. DeleteLogFile($"C:\\TLData\\ivf_tl_Control_logs\\Log");
  1529. }
  1530. catch (Exception ex)
  1531. {
  1532. LogService.ExceptionLog(ex, "DeleteLog", null, LogEnum.RunException);
  1533. }
  1534. }
  1535. private void DeleteLogFile(string newPath)
  1536. {
  1537. var newDir = Directory.GetFiles(newPath, "*.htm", SearchOption.TopDirectoryOnly);
  1538. string fileName = "";
  1539. DateTime fileTime = DateTime.Now;
  1540. DateTime nowTime = fileTime;
  1541. foreach (var item in newDir)
  1542. {
  1543. fileName = System.IO.Path.GetFileNameWithoutExtension(item);
  1544. if (fileName.Length == 8)
  1545. {
  1546. fileName = fileName.Insert(6, "-");
  1547. fileName = fileName.Insert(4, "-");
  1548. if (DateTime.TryParse(fileName, out fileTime))
  1549. {
  1550. if (nowTime.Subtract(fileTime).Days >= 5)
  1551. {
  1552. try
  1553. {
  1554. File.Delete(item);
  1555. }
  1556. catch (Exception)
  1557. {
  1558. continue;
  1559. }
  1560. }
  1561. }
  1562. }
  1563. }
  1564. }
  1565. public string ReadText(string fileName)
  1566. {
  1567. return File.ReadAllText(fileName);
  1568. }
  1569. public PositionInfoResultDTO HouseBin_GetCCDServiceEventTest(int arg1, Dictionary<int, DateTime?> arg3)
  1570. {
  1571. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  1572. foreach (var item in arg3)
  1573. {
  1574. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  1575. {
  1576. well = item.Key,
  1577. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  1578. });
  1579. }
  1580. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  1581. {
  1582. houseSn = arg1,
  1583. wellSnList = wellSnAndAutoTimes,
  1584. tlSn = "NEO-1-20230410",
  1585. };
  1586. var result = HouseBinController.GetCCDPositionController(positionRequestDTO);
  1587. if (result != null && result.complete == 0)//完成
  1588. {
  1589. List<HouseWellPhoto> CCDPositionList = new List<HouseWellPhoto>();
  1590. foreach (var item in result.positionVOList)
  1591. {
  1592. CCDPositionList.Add(ConvertHelper.ConvertToHouseWellPhoto(item));
  1593. }
  1594. HouseBinController.DbUpdatePositionData(CCDPositionList, positionRequestDTO.houseSn, positionRequestDTO.tlSn, 1);
  1595. }
  1596. return result;
  1597. }
  1598. public List<HouseWellPhoto> HouseBin_GetAutoFocusServiceEventTest(int arg1, Dictionary<int, DateTime?> arg3)
  1599. {
  1600. List<WellSnAndAutoTime> wellSnAndAutoTimes = new List<WellSnAndAutoTime>();
  1601. foreach (var item in arg3)
  1602. {
  1603. wellSnAndAutoTimes.Add(new WellSnAndAutoTime
  1604. {
  1605. well = item.Key,
  1606. autofocusTime = item.Value.HasValue ? item.Value.Value.ToString("yyyy-MM-dd HH:mm:ss") : null,
  1607. });
  1608. }
  1609. PositionRequestDTO positionRequestDTO = new PositionRequestDTO()
  1610. {
  1611. houseSn = arg1,
  1612. tlSn = "NEO-1-20230410",
  1613. wellSnList = wellSnAndAutoTimes,
  1614. };
  1615. return HouseBinController.GetAutoFocusController(positionRequestDTO);
  1616. }
  1617. public string GetLanguageStringByKey(string key)
  1618. {
  1619. try
  1620. {
  1621. if (System.Windows.Application.Current == null) return "";
  1622. object value = System.Windows.Application.Current.TryFindResource(key);
  1623. return value == null ? "" : value.ToString();
  1624. }
  1625. catch (Exception)
  1626. {
  1627. return "";
  1628. }
  1629. }
  1630. }
  1631. }