LogPcTask_Biz.cs 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550
  1. using B20UVLog.Models;
  2. using B20UVLog.Pages;
  3. using NetTaste;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Configuration;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using TFT_MelsecMcNet;
  12. namespace B20UVLog
  13. {
  14. public class LogPcTask_Biz
  15. {
  16. #region 单例模式
  17. /// <summary>
  18. /// 单例模式对象
  19. /// </summary>
  20. private static LogPcTask_Biz _instance = null;
  21. private static readonly object lockObj = new object();
  22. /// <summary>
  23. /// 单例模式方法
  24. /// </summary>
  25. public static LogPcTask_Biz Instance
  26. {
  27. get
  28. {
  29. if (_instance == null)
  30. {
  31. lock (lockObj)
  32. {
  33. if (_instance == null)
  34. {
  35. _instance = new LogPcTask_Biz();
  36. }
  37. }
  38. }
  39. return _instance;
  40. }
  41. }
  42. #endregion
  43. #region 全局变量
  44. public MelsecMcNet melsec_net = null;
  45. /// <summary>
  46. /// 日志头部
  47. /// </summary>
  48. private readonly string LogHeadText = "日志采集系统LogPc主业务类 ==>> ";
  49. private readonly List<Task> taskList = new();
  50. private readonly int TaskDelayTime = 500;
  51. private readonly int ReadDelayTime = 5000;
  52. private readonly CancellationTokenSource tokenSource = new();
  53. private PlcItemTypeModel AxisDataPLC;
  54. private PlcItemTypeModel AxisData2PLC;
  55. private PlcItemTypeModel AxisData3PLC;
  56. private PlcItemTypeModel AxisData4PLC;
  57. private PlcItemTypeModel AxisData5PLC;
  58. private PlcItemTypeModel ServoAxisStautsPLC;
  59. private PlcItemTypeModel GlassInformationPLC;
  60. private PlcItemTypeModel LampUseTimePLC;
  61. private PlcItemTypeModel RecipeBodyPLC;
  62. private PlcItemTypeModel SYSParaPLC;
  63. private PlcItemTypeModel RobotInterfaceInPLC;
  64. private PlcItemTypeModel RobotInterfaceOutPLC;
  65. private PlcItemTypeModel YMeasureDataPLC;
  66. private PlcItemTypeModel EQPStatusPLC;
  67. private PlcItemTypeModel RecipeCountPLC;
  68. private PlcItemTypeModel LampDataPLC;
  69. private PlcItemTypeModel AnalogDataPLC;
  70. private PlcItemTypeModel AlarmPLC;
  71. private PlcItemTypeModel WarnPLC;
  72. private PlcItemTypeModel IOPLC;
  73. //字典字段
  74. private List<DictModel> axleAlarm=new List<DictModel>();
  75. private List<DictModel> axleWarn = new List<DictModel>();
  76. private List<DictModel> deviceAlarm = new List<DictModel>();
  77. private List<DictModel> deviceWarn = new List<DictModel>();
  78. #endregion
  79. /// <summary>
  80. /// Log采集业务类 初始化数据
  81. /// </summary>
  82. /// <exception cref="Exception"></exception>
  83. public void Init()
  84. {
  85. var viewdata = DbHelper.Db.Queryable<AxisDataAllModel>().ToList();
  86. AxisDataPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AxisData");
  87. AxisData2PLC= DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AxisData2");
  88. AxisData3PLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AxisData3");
  89. AxisData4PLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AxisData4");
  90. AxisData5PLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AxisData5");
  91. ServoAxisStautsPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "ServoAxisStatus");
  92. GlassInformationPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "GlassInformation");
  93. LampUseTimePLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "LampUseTime");
  94. RecipeBodyPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "RecipeBody");
  95. SYSParaPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "SysPara");
  96. RobotInterfaceInPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "RobotInterfaceIn");
  97. RobotInterfaceOutPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "RobotInterfaceOut");
  98. YMeasureDataPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "YMeasureData");
  99. EQPStatusPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "EQPStatus");
  100. RecipeCountPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "RecipeCount");
  101. AnalogDataPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "AnalogData");
  102. LampDataPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "LampData");
  103. AlarmPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "Alarm");
  104. WarnPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "Warn");
  105. IOPLC = DbHelper.Db.Queryable<PlcItemTypeModel>().First(x => x.PlcItemType == "IO");
  106. //获取字典中的所有字段
  107. axleAlarm = DbHelper.Db.Queryable<DictModel>().ToList().FindAll(x=>x.Type=="Alarm"&&x.Code=="Axle");
  108. axleWarn = DbHelper.Db.Queryable<DictModel>().ToList().FindAll(x => x.Type == "Warn" && x.Code == "Axle");
  109. deviceAlarm = DbHelper.Db.Queryable<DictModel>().ToList().FindAll(x => x.Type == "Alarm" && x.Code == "Device");
  110. deviceWarn = DbHelper.Db.Queryable<DictModel>().ToList().FindAll(x => x.Type == "Warn" && x.Code == "Warn");
  111. }
  112. /// <summary>
  113. /// 连接PLC
  114. /// </summary>
  115. /// <returns></returns>
  116. public bool ConnectPlc()
  117. {
  118. try
  119. {
  120. melsec_net = new MelsecMcNet(ConfigurationManager.AppSettings["PLCAddr"], Convert.ToInt32(ConfigurationManager.AppSettings["PLCPort"]));
  121. OperateResult connect = melsec_net.ConnectServer();
  122. if (connect.IsSuccess)
  123. {
  124. ;
  125. return true;
  126. }
  127. else
  128. {
  129. return false;
  130. }
  131. }
  132. catch (Exception ex)
  133. {
  134. return false;
  135. }
  136. }
  137. /// <summary>
  138. /// 断开PLC连接
  139. /// </summary>
  140. public void DisConnectPlc()
  141. {
  142. // 暂停所有PLC采集线程。
  143. if (taskList.Count > 0)
  144. {
  145. tokenSource?.Cancel();
  146. foreach (Task item in taskList)
  147. {
  148. while (!item.IsCompleted)
  149. {
  150. }
  151. item.Dispose();
  152. }
  153. taskList.Clear();
  154. tokenSource?.Dispose();
  155. }
  156. OperateResult result = melsec_net?.ConnectClose();
  157. if (result.IsSuccess)
  158. {
  159. }
  160. else
  161. {
  162. }
  163. melsec_net = null;
  164. }
  165. #region PLC数据采集主业务线程
  166. public void StartPlcLogMonitor()
  167. {
  168. AxisDataLogTask();
  169. AxisData2LogTask();
  170. AxisData3LogTask();
  171. AxisData4LogTask();
  172. AxisData5LogTask();
  173. ServoAxisStatusLogTask();
  174. GlassInformationLogTask();
  175. LampUserTimeLogTask();
  176. RecipeBodyLogTask();
  177. SYSParaLogTask();
  178. RobotInPLCLogTask();
  179. RobotOutPLCLogTask();
  180. YMeasureDataLogTask();
  181. EQPStatusLogTask();
  182. RecipeBodyLogTask();
  183. AnalogDataLogTask();
  184. LampDataLogTask();
  185. AlarmLogTask();
  186. WarnLogTask();
  187. IOLogTask();
  188. }
  189. private void AxisDataLogTask()
  190. {
  191. taskList.Add(Task.Factory.StartNew(() =>
  192. {
  193. while (true)
  194. {
  195. if (tokenSource.IsCancellationRequested)
  196. {
  197. break;
  198. }
  199. if (AxisDataPLC is null)
  200. {
  201. continue;
  202. }
  203. OperateResult<bool> isAxisData = melsec_net.ReadBool(AxisDataPLC.ReportFlagAddress);
  204. if (isAxisData.IsSuccess && isAxisData.Content)
  205. {
  206. OperateResult<short[]> axisDataRet = melsec_net.ReadInt16(AxisDataPLC.PlcItemAddressType + AxisDataPLC.PlcItemStartAddress, (ushort)AxisDataPLC.PlcItemAddressLength);
  207. List<PlcItemModel> axisDataPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AxisDataPLC.PlcItemType).ToList();
  208. if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0)
  209. {
  210. continue;
  211. }
  212. foreach (PlcItemModel plcItem in axisDataPlcItemLst)
  213. {
  214. ParsePlcItemData(plcItem, axisDataRet.Content, 0);
  215. }
  216. //ToDo:把PLC数据插入到数据库中
  217. AxisDataModel axisData = MapPlcItemToObjectProperty<AxisDataModel>(axisDataPlcItemLst);
  218. axisData.RecordTime = DateTime.Now;
  219. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  220. melsec_net.Write(AxisDataPLC.ReplyFlagAddress, true);
  221. }
  222. else
  223. {
  224. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AxisDataPLC.ReplyFlagAddress);
  225. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  226. {
  227. melsec_net.Write(AxisDataPLC.ReplyFlagAddress, false);
  228. }
  229. }
  230. Task.Delay(TaskDelayTime).Wait();
  231. }
  232. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  233. }
  234. private void AxisData2LogTask()
  235. {
  236. taskList.Add(Task.Factory.StartNew(() =>
  237. {
  238. while (true)
  239. {
  240. if (tokenSource.IsCancellationRequested)
  241. {
  242. break;
  243. }
  244. if (AxisData2PLC is null)
  245. {
  246. continue;
  247. }
  248. OperateResult<bool> isAxisData = melsec_net.ReadBool(AxisData2PLC.ReportFlagAddress);
  249. if (isAxisData.IsSuccess && isAxisData.Content)
  250. {
  251. OperateResult<short[]> axisDatatRet = melsec_net.ReadInt16(AxisData2PLC.PlcItemAddressType + AxisData2PLC.PlcItemStartAddress, (ushort)AxisData2PLC.PlcItemAddressLength);
  252. List<PlcItemModel> axisDataPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AxisData2PLC.PlcItemType).ToList();
  253. if (!axisDatatRet.IsSuccess || axisDatatRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0)
  254. {
  255. continue;
  256. }
  257. foreach (PlcItemModel plcItem in axisDataPlcItemLst)
  258. {
  259. ParsePlcItemData(plcItem, axisDatatRet.Content, 0);
  260. }
  261. //ToDo:把PLC数据插入到数据库中
  262. AxisData2 axisData = MapPlcItemToObjectProperty<AxisData2>(axisDataPlcItemLst);
  263. axisData.RecordTime = DateTime.Now;
  264. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  265. melsec_net.Write(AxisData2PLC.ReplyFlagAddress, true);
  266. }
  267. else
  268. {
  269. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AxisData2PLC.ReplyFlagAddress);
  270. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  271. {
  272. melsec_net.Write(AxisData2PLC.ReplyFlagAddress, false);
  273. }
  274. }
  275. Task.Delay(TaskDelayTime).Wait();
  276. }
  277. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  278. }
  279. private void AxisData3LogTask()
  280. {
  281. taskList.Add(Task.Factory.StartNew(() =>
  282. {
  283. while (true)
  284. {
  285. if (tokenSource.IsCancellationRequested)
  286. {
  287. break;
  288. }
  289. if (AxisData3PLC is null)
  290. {
  291. continue;
  292. }
  293. OperateResult<bool> isAxisData = melsec_net.ReadBool(AxisData3PLC.ReportFlagAddress);
  294. if (isAxisData.IsSuccess && isAxisData.Content)
  295. {
  296. OperateResult<short[]> axisDataRet = melsec_net.ReadInt16(AxisData3PLC.PlcItemAddressType + AxisData3PLC.PlcItemStartAddress, (ushort)AxisData3PLC.PlcItemAddressLength);
  297. List<PlcItemModel> axisDataPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AxisData3PLC.PlcItemType).ToList();
  298. if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0)
  299. {
  300. continue;
  301. }
  302. foreach (PlcItemModel plcItem in axisDataPlcItemLst)
  303. {
  304. ParsePlcItemData(plcItem, axisDataRet.Content, 0);
  305. }
  306. //ToDo:把PLC数据插入到数据库中
  307. AxisData3 axisData = MapPlcItemToObjectProperty<AxisData3>(axisDataPlcItemLst);
  308. axisData.RecordTime = DateTime.Now;
  309. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  310. melsec_net.Write(AxisData3PLC.ReplyFlagAddress, true);
  311. }
  312. else
  313. {
  314. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AxisData3PLC.ReplyFlagAddress);
  315. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  316. {
  317. melsec_net.Write(AxisData3PLC.ReplyFlagAddress, false);
  318. }
  319. }
  320. Task.Delay(TaskDelayTime).Wait();
  321. }
  322. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  323. }
  324. private void AxisData4LogTask()
  325. {
  326. taskList.Add(Task.Factory.StartNew(() =>
  327. {
  328. while (true)
  329. {
  330. if (tokenSource.IsCancellationRequested)
  331. {
  332. break;
  333. }
  334. if (AxisData4PLC is null)
  335. {
  336. continue;
  337. }
  338. OperateResult<bool> isAxisData = melsec_net.ReadBool(AxisData4PLC.ReportFlagAddress);
  339. if (isAxisData.IsSuccess && isAxisData.Content)
  340. {
  341. OperateResult<short[]> axisDataRet = melsec_net.ReadInt16(AxisData4PLC.PlcItemAddressType + AxisData4PLC.PlcItemStartAddress, (ushort)AxisData4PLC.PlcItemAddressLength);
  342. List<PlcItemModel> axisDataPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AxisData4PLC.PlcItemType).ToList();
  343. if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0)
  344. {
  345. continue;
  346. }
  347. foreach (PlcItemModel plcItem in axisDataPlcItemLst)
  348. {
  349. ParsePlcItemData(plcItem, axisDataRet.Content, 0);
  350. }
  351. //ToDo:把PLC数据插入到数据库中
  352. AxisData4 axisData = MapPlcItemToObjectProperty<AxisData4>(axisDataPlcItemLst);
  353. axisData.RecordTime = DateTime.Now;
  354. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  355. melsec_net.Write(AxisData4PLC.ReplyFlagAddress, true);
  356. }
  357. else
  358. {
  359. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AxisData4PLC.ReplyFlagAddress);
  360. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  361. {
  362. melsec_net.Write(AxisData4PLC.ReplyFlagAddress, false);
  363. }
  364. }
  365. Task.Delay(TaskDelayTime).Wait();
  366. }
  367. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  368. }
  369. private void AxisData5LogTask()
  370. {
  371. taskList.Add(Task.Factory.StartNew(() =>
  372. {
  373. while (true)
  374. {
  375. if (tokenSource.IsCancellationRequested)
  376. {
  377. break;
  378. }
  379. if (AxisData5PLC is null)
  380. {
  381. continue;
  382. }
  383. OperateResult<bool> isAxisData = melsec_net.ReadBool(AxisData5PLC.ReportFlagAddress);
  384. if (isAxisData.IsSuccess && isAxisData.Content)
  385. {
  386. OperateResult<short[]> axisDataRet = melsec_net.ReadInt16(AxisData5PLC.PlcItemAddressType + AxisData5PLC.PlcItemStartAddress, (ushort)AxisData5PLC.PlcItemAddressLength);
  387. List<PlcItemModel> axisDataPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AxisData5PLC.PlcItemType).ToList();
  388. if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0)
  389. {
  390. continue;
  391. }
  392. foreach (PlcItemModel plcItem in axisDataPlcItemLst)
  393. {
  394. ParsePlcItemData(plcItem, axisDataRet.Content, 0);
  395. }
  396. //ToDo:把PLC数据插入到数据库中
  397. AxisData5 axisData = MapPlcItemToObjectProperty<AxisData5>(axisDataPlcItemLst);
  398. axisData.RecordTime = DateTime.Now;
  399. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  400. melsec_net.Write(AxisData5PLC.ReplyFlagAddress, true);
  401. }
  402. else
  403. {
  404. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AxisData5PLC.ReplyFlagAddress);
  405. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  406. {
  407. melsec_net.Write(AxisData5PLC.ReplyFlagAddress, false);
  408. }
  409. }
  410. Task.Delay(TaskDelayTime).Wait();
  411. }
  412. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  413. }
  414. /// <summary>
  415. /// servoAxis
  416. /// </summary>
  417. private void ServoAxisStatusLogTask()
  418. {
  419. taskList.Add(Task.Factory.StartNew(() =>
  420. {
  421. while (true)
  422. {
  423. if (tokenSource.IsCancellationRequested)
  424. {
  425. break;
  426. }
  427. if (ServoAxisStautsPLC is null)
  428. {
  429. continue;
  430. }
  431. OperateResult<bool> isServoAxis = melsec_net.ReadBool(ServoAxisStautsPLC.ReportFlagAddress);
  432. if (isServoAxis.IsSuccess && isServoAxis.Content)
  433. {
  434. OperateResult<short[]> servoAxisRet = melsec_net.ReadInt16(ServoAxisStautsPLC.PlcItemAddressType + ServoAxisStautsPLC.PlcItemStartAddress, (ushort)ServoAxisStautsPLC.PlcItemAddressLength);
  435. List<PlcItemModel> servoAxisPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == ServoAxisStautsPLC.PlcItemType).ToList();
  436. if (!servoAxisRet.IsSuccess || servoAxisRet.Content.Length <= 0 || servoAxisPlcItemLst is null || servoAxisPlcItemLst.Count <= 0)
  437. {
  438. continue;
  439. }
  440. foreach (PlcItemModel plcItem in servoAxisPlcItemLst)
  441. {
  442. ParsePlcItemData(plcItem, servoAxisRet.Content, 0);
  443. }
  444. //ToDo:把PLC数据插入到数据库中
  445. ServoAxisStautsOriginal servoOrignal = MapPlcItemToObjectProperty<ServoAxisStautsOriginal>(servoAxisPlcItemLst);
  446. //ServoAxisStautsOriginal 将不为0的字段转为ServoAxisStautsModel
  447. var nonZeroProperties = GetNonZeroProperties(servoOrignal);
  448. foreach (var property in nonZeroProperties)
  449. {
  450. string name = property.Key;
  451. int value = property.Value;
  452. ServoAxisStatusModel servoAxisStatusModel = new ServoAxisStatusModel();
  453. if(name.Contains("Warn"))
  454. {
  455. servoAxisStatusModel.AxisName = name.Substring(0, 4);
  456. servoAxisStatusModel.WarningCode = value;
  457. servoAxisStatusModel.WarningDescribe =axleWarn?.FirstOrDefault(x=>x.Key==value.ToString().Trim())?.Value;
  458. }
  459. else
  460. {
  461. if (name.Contains("Alarm"))
  462. {
  463. servoAxisStatusModel.AxisName = name.Substring(0, 4);
  464. servoAxisStatusModel.AlarmCode = value;
  465. servoAxisStatusModel.AlarmDescribe = axleAlarm?.FirstOrDefault(x => x.Key == value.ToString().Trim())?.Value;
  466. }
  467. }
  468. servoAxisStatusModel.RecordTime = DateTime.Now;
  469. DbHelper.Db.Insertable(servoAxisStatusModel).ExecuteCommand();
  470. melsec_net.Write(ServoAxisStautsPLC.ReplyFlagAddress, true);
  471. }
  472. }
  473. else
  474. {
  475. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(ServoAxisStautsPLC.ReplyFlagAddress);
  476. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  477. {
  478. melsec_net.Write(ServoAxisStautsPLC.ReplyFlagAddress, false);
  479. }
  480. }
  481. Task.Delay(TaskDelayTime).Wait();
  482. }
  483. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  484. }
  485. private void GlassInformationLogTask()
  486. {
  487. taskList.Add(Task.Factory.StartNew(() =>
  488. {
  489. while (true)
  490. {
  491. if (tokenSource.IsCancellationRequested)
  492. {
  493. break;
  494. }
  495. if (GlassInformationPLC is null)
  496. {
  497. continue;
  498. }
  499. OperateResult<bool> isServoAxis = melsec_net.ReadBool(GlassInformationPLC.ReportFlagAddress);
  500. if (isServoAxis.IsSuccess && isServoAxis.Content)
  501. {
  502. OperateResult<short[]> glassInfoRet = melsec_net.ReadInt16(GlassInformationPLC.PlcItemAddressType + GlassInformationPLC.PlcItemStartAddress, (ushort)GlassInformationPLC.PlcItemAddressLength);
  503. List<PlcItemModel> servoAxisPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == GlassInformationPLC.PlcItemType).ToList();
  504. if (!glassInfoRet.IsSuccess || glassInfoRet.Content.Length <= 0 || servoAxisPlcItemLst is null || servoAxisPlcItemLst.Count <= 0)
  505. {
  506. continue;
  507. }
  508. foreach (PlcItemModel plcItem in servoAxisPlcItemLst)
  509. {
  510. ParsePlcItemData(plcItem, glassInfoRet.Content, 0);
  511. }
  512. //ToDo:把PLC数据插入到数据库中
  513. GlassInformationModel glassInfoData = MapPlcItemToObjectProperty<GlassInformationModel>(servoAxisPlcItemLst);
  514. //读取时间
  515. OperateResult<short[]> glassInfoRetTime = melsec_net.ReadInt16("D16100", 6);
  516. if (!glassInfoRetTime.IsSuccess || glassInfoRetTime.Content.Length <= 0)
  517. {
  518. continue;
  519. }
  520. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[0], out int yy1, out int mm1);
  521. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[1], out int dd1, out int hh1);
  522. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[2], out int ff1, out int ss1);
  523. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[3], out int yy2, out int mm2);
  524. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[4], out int dd2, out int hh2);
  525. Convert16BitBCDToTwoInts(glassInfoRetTime.Content[5], out int ff2, out int ss2);
  526. glassInfoData.LordingTime = new DateTime(yy1, mm1, dd1, hh1, ff1, ss1);
  527. glassInfoData.UnlordingTime = new DateTime(yy2, mm2, dd2, hh2, ff2, ss2);
  528. glassInfoData.RecordTime = DateTime.Now;
  529. DbHelper.Db.Insertable(glassInfoData).ExecuteCommand();
  530. melsec_net.Write(GlassInformationPLC.ReplyFlagAddress, true);
  531. }
  532. else
  533. {
  534. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(GlassInformationPLC.ReplyFlagAddress);
  535. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  536. {
  537. melsec_net.Write(GlassInformationPLC.ReplyFlagAddress, false);
  538. }
  539. }
  540. Task.Delay(TaskDelayTime).Wait();
  541. }
  542. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  543. }
  544. private void LampUserTimeLogTask()
  545. {
  546. taskList.Add(Task.Factory.StartNew(() =>
  547. {
  548. while (true)
  549. {
  550. if (tokenSource.IsCancellationRequested)
  551. {
  552. break;
  553. }
  554. if (LampUseTimePLC is null)
  555. {
  556. continue;
  557. }
  558. OperateResult<bool> isLampUse = melsec_net.ReadBool(LampUseTimePLC.ReportFlagAddress);
  559. if (isLampUse.IsSuccess && isLampUse.Content)
  560. {
  561. OperateResult<short[]> glassInfoRet = melsec_net.ReadInt16(LampUseTimePLC.PlcItemAddressType + LampUseTimePLC.PlcItemStartAddress, (ushort)LampUseTimePLC.PlcItemAddressLength);
  562. List<PlcItemModel> glassInfoPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == LampUseTimePLC.PlcItemType).ToList();
  563. if (!glassInfoRet.IsSuccess || glassInfoRet.Content.Length <= 0 || glassInfoPlcItemLst is null || glassInfoPlcItemLst.Count <= 0)
  564. {
  565. continue;
  566. }
  567. foreach (PlcItemModel plcItem in glassInfoPlcItemLst)
  568. {
  569. ParsePlcItemData(plcItem, glassInfoRet.Content, 0);
  570. }
  571. //ToDo:把PLC数据插入到数据库中
  572. LampUseTimeModel axisData = MapPlcItemToObjectProperty<LampUseTimeModel>(glassInfoPlcItemLst);
  573. axisData.RecordTime = DateTime.Now;
  574. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  575. melsec_net.Write(LampUseTimePLC.ReplyFlagAddress, true);
  576. }
  577. else
  578. {
  579. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(LampUseTimePLC.ReplyFlagAddress);
  580. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  581. {
  582. melsec_net.Write(LampUseTimePLC.ReplyFlagAddress, false);
  583. }
  584. }
  585. Task.Delay(TaskDelayTime).Wait();
  586. }
  587. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  588. }
  589. private void RecipeBodyLogTask()
  590. {
  591. taskList.Add(Task.Factory.StartNew(() =>
  592. {
  593. while (true)
  594. {
  595. if (tokenSource.IsCancellationRequested)
  596. {
  597. break;
  598. }
  599. if (RecipeBodyPLC is null)
  600. {
  601. continue;
  602. }
  603. OperateResult<bool> isLampUse = melsec_net.ReadBool(RecipeBodyPLC.ReportFlagAddress);
  604. if (isLampUse.IsSuccess && isLampUse.Content)
  605. {
  606. OperateResult<short[]> recipeBodyRet = melsec_net.ReadInt16(RecipeBodyPLC.PlcItemAddressType + RecipeBodyPLC.PlcItemStartAddress, (ushort)RecipeBodyPLC.PlcItemAddressLength);
  607. List<PlcItemModel> reciprBodyPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == RecipeBodyPLC.PlcItemType).ToList();
  608. if (!recipeBodyRet.IsSuccess || recipeBodyRet.Content.Length <= 0 || reciprBodyPlcItemLst is null || reciprBodyPlcItemLst.Count <= 0)
  609. {
  610. continue;
  611. }
  612. foreach (PlcItemModel plcItem in reciprBodyPlcItemLst)
  613. {
  614. ParsePlcItemData(plcItem, recipeBodyRet.Content, 0);
  615. }
  616. //ToDo:把PLC数据插入到数据库中
  617. RecipeBodyModel axisData = MapPlcItemToObjectProperty<RecipeBodyModel>(reciprBodyPlcItemLst);
  618. axisData.RecordTime = DateTime.Now;
  619. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  620. melsec_net.Write(RecipeBodyPLC.ReplyFlagAddress, true);
  621. }
  622. else
  623. {
  624. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(RecipeBodyPLC.ReplyFlagAddress);
  625. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  626. {
  627. melsec_net.Write(RecipeBodyPLC.ReplyFlagAddress, false);
  628. }
  629. }
  630. Task.Delay(TaskDelayTime).Wait();
  631. }
  632. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  633. }
  634. private void SYSParaLogTask()
  635. {
  636. taskList.Add(Task.Factory.StartNew(() =>
  637. {
  638. while (true)
  639. {
  640. if (tokenSource.IsCancellationRequested)
  641. {
  642. break;
  643. }
  644. if (SYSParaPLC is null)
  645. {
  646. continue;
  647. }
  648. OperateResult<bool> isSysPara = melsec_net.ReadBool(SYSParaPLC.ReportFlagAddress);
  649. if (isSysPara.IsSuccess && isSysPara.Content)
  650. {
  651. OperateResult<short[]> sysParaRet = melsec_net.ReadInt16(SYSParaPLC.PlcItemAddressType + SYSParaPLC.PlcItemStartAddress, (ushort)SYSParaPLC.PlcItemAddressLength);
  652. List<PlcItemModel> sysparaItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == SYSParaPLC.PlcItemType).ToList();
  653. if (!sysParaRet.IsSuccess || sysParaRet.Content.Length <= 0 || sysparaItemLst is null || sysparaItemLst.Count <= 0)
  654. {
  655. continue;
  656. }
  657. foreach (PlcItemModel plcItem in sysparaItemLst)
  658. {
  659. ParsePlcItemData(plcItem, sysParaRet.Content, 0);
  660. }
  661. //ToDo:把PLC数据插入到数据库中
  662. SysParaModel axisData = MapPlcItemToObjectProperty<SysParaModel>(sysparaItemLst);
  663. axisData.RecordTime = DateTime.Now;
  664. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  665. melsec_net.Write(SYSParaPLC.ReplyFlagAddress, true);
  666. }
  667. else
  668. {
  669. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(SYSParaPLC.ReplyFlagAddress);
  670. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  671. {
  672. melsec_net.Write(SYSParaPLC.ReplyFlagAddress, false);
  673. }
  674. }
  675. Task.Delay(TaskDelayTime).Wait();
  676. }
  677. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  678. }
  679. private void RobotInPLCLogTask()
  680. {
  681. taskList.Add(Task.Factory.StartNew(() =>
  682. {
  683. while (true)
  684. {
  685. if (tokenSource.IsCancellationRequested)
  686. {
  687. break;
  688. }
  689. if (RobotInterfaceInPLC is null)
  690. {
  691. continue;
  692. }
  693. OperateResult<bool> isRobotIn = melsec_net.ReadBool(RobotInterfaceInPLC.ReportFlagAddress);
  694. if (isRobotIn.IsSuccess && isRobotIn.Content)
  695. {
  696. OperateResult<short[]> robotInRet = melsec_net.ReadInt16(RobotInterfaceInPLC.PlcItemAddressType + RobotInterfaceInPLC.PlcItemStartAddress, (ushort)RobotInterfaceInPLC.PlcItemAddressLength);
  697. List<PlcItemModel> robotInPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == RobotInterfaceInPLC.PlcItemType).ToList();
  698. if (!robotInRet.IsSuccess || robotInRet.Content.Length <= 0 || robotInPlcItemLst is null || robotInPlcItemLst.Count <= 0)
  699. {
  700. continue;
  701. }
  702. foreach (PlcItemModel plcItem in robotInPlcItemLst)
  703. {
  704. ParsePlcItemData(plcItem, robotInRet.Content, 0);
  705. }
  706. //ToDo:把PLC数据插入到数据库中
  707. RobotInterfaceInModel axisData = MapPlcItemToObjectProperty<RobotInterfaceInModel>(robotInPlcItemLst);
  708. axisData.RecordTime = DateTime.Now;
  709. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  710. melsec_net.Write(RobotInterfaceInPLC.ReplyFlagAddress, true);
  711. }
  712. else
  713. {
  714. OperateResult<bool> isRobotInReply = melsec_net.ReadBool(RobotInterfaceInPLC.ReplyFlagAddress);
  715. if (isRobotInReply.IsSuccess && isRobotInReply.Content)
  716. {
  717. melsec_net.Write(RobotInterfaceInPLC.ReplyFlagAddress, false);
  718. }
  719. }
  720. Task.Delay(TaskDelayTime).Wait();
  721. }
  722. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  723. }
  724. private void RobotOutPLCLogTask()
  725. {
  726. taskList.Add(Task.Factory.StartNew(() =>
  727. {
  728. while (true)
  729. {
  730. if (tokenSource.IsCancellationRequested)
  731. {
  732. break;
  733. }
  734. if (RobotInterfaceOutPLC is null)
  735. {
  736. continue;
  737. }
  738. OperateResult<bool> isRobotOut = melsec_net.ReadBool(RobotInterfaceOutPLC.ReportFlagAddress);
  739. if (isRobotOut.IsSuccess && isRobotOut.Content)
  740. {
  741. OperateResult<short[]> robotInRet = melsec_net.ReadInt16(RobotInterfaceOutPLC.PlcItemAddressType + RobotInterfaceOutPLC.PlcItemStartAddress, (ushort)RobotInterfaceOutPLC.PlcItemAddressLength);
  742. List<PlcItemModel> robotInPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == RobotInterfaceOutPLC.PlcItemType).ToList();
  743. if (!robotInRet.IsSuccess || robotInRet.Content.Length <= 0 || robotInPlcItemLst is null || robotInPlcItemLst.Count <= 0)
  744. {
  745. continue;
  746. }
  747. foreach (PlcItemModel plcItem in robotInPlcItemLst)
  748. {
  749. ParsePlcItemData(plcItem, robotInRet.Content, 0);
  750. }
  751. //ToDo:把PLC数据插入到数据库中
  752. RobotInterfaceOutModel axisData = MapPlcItemToObjectProperty<RobotInterfaceOutModel>(robotInPlcItemLst);
  753. axisData.RecordTime = DateTime.Now;
  754. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  755. melsec_net.Write(RobotInterfaceOutPLC.ReplyFlagAddress, true);
  756. }
  757. else
  758. {
  759. OperateResult<bool> isRobotInReply = melsec_net.ReadBool(RobotInterfaceOutPLC.ReplyFlagAddress);
  760. if (isRobotInReply.IsSuccess && isRobotInReply.Content)
  761. {
  762. melsec_net.Write(RobotInterfaceOutPLC.ReplyFlagAddress, false);
  763. }
  764. }
  765. Task.Delay(TaskDelayTime).Wait();
  766. }
  767. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  768. }
  769. private void YMeasureDataLogTask()
  770. {
  771. taskList.Add(Task.Factory.StartNew(() =>
  772. {
  773. while (true)
  774. {
  775. if (tokenSource.IsCancellationRequested)
  776. {
  777. break;
  778. }
  779. if (YMeasureDataPLC is null)
  780. {
  781. continue;
  782. }
  783. OperateResult<bool> isYMeasure = melsec_net.ReadBool(YMeasureDataPLC.ReportFlagAddress);
  784. if (isYMeasure.IsSuccess && isYMeasure.Content)
  785. {
  786. OperateResult<short[]> yMeasureRet = melsec_net.ReadInt16(YMeasureDataPLC.PlcItemAddressType + YMeasureDataPLC.PlcItemStartAddress, (ushort)YMeasureDataPLC.PlcItemAddressLength);
  787. List<PlcItemModel> glassInfoPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == YMeasureDataPLC.PlcItemType).ToList();
  788. if (!yMeasureRet.IsSuccess || yMeasureRet.Content.Length <= 0 || glassInfoPlcItemLst is null || glassInfoPlcItemLst.Count <= 0)
  789. {
  790. continue;
  791. }
  792. foreach (PlcItemModel plcItem in glassInfoPlcItemLst)
  793. {
  794. ParsePlcItemData(plcItem, yMeasureRet.Content, 0);
  795. }
  796. //ToDo:把PLC数据插入到数据库中
  797. YMeasureDataModel axisData = MapPlcItemToObjectProperty<YMeasureDataModel>(glassInfoPlcItemLst);
  798. axisData.RecordTime = DateTime.Now;
  799. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  800. melsec_net.Write(YMeasureDataPLC.ReplyFlagAddress, true);
  801. }
  802. else
  803. {
  804. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(YMeasureDataPLC.ReplyFlagAddress);
  805. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  806. {
  807. melsec_net.Write(YMeasureDataPLC.ReplyFlagAddress, false);
  808. }
  809. }
  810. Task.Delay(TaskDelayTime).Wait();
  811. }
  812. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  813. }
  814. private void EQPStatusLogTask()
  815. {
  816. taskList.Add(Task.Factory.StartNew(() =>
  817. {
  818. while (true)
  819. {
  820. if (tokenSource.IsCancellationRequested)
  821. {
  822. break;
  823. }
  824. if (EQPStatusPLC is null)
  825. {
  826. continue;
  827. }
  828. OperateResult<bool> isEQPStatus = melsec_net.ReadBool(EQPStatusPLC.ReportFlagAddress);
  829. if (isEQPStatus.IsSuccess && isEQPStatus.Content)
  830. {
  831. OperateResult<short[]> eqpStatusRet = melsec_net.ReadInt16(EQPStatusPLC.PlcItemAddressType + EQPStatusPLC.PlcItemStartAddress, (ushort)EQPStatusPLC.PlcItemAddressLength);
  832. List<PlcItemModel> eqpPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == EQPStatusPLC.PlcItemType).ToList();
  833. if (!eqpStatusRet.IsSuccess || eqpStatusRet.Content.Length <= 0 || eqpPlcItemLst is null || eqpPlcItemLst.Count <= 0)
  834. {
  835. continue;
  836. }
  837. foreach (PlcItemModel plcItem in eqpPlcItemLst)
  838. {
  839. ParsePlcItemData(plcItem, eqpStatusRet.Content, 0);
  840. }
  841. //ToDo:把PLC数据插入到数据库中
  842. EQPStatusModel axisData = MapPlcItemToObjectProperty<EQPStatusModel>(eqpPlcItemLst);
  843. axisData.RecordTime = DateTime.Now;
  844. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  845. melsec_net.Write(EQPStatusPLC.ReplyFlagAddress, true);
  846. }
  847. else
  848. {
  849. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(EQPStatusPLC.ReplyFlagAddress);
  850. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  851. {
  852. melsec_net.Write(EQPStatusPLC.ReplyFlagAddress, false);
  853. }
  854. }
  855. Task.Delay(TaskDelayTime).Wait();
  856. }
  857. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  858. }
  859. private void RecipeCountLogTask()
  860. {
  861. taskList.Add(Task.Factory.StartNew(() =>
  862. {
  863. while (true)
  864. {
  865. if (tokenSource.IsCancellationRequested)
  866. {
  867. break;
  868. }
  869. if (RecipeCountPLC is null)
  870. {
  871. continue;
  872. }
  873. OperateResult<bool> isRecipeCount = melsec_net.ReadBool(RecipeCountPLC.ReportFlagAddress);
  874. if (isRecipeCount.IsSuccess && isRecipeCount.Content)
  875. {
  876. OperateResult<short[]> recipeRet = melsec_net.ReadInt16(RecipeCountPLC.PlcItemAddressType + RecipeCountPLC.PlcItemStartAddress, (ushort)RecipeCountPLC.PlcItemAddressLength);
  877. List<PlcItemModel> recipePlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == RecipeCountPLC.PlcItemType).ToList();
  878. if (!recipeRet.IsSuccess || recipeRet.Content.Length <= 0 || recipePlcItemLst is null || recipePlcItemLst.Count <= 0)
  879. {
  880. continue;
  881. }
  882. foreach (PlcItemModel plcItem in recipePlcItemLst)
  883. {
  884. ParsePlcItemData(plcItem, recipeRet.Content, 0);
  885. }
  886. //ToDo:把PLC数据插入到数据库中
  887. RecipeCountModel axisData = MapPlcItemToObjectProperty<RecipeCountModel>(recipePlcItemLst);
  888. axisData.RecordTime = DateTime.Now;
  889. DbHelper.Db.Insertable(axisData).ExecuteCommand();
  890. melsec_net.Write(RecipeCountPLC.ReplyFlagAddress, true);
  891. }
  892. else
  893. {
  894. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(RecipeCountPLC.ReplyFlagAddress);
  895. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  896. {
  897. melsec_net.Write(RecipeCountPLC.ReplyFlagAddress, false);
  898. }
  899. }
  900. Task.Delay(TaskDelayTime).Wait();
  901. }
  902. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  903. }
  904. private void AnalogDataLogTask()
  905. {
  906. taskList.Add(Task.Factory.StartNew(() =>
  907. {
  908. while (true)
  909. {
  910. if (tokenSource.IsCancellationRequested)
  911. {
  912. break;
  913. }
  914. if (AnalogDataPLC is null)
  915. {
  916. continue;
  917. }
  918. {
  919. List<PlcItemModel> analogPlcItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AnalogDataPLC.PlcItemType).ToList();
  920. foreach(var item in analogPlcItemLst)
  921. {
  922. item.Value= melsec_net.ReadInt16(item.PlcAddr).Content;
  923. }
  924. //foreach (PlcItemModel plcItem in analogPlcItemLst)
  925. //{
  926. // ParsePlcItemData(plcItem, analogDataRet.Content, 0);
  927. //}
  928. //ToDo:把PLC数据插入到数据库中
  929. AnalogDataModel analogData = MapPlcItemToObjectProperty<AnalogDataModel>(analogPlcItemLst);
  930. //几个字段特殊读取
  931. //OperateResult<short> stageMain = melsec_net.ReadInt16("D16640");
  932. //analogData.StageMainCDA= stageMain.Content;
  933. //OperateResult<short> irradiator = melsec_net.ReadInt16("D16642");
  934. //analogData.IrradiatorMainCDA = irradiator.Content;
  935. //OperateResult<short> z1Current = melsec_net.ReadInt16("D16650");
  936. //analogData.Z1Current = z1Current.Content;
  937. //OperateResult<short> z2Current = melsec_net.ReadInt16("D16652");
  938. //analogData.Z2Current = z2Current.Content;
  939. //OperateResult<short> z3Current = melsec_net.ReadInt16("D16654");
  940. //analogData.Z3Current = z3Current.Content;
  941. //OperateResult<short> z4Current = melsec_net.ReadInt16("D16656");
  942. //analogData.Z4Current = z4Current.Content;
  943. analogData.RecordTime = DateTime.Now;
  944. DbHelper.Db.Insertable(analogData).ExecuteCommand();
  945. }
  946. Task.Delay(ReadDelayTime).Wait();
  947. }
  948. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  949. }
  950. private void LampDataLogTask()
  951. {
  952. taskList.Add(Task.Factory.StartNew(() =>
  953. {
  954. while (true)
  955. {
  956. if (tokenSource.IsCancellationRequested)
  957. {
  958. break;
  959. }
  960. if (LampDataPLC is null)
  961. {
  962. continue;
  963. }
  964. {
  965. //OperateResult<short[]> lampDataRet = melsec_net.ReadInt16(LampDataPLC.PlcItemAddressType + LampDataPLC.PlcItemStartAddress, (ushort)AnalogDataPLC.PlcItemAddressLength);
  966. List<PlcItemModel> lampDataItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == LampDataPLC.PlcItemType).ToList();
  967. foreach (var item in lampDataItemLst)
  968. {
  969. item.Value = melsec_net.ReadInt16(item.PlcAddr).Content;
  970. }
  971. //ToDo:把PLC数据插入到数据库中
  972. LampDataModel lampData = MapPlcItemToObjectProperty<LampDataModel>(lampDataItemLst);
  973. //几个字段特殊读取
  974. lampData.RecordTime = DateTime.Now;
  975. DbHelper.Db.Insertable(lampData).ExecuteCommand();
  976. }
  977. Task.Delay(ReadDelayTime).Wait();
  978. }
  979. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  980. }
  981. private void AlarmLogTask()
  982. {
  983. taskList.Add(Task.Factory.StartNew(() =>
  984. {
  985. while (true)
  986. {
  987. if (tokenSource.IsCancellationRequested)
  988. {
  989. break;
  990. }
  991. if (AlarmPLC is null)
  992. {
  993. continue;
  994. }
  995. OperateResult<bool> isAlarm = melsec_net.ReadBool(AlarmPLC.ReportFlagAddress);
  996. if (isAlarm.IsSuccess && isAlarm.Content)
  997. {
  998. OperateResult<short[]> alarmRet = melsec_net.ReadInt16(AlarmPLC.PlcItemAddressType + AlarmPLC.PlcItemStartAddress, (ushort)AlarmPLC.PlcItemAddressLength);
  999. List<PlcItemModel> alarmItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == AlarmPLC.PlcItemType).ToList();
  1000. if (!alarmRet.IsSuccess || alarmRet.Content.Length <= 0 || alarmItemLst is null || alarmItemLst.Count <= 0)
  1001. {
  1002. continue;
  1003. }
  1004. foreach (PlcItemModel plcItem in alarmItemLst)
  1005. {
  1006. ParsePlcItemData(plcItem, alarmRet.Content, 0);
  1007. }
  1008. //ToDo:把PLC数据插入到数据库中
  1009. AlarmModel alarmData = MapPlcItemToObjectProperty<AlarmModel>(alarmItemLst);
  1010. alarmData.AlarmDescribe = deviceAlarm?.FirstOrDefault(x=>x.Key.Trim()==alarmData.AlarmCode.ToString())?.Value;
  1011. alarmData.RecordTime = DateTime.Now;
  1012. DbHelper.Db.Insertable(alarmData).ExecuteCommand();
  1013. melsec_net.Write(AlarmPLC.ReplyFlagAddress, true);
  1014. }
  1015. else
  1016. {
  1017. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(AlarmPLC.ReplyFlagAddress);
  1018. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  1019. {
  1020. melsec_net.Write(AlarmPLC.ReplyFlagAddress, false);
  1021. }
  1022. }
  1023. Task.Delay(TaskDelayTime).Wait();
  1024. }
  1025. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  1026. }
  1027. private void WarnLogTask()
  1028. {
  1029. taskList.Add(Task.Factory.StartNew(() =>
  1030. {
  1031. while (true)
  1032. {
  1033. if (tokenSource.IsCancellationRequested)
  1034. {
  1035. break;
  1036. }
  1037. if (WarnPLC is null)
  1038. {
  1039. continue;
  1040. }
  1041. OperateResult<bool> isLampUse = melsec_net.ReadBool(WarnPLC.ReportFlagAddress);
  1042. if (isLampUse.IsSuccess && isLampUse.Content)
  1043. {
  1044. OperateResult<short[]> warnRet = melsec_net.ReadInt16(WarnPLC.PlcItemAddressType + WarnPLC.PlcItemStartAddress, (ushort)WarnPLC.PlcItemAddressLength);
  1045. List<PlcItemModel> warnItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == WarnPLC.PlcItemType).ToList();
  1046. if (!warnRet.IsSuccess || warnRet.Content.Length <= 0 || warnItemLst is null || warnItemLst.Count <= 0)
  1047. {
  1048. continue;
  1049. }
  1050. foreach (PlcItemModel plcItem in warnItemLst)
  1051. {
  1052. ParsePlcItemData(plcItem, warnRet.Content, 0);
  1053. }
  1054. //ToDo:把PLC数据插入到数据库中
  1055. WarnModel warnData = MapPlcItemToObjectProperty<WarnModel>(warnItemLst);
  1056. warnData.WarnDescribe = deviceWarn?.FirstOrDefault(x => x.Key.Trim() == warnData.WarnCode.ToString())?.Value;
  1057. warnData.RecordTime = DateTime.Now;
  1058. DbHelper.Db.Insertable(warnData).ExecuteCommand();
  1059. melsec_net.Write(WarnPLC.ReplyFlagAddress, true);
  1060. }
  1061. else
  1062. {
  1063. OperateResult<bool> isJobEventReply = melsec_net.ReadBool(WarnPLC.ReplyFlagAddress);
  1064. if (isJobEventReply.IsSuccess && isJobEventReply.Content)
  1065. {
  1066. melsec_net.Write(WarnPLC.ReplyFlagAddress, false);
  1067. }
  1068. }
  1069. Task.Delay(TaskDelayTime).Wait();
  1070. }
  1071. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  1072. }
  1073. private void IOLogTask()
  1074. {
  1075. List<IONewModel> ioNewModelList = new List<IONewModel>();
  1076. DateTime recordTime;
  1077. taskList.Add(Task.Factory.StartNew(() =>
  1078. {
  1079. while (true)
  1080. {
  1081. if (tokenSource.IsCancellationRequested)
  1082. {
  1083. break;
  1084. }
  1085. if (IOPLC is null)
  1086. {
  1087. continue;
  1088. }
  1089. {
  1090. OperateResult<short[]> ioRet = melsec_net.ReadInt16(IOPLC.PlcItemAddressType + IOPLC.PlcItemStartAddress, (ushort)IOPLC.PlcItemAddressLength);
  1091. List<PlcItemModel> ioItemLst = DbHelper.Db.Queryable<PlcItemModel>().Where(x => x.PlcItemType == IOPLC.PlcItemType).ToList();
  1092. if (!ioRet.IsSuccess || ioRet.Content.Length <= 0 || ioItemLst is null || ioItemLst.Count <= 0)
  1093. {
  1094. continue;
  1095. }
  1096. recordTime = DateTime.Now;
  1097. ioNewModelList.Clear();
  1098. foreach (PlcItemModel plcItem in ioItemLst)
  1099. {
  1100. ParsePlcItemData(plcItem, ioRet.Content, 0);
  1101. //转化为
  1102. IONewModel ioNewModel = new IONewModel();
  1103. ioNewModel.IOName = plcItem.PlcItemCode;
  1104. if (plcItem.PlcItemCode.Contains("Stage"))
  1105. {
  1106. ioNewModel.IOType = "Stage";
  1107. }
  1108. else
  1109. {
  1110. if (plcItem.PlcItemCode.Contains("IrradiatorInput"))
  1111. {
  1112. ioNewModel.IOType = "IrradiatorInput";
  1113. }
  1114. else
  1115. {
  1116. if (plcItem.PlcItemCode.Contains("IrradiatorOutput"))
  1117. {
  1118. ioNewModel.IOType = "IrradiatorOutput";
  1119. }
  1120. }
  1121. }
  1122. ioNewModel.IOValue = Convert.ToInt32(plcItem.Value);
  1123. ioNewModel.RecordTime = recordTime;
  1124. ioNewModelList.Add(ioNewModel);
  1125. }
  1126. //ToDo:把PLC数据插入到数据库中
  1127. DbHelper.Db.Insertable(ioNewModelList).ExecuteCommand();
  1128. }
  1129. Task.Delay(500).Wait();
  1130. }
  1131. }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
  1132. }
  1133. private void ParsePlcItemData(PlcItemModel plcItem, short[] retLst, int startIndex)
  1134. {
  1135. if (plcItem.PlcItemFormat == 0) // 解析为int类型
  1136. {
  1137. if (plcItem.IsFullWord == 1) // 全字解析,不进行二进制拆分
  1138. {
  1139. short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray();
  1140. if (plcItem.WordSize == 1)
  1141. {
  1142. plcItem.Value = tmpVal[0];
  1143. }
  1144. else if (plcItem.WordSize == 2)
  1145. {
  1146. plcItem.Value = (tmpVal[0] << 16) + tmpVal[1];
  1147. }
  1148. }
  1149. else // 非全字解析,需要对数据进行二进制拆分,根据具体的二进制位数,进行数据转换。
  1150. {
  1151. short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray();
  1152. string binStr = string.Empty;
  1153. for (int j = 0; j < tmpVal.Length; j++)
  1154. {
  1155. binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse());
  1156. }
  1157. string retStr = string.Concat(binStr.Skip(plcItem.BinSubOffset).Take(plcItem.BinSize).ToArray().Reverse());
  1158. plcItem.Value = Convert.ToInt32(retStr, 2);
  1159. }
  1160. }
  1161. else if (plcItem.PlcItemFormat == 1) // 解析为ASCII码字符串, 数据直接转换为对应的ASCII码字符串数据进行存储
  1162. {
  1163. short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray();
  1164. List<byte> bytes = new();
  1165. for (int j = 0; j < plcItem.WordSize; j++)
  1166. {
  1167. //bytes.AddRange(BitConverter.GetBytes(tmpVal[j]));
  1168. bytes.Add((byte)tmpVal[j]);
  1169. }
  1170. ASCIIEncoding asciiMd = new();
  1171. //Console.WriteLine(BitConverter.ToString(bytes.ToArray()));
  1172. char[] ascii = asciiMd.GetChars(bytes.ToArray());
  1173. string retStr = string.Empty;
  1174. for (int j = 0; j < bytes.Count; j++)
  1175. {
  1176. retStr += ascii[j];
  1177. }
  1178. plcItem.Value = retStr;
  1179. }
  1180. else if (plcItem.PlcItemFormat == 2) // 解析为二进制数据,按照二进制具体位置和位数,重新组装数据
  1181. {
  1182. if (plcItem.IsFullWord == 1) // 全字解析 , 直接存储数据的二进制字符串
  1183. {
  1184. short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray();
  1185. string binStr = string.Empty;
  1186. for (int j = 0; j < tmpVal.Length; j++)
  1187. {
  1188. binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse());
  1189. }
  1190. plcItem.Value = binStr;
  1191. }
  1192. else // 非全字解析 按照二进制具体位置和位数,存储相应的二进制字符串
  1193. {
  1194. short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray();
  1195. string binStr = string.Empty;
  1196. for (int j = 0; j < tmpVal.Length; j++)
  1197. {
  1198. binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse());
  1199. }
  1200. string retStr = string.Concat(binStr.Skip(plcItem.BinSubOffset).Take(plcItem.BinSize).ToArray().Reverse());
  1201. plcItem.Value = retStr;
  1202. }
  1203. }
  1204. }
  1205. /// <summary>
  1206. /// 根据解析出来的PLC点位数据,创建对应的数据库实体对象。
  1207. /// </summary>
  1208. /// <typeparam name="T">对应的数据库实体对象</typeparam>
  1209. /// <param name="plcItemLst">解析出来的PLC点位数据</param>
  1210. /// <returns></returns>
  1211. private static T MapPlcItemToObjectProperty<T>(List<PlcItemModel> plcItemLst) where T : class, new()
  1212. {
  1213. T tmp = new();
  1214. PropertyInfo[] propertys = tmp.GetType().GetProperties();
  1215. foreach (PropertyInfo property in propertys)
  1216. {
  1217. foreach (PlcItemModel item in plcItemLst)
  1218. {
  1219. if (property.Name == item.PlcItemCode)
  1220. {
  1221. if (property.PropertyType.FullName == typeof(DateTime).FullName)
  1222. {
  1223. property.SetValue(tmp, item.Value is null ? new DateTime() : Convert.ToDateTime(item.Value), null);
  1224. }
  1225. else if (property.PropertyType.FullName == typeof(int).FullName)
  1226. {
  1227. property.SetValue(tmp, item.Value is null ? 0 : Convert.ToInt32(item.Value), null);
  1228. }
  1229. else if (property.PropertyType.FullName == typeof(decimal).FullName)
  1230. {
  1231. property.SetValue(tmp, item.Value is null ? 0 : Convert.ToDecimal(item.Value), null);
  1232. }
  1233. else if (property.PropertyType.FullName == typeof(string).FullName)
  1234. {
  1235. property.SetValue(tmp, item.Value is null ? null : item.Value.ToString(), null);
  1236. }
  1237. else if (property.PropertyType.FullName == typeof(bool).FullName || property.PropertyType.FullName == typeof(bool).FullName)
  1238. {
  1239. //property.SetValue(tmp, item.Value is null ? false : Convert.ToBoolean(item.Value), null);
  1240. //VS编辑器建议的简化写法。 非常巧妙!!!!!!
  1241. property.SetValue(tmp, item.Value is not null && Convert.ToBoolean(item.Value), null);
  1242. }
  1243. else if (property.PropertyType.BaseType.FullName == typeof(byte[]).FullName)
  1244. {
  1245. property.SetValue(tmp, item.Value is null ? null : item.Value, null);
  1246. }
  1247. else if (property.PropertyType.BaseType.FullName == typeof(Enum).FullName)
  1248. {
  1249. property.SetValue(tmp, Enum.Parse(property.PropertyType, (item.Value ?? 0).ToString()), null);
  1250. }
  1251. else
  1252. {
  1253. property.SetValue(tmp, item.Value, null);
  1254. }
  1255. break;
  1256. }
  1257. }
  1258. }
  1259. return tmp;
  1260. }
  1261. private Dictionary<string, int> GetNonZeroProperties(object obj)
  1262. {
  1263. Dictionary<string, int> nonZeroProperties = new Dictionary<string, int>();
  1264. PropertyInfo[] properties = obj.GetType().GetProperties();
  1265. foreach (PropertyInfo property in properties)
  1266. {
  1267. if (property.PropertyType == typeof(int))
  1268. {
  1269. int value = (int)property.GetValue(obj);
  1270. if (value != 0)
  1271. {
  1272. nonZeroProperties.Add(property.Name, value);
  1273. }
  1274. }
  1275. }
  1276. return nonZeroProperties;
  1277. }
  1278. // 将8位BCD码转化为整数
  1279. private int BCDToInt(byte bcdValue)
  1280. {
  1281. int result = 0;
  1282. int multiplier = 1;
  1283. while (bcdValue > 0)
  1284. {
  1285. int digit = bcdValue & 0xF;
  1286. result += digit * multiplier;
  1287. bcdValue >>= 4;
  1288. multiplier *= 10;
  1289. }
  1290. return result;
  1291. }
  1292. // 将16位BCD码转化为两个整数
  1293. private void Convert16BitBCDToTwoInts(short bcdValue, out int int1, out int int2)
  1294. {
  1295. // 高8位BCD码
  1296. byte highByte = (byte)((bcdValue >> 8) & 0xFF);
  1297. // 低8位BCD码
  1298. byte lowByte = (byte)(bcdValue & 0xFF);
  1299. // 分别转换高8位和低8位
  1300. int1 = BCDToInt(highByte);
  1301. int2 = BCDToInt(lowByte);
  1302. }
  1303. #endregion
  1304. }
  1305. }