DataCollectionSysyem.cs 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646
  1. using System.Collections.Concurrent;
  2. using System.ComponentModel;
  3. using PlcSiemens.Core.Extension;
  4. using ServiceCenter.Extensions;
  5. using ServiceCenter.Logs;
  6. using ServiceCenter.SqlSugars;
  7. using SqlSugar;
  8. using WCS.Core;
  9. using WCS.Entity.Protocol.DataStructure;
  10. using WCS.Entity.Protocol.HUB;
  11. using WCS.Entity.Protocol.RGV;
  12. using WCS.Entity.Protocol.Robot;
  13. using WCS.Entity.Protocol.SRM;
  14. using WCS.Entity.Protocol.Station;
  15. using WCS.Entity.Protocol.Truss;
  16. using WCS.WorkEngineering.Worlds;
  17. namespace WCS.WorkEngineering.Systems;
  18. /// <summary>
  19. /// 数据处理系统
  20. /// </summary>
  21. [BelongTo(typeof(MainWorld))]
  22. [Description("数据处理系统")]
  23. public class DataCollectionSysyem : DeviceSystem<Device<IStation520>>
  24. {
  25. public static DeviceDataPack pack = new();
  26. private static object locker = new();
  27. /// <summary>
  28. /// 所有设备数据
  29. /// Key 是不同设备所使用的类型 例如DeviceDataCollection
  30. /// <SRMData>
  31. /// value 不同设备的具体数据
  32. /// </summary>
  33. public static ConcurrentDictionary<string, DeviceData> AllDatas = new();
  34. protected override bool ParallelDo => true;
  35. public override bool Select(Device dev)
  36. {
  37. return dev.Code == "1";
  38. }
  39. public override void Do(Device<IStation520> objDev)
  40. {
  41. //通过数据条数处理
  42. var db = new SqlSugarHelper().PLC;
  43. var plcEx = new SqlSugarHelper().PLCEX;
  44. ExRobotRunInfo(db, plcEx);
  45. ExSrmRunInfo(db, plcEx);
  46. ExRgvRunInfo(db, plcEx);
  47. ExTrussRunInfo(db, plcEx);
  48. //ExRobotAlarmInfo(db, plcEx);
  49. //ExSrmAlarmInfo(db, plcEx);
  50. //ExRgvAlarmInfo(db, plcEx);
  51. //ExTrussAlarmInfo(db, plcEx);
  52. ExRobotTaskSumRunInfo(db, plcEx);
  53. ExTrussTaskSumRunInfo(db, plcEx);
  54. SummarizeInboundMaterialByRegion(db, plcEx);
  55. }
  56. /// <summary>
  57. /// 汇总并分析南北区域的来料数量。
  58. /// </summary>
  59. /// <param name="db"></param>
  60. public void SummarizeInboundMaterialByRegion(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  61. {
  62. try
  63. {
  64. var startTime = DateTime.Now;
  65. var endTime = DateTime.Now;
  66. IEnumerable<IGrouping<string, WCS_Station5>> station5 = new List<IGrouping<string, WCS_Station5>>();
  67. var type = DevType.FeedRate.ToString();
  68. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  69. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  70. {
  71. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  72. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type)
  73. .OrderByDescending(x => x.Frame).First();
  74. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  75. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0,
  76. 0); //后一个小时的开始时间
  77. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  78. }
  79. else
  80. {
  81. if (db.Queryable<WCS_Station5>().Count() <= 0) return;
  82. startTime = db.Queryable<WCS_Station5>().OrderBy(x => x.Frame).First().Frame;
  83. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0,
  84. 0); //后一个小时的开始时间
  85. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  86. }
  87. //取上一小时的第一秒
  88. var now = DateTime.Now;
  89. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  90. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  91. //当前时间之前
  92. if (endTime > now) throw new KnownException("当前时间之前", LogLevelEnum.High);
  93. //是当前这一个小时
  94. if (nowEndTime == now) throw new KnownException("是当前这一个小时", LogLevelEnum.High);
  95. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0);
  96. // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  97. if (DateTime.Now < now)
  98. throw new KnownException("每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理", LogLevelEnum.High);
  99. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type))
  100. throw new KnownException("当前小时有数据", LogLevelEnum.High);
  101. station5 = db.Queryable<WCS_Station5>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  102. .GroupBy(x => x.Code).ToList();
  103. if (!station5.Any())
  104. plcEx.Insertable(new DevRunInfo
  105. {
  106. Frame = endTime,
  107. Code = "当前时段无有效数据",
  108. RunMode = "当前时段无有效数据",
  109. RunStatus = "当前时段无有效数据",
  110. StartTime = startTime,
  111. EndTime = endTime,
  112. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  113. Type = type
  114. }).ExecuteCommand();
  115. foreach (var infos in station5)
  116. {
  117. var infoList = infos.SelectMany(FeedRateMethod).ToList().GroupBy(x => x.Day);
  118. var feedRateList = new List<DevRunInfo?>();
  119. //获取每一分钟最大的数据
  120. infoList.ForEach(day =>
  121. {
  122. day.GroupBy(x => x.Hour).ForEach(hour =>
  123. {
  124. hour.GroupBy(x => x.Minute).ForEach(minute =>
  125. {
  126. var feedRate = minute.MaxBy(x => x.Number);
  127. feedRateList.Add(new DevRunInfo
  128. {
  129. Frame = feedRate.Frame,
  130. Code = feedRate.Code,
  131. RunMode = $"{feedRate.Day} {feedRate.Hour}:{feedRate.Minute}",
  132. RunStatus = feedRate.Number.ToString(),
  133. Duration = 0,
  134. Type = type
  135. });
  136. });
  137. });
  138. });
  139. if (!feedRateList.Any())
  140. {
  141. plcEx.Insertable(new DevRunInfo
  142. {
  143. Frame = endTime,
  144. Code = infos.Key,
  145. RunMode = "当前时段无有效数据",
  146. RunStatus = "当前时段无有效数据",
  147. StartTime = startTime,
  148. EndTime = endTime,
  149. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  150. Type = type
  151. }).ExecuteCommand();
  152. continue;
  153. }
  154. var sql = plcEx.Insertable(feedRateList).ToSqlString();
  155. plcEx.Ado.ExecuteCommand(GetString(sql));
  156. }
  157. }
  158. catch (Exception e)
  159. {
  160. Console.WriteLine(e);
  161. throw new KnownException($"{e.Message}:{e.StackTrace}", LogLevelEnum.High);
  162. }
  163. }
  164. public List<FeedRateDto> FeedRateMethod(WCS_Station5 st)
  165. {
  166. List<FeedRateDto> res =
  167. [
  168. new(st.Day0, st.Hour0, st.Minute0, st.Number0, st.Frame, st.Code),
  169. new(st.Day1, st.Hour1, st.Minute1, st.Number1, st.Frame, st.Code),
  170. new(st.Day2, st.Hour2, st.Minute2, st.Number2, st.Frame, st.Code),
  171. new(st.Day3, st.Hour3, st.Minute3, st.Number3, st.Frame, st.Code),
  172. new(st.Day4, st.Hour4, st.Minute4, st.Number4, st.Frame, st.Code),
  173. new(st.Day5, st.Hour5, st.Minute5, st.Number5, st.Frame, st.Code),
  174. new(st.Day6, st.Hour6, st.Minute6, st.Number6, st.Frame, st.Code),
  175. new(st.Day7, st.Hour7, st.Minute7, st.Number7, st.Frame, st.Code),
  176. new(st.Day8, st.Hour8, st.Minute8, st.Number8, st.Frame, st.Code),
  177. new(st.Day9, st.Hour9, st.Minute9, st.Number9, st.Frame, st.Code),
  178. new(st.Day10, st.Hour10, st.Minute10, st.Number10, st.Frame, st.Code),
  179. new(st.Day11, st.Hour11, st.Minute11, st.Number11, st.Frame, st.Code),
  180. new(st.Day12, st.Hour12, st.Minute12, st.Number12, st.Frame, st.Code),
  181. new(st.Day13, st.Hour13, st.Minute13, st.Number13, st.Frame, st.Code),
  182. new(st.Day14, st.Hour14, st.Minute14, st.Number14, st.Frame, st.Code),
  183. new(st.Day15, st.Hour15, st.Minute15, st.Number15, st.Frame, st.Code),
  184. new(st.Day16, st.Hour16, st.Minute16, st.Number16, st.Frame, st.Code),
  185. new(st.Day17, st.Hour17, st.Minute17, st.Number17, st.Frame, st.Code),
  186. new(st.Day18, st.Hour18, st.Minute18, st.Number18, st.Frame, st.Code),
  187. new(st.Day19, st.Hour19, st.Minute19, st.Number19, st.Frame, st.Code),
  188. new(st.Day20, st.Hour20, st.Minute20, st.Number20, st.Frame, st.Code),
  189. new(st.Day21, st.Hour21, st.Minute21, st.Number21, st.Frame, st.Code),
  190. new(st.Day22, st.Hour22, st.Minute22, st.Number22, st.Frame, st.Code),
  191. new(st.Day23, st.Hour23, st.Minute23, st.Number23, st.Frame, st.Code),
  192. new(st.Day24, st.Hour24, st.Minute24, st.Number24, st.Frame, st.Code),
  193. new(st.Day25, st.Hour25, st.Minute25, st.Number25, st.Frame, st.Code),
  194. new(st.Day26, st.Hour26, st.Minute26, st.Number26, st.Frame, st.Code),
  195. new(st.Day27, st.Hour27, st.Minute27, st.Number27, st.Frame, st.Code),
  196. new(st.Day28, st.Hour28, st.Minute28, st.Number28, st.Frame, st.Code),
  197. new(st.Day29, st.Hour29, st.Minute29, st.Number29, st.Frame, st.Code),
  198. new(st.Day30, st.Hour30, st.Minute30, st.Number30, st.Frame, st.Code),
  199. new(st.Day31, st.Hour31, st.Minute31, st.Number31, st.Frame, st.Code),
  200. new(st.Day32, st.Hour32, st.Minute32, st.Number32, st.Frame, st.Code),
  201. new(st.Day33, st.Hour33, st.Minute33, st.Number33, st.Frame, st.Code),
  202. new(st.Day34, st.Hour34, st.Minute34, st.Number34, st.Frame, st.Code),
  203. new(st.Day35, st.Hour35, st.Minute35, st.Number35, st.Frame, st.Code),
  204. new(st.Day36, st.Hour36, st.Minute36, st.Number36, st.Frame, st.Code),
  205. new(st.Day37, st.Hour37, st.Minute37, st.Number37, st.Frame, st.Code),
  206. new(st.Day38, st.Hour38, st.Minute38, st.Number38, st.Frame, st.Code),
  207. new(st.Day39, st.Hour39, st.Minute39, st.Number39, st.Frame, st.Code),
  208. new(st.Day40, st.Hour40, st.Minute40, st.Number40, st.Frame, st.Code),
  209. new(st.Day41, st.Hour41, st.Minute41, st.Number41, st.Frame, st.Code),
  210. new(st.Day42, st.Hour42, st.Minute42, st.Number42, st.Frame, st.Code),
  211. new(st.Day43, st.Hour43, st.Minute43, st.Number43, st.Frame, st.Code),
  212. new(st.Day44, st.Hour44, st.Minute44, st.Number44, st.Frame, st.Code),
  213. new(st.Day45, st.Hour45, st.Minute45, st.Number45, st.Frame, st.Code),
  214. new(st.Day46, st.Hour46, st.Minute46, st.Number46, st.Frame, st.Code),
  215. new(st.Day47, st.Hour47, st.Minute47, st.Number47, st.Frame, st.Code),
  216. new(st.Day48, st.Hour48, st.Minute48, st.Number48, st.Frame, st.Code),
  217. new(st.Day49, st.Hour49, st.Minute49, st.Number49, st.Frame, st.Code),
  218. new(st.Day50, st.Hour50, st.Minute50, st.Number50, st.Frame, st.Code),
  219. new(st.Day51, st.Hour51, st.Minute51, st.Number51, st.Frame, st.Code),
  220. new(st.Day52, st.Hour52, st.Minute52, st.Number52, st.Frame, st.Code),
  221. new(st.Day53, st.Hour53, st.Minute53, st.Number53, st.Frame, st.Code),
  222. new(st.Day54, st.Hour54, st.Minute54, st.Number54, st.Frame, st.Code),
  223. new(st.Day55, st.Hour55, st.Minute55, st.Number55, st.Frame, st.Code),
  224. new(st.Day56, st.Hour56, st.Minute56, st.Number56, st.Frame, st.Code),
  225. new(st.Day57, st.Hour57, st.Minute57, st.Number57, st.Frame, st.Code),
  226. new(st.Day58, st.Hour58, st.Minute58, st.Number58, st.Frame, st.Code),
  227. new(st.Day59, st.Hour59, st.Minute59, st.Number59, st.Frame, st.Code)
  228. ];
  229. return res;
  230. }
  231. public string GetString(string value)
  232. {
  233. return value.Replace(",N'", ",'")
  234. .Replace("\0", "")
  235. .Replace("(N'", "('") + "\r";
  236. }
  237. #region 设备运行信息收集
  238. /// <summary>
  239. /// 机械臂
  240. /// </summary>
  241. /// <param name="db"></param>
  242. public void ExRobotRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  243. {
  244. var startTime = DateTime.Now;
  245. var endTime = DateTime.Now;
  246. IEnumerable<IGrouping<string, WCS_Robot521>> robot521 = new List<IGrouping<string, WCS_Robot521>>();
  247. var type = DevType.Robot.ToString();
  248. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  249. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  250. {
  251. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  252. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  253. .First();
  254. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  255. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  256. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  257. }
  258. else
  259. {
  260. if (db.Queryable<WCS_Robot521>().Count() <= 0) return;
  261. startTime = db.Queryable<WCS_Robot521>().OrderBy(x => x.Frame).First().Frame;
  262. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  263. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  264. }
  265. //取上一小时的第一秒
  266. var now = DateTime.Now;
  267. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  268. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  269. if (endTime > now) return; //当前时间之前
  270. if (nowEndTime == now) return; //是当前这一个小时
  271. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0);
  272. if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  273. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  274. var sqls = db.Queryable<WCS_Robot521>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToSqlString();
  275. var aaa = db.Ado.GetDataTable(sqls);
  276. robot521 = db.Queryable<WCS_Robot521>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  277. .GroupBy(x => x.Code).ToList();
  278. if (!robot521.Any())
  279. plcEx.Insertable(new DevRunInfo
  280. {
  281. Frame = endTime,
  282. Code = "当前时段无有效数据",
  283. RunMode = "当前时段无有效数据",
  284. RunStatus = "当前时段无有效数据",
  285. StartTime = startTime,
  286. EndTime = endTime,
  287. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  288. Type = type
  289. }).ExecuteCommand();
  290. foreach (var infos in robot521)
  291. {
  292. // 获取第一条数据与最后一条数据
  293. var start = infos.OrderBy(x => x.Frame).First();
  294. var end = infos.OrderByDescending(x => x.Frame).First();
  295. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  296. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  297. //获取前一天最后的一条数据
  298. var yesterEnd = plcEx.Queryable<DevRunInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  299. .OrderByDescending(x => x.Frame).First();
  300. var runInfos = new List<DevRunInfo>();
  301. foreach (var info in infos)
  302. if (info.Frame == start.Frame) //当天的第一条数据
  303. {
  304. if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算
  305. runInfos.Add(new DevRunInfo
  306. {
  307. Frame = info.Frame,
  308. Code = info.Code,
  309. RunMode = info.RobotMode.GetDescription(),
  310. RunStatus = info.RunStatus.GetDescription(),
  311. StartTime = startTime,
  312. EndTime = info.Frame,
  313. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  314. Type = type
  315. });
  316. else //如果有就用前一天的最后一条数据做计算
  317. runInfos.Add(new DevRunInfo
  318. {
  319. Frame = info.Frame,
  320. Code = info.Code,
  321. RunMode = yesterEnd.RunMode,
  322. RunStatus = yesterEnd.RunStatus,
  323. StartTime = startTime,
  324. EndTime = info.Frame,
  325. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  326. Type = type
  327. });
  328. }
  329. else //状态出现状态变化时或最后一条数据
  330. {
  331. if (start.RobotMode != info.RobotMode || start.RunStatus != info.RunStatus ||
  332. info.Frame == end.Frame)
  333. {
  334. var runInfo = new DevRunInfo
  335. {
  336. Frame = info.Frame,
  337. Code = info.Code,
  338. RunMode = start.RobotMode.GetDescription(),
  339. RunStatus = start.RunStatus.GetDescription(),
  340. StartTime = start.Frame,
  341. Type = type
  342. };
  343. if (info.Frame == end.Frame) runInfo.EndTime = endTime;
  344. else runInfo.EndTime = info.Frame;
  345. runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds);
  346. runInfos.Add(runInfo);
  347. start = info;
  348. }
  349. }
  350. var sql = plcEx.Insertable(runInfos).ToSqlString();
  351. plcEx.Ado.ExecuteCommand(GetString(sql));
  352. }
  353. }
  354. /// <summary>
  355. /// 堆垛机
  356. /// </summary>
  357. /// <param name="db"></param>
  358. public void ExSrmRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  359. {
  360. var startTime = DateTime.Now;
  361. var endTime = DateTime.Now;
  362. IEnumerable<IGrouping<string, WCS_SRM521>> srm521 = new List<IGrouping<string, WCS_SRM521>>();
  363. var type = DevType.SRM.ToString();
  364. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  365. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  366. {
  367. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  368. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  369. .First();
  370. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  371. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  372. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  373. }
  374. else
  375. {
  376. if (db.Queryable<WCS_SRM521>().Count() <= 0) return;
  377. startTime = db.Queryable<WCS_SRM521>().OrderBy(x => x.Frame).First().Frame;
  378. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  379. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  380. }
  381. //取上一小时的第一秒
  382. var now = DateTime.Now;
  383. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  384. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  385. if (endTime > now) return; //当前时间之前
  386. if (nowEndTime == now) return; //是当前这一个小时
  387. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0);
  388. if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  389. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  390. srm521 = db.Queryable<WCS_SRM521>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  391. .GroupBy(x => x.Code).ToList();
  392. if (!srm521.Any())
  393. plcEx.Insertable(new DevRunInfo
  394. {
  395. Frame = endTime,
  396. Code = "当前时段无有效数据",
  397. RunMode = "当前时段无有效数据",
  398. RunStatus = "当前时段无有效数据",
  399. StartTime = startTime,
  400. EndTime = endTime,
  401. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  402. Type = type
  403. }).ExecuteCommand();
  404. foreach (var infos in srm521)
  405. {
  406. // 获取第一条数据与最后一条数据
  407. var start = infos.OrderBy(x => x.Frame).First();
  408. var end = infos.OrderByDescending(x => x.Frame).First();
  409. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  410. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  411. //获取前一天最后的一条数据
  412. var yesterEnd = plcEx.Queryable<DevRunInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  413. .OrderByDescending(x => x.Frame).First();
  414. var runInfos = new List<DevRunInfo>();
  415. foreach (var info in infos.OrderBy(x => x.Frame))
  416. if (info.Frame == start.Frame) //当天的第一条数据
  417. {
  418. if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算
  419. runInfos.Add(new DevRunInfo
  420. {
  421. Frame = info.Frame,
  422. Code = info.Code,
  423. RunMode = info.AutoStatus.GetDescription(),
  424. RunStatus = info.RunStatus.GetDescription(),
  425. StartTime = startTime,
  426. EndTime = info.Frame,
  427. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  428. Type = type
  429. });
  430. else //如果有就用前一天的最后一条数据做计算
  431. runInfos.Add(new DevRunInfo
  432. {
  433. Frame = info.Frame,
  434. Code = info.Code,
  435. RunMode = yesterEnd.RunMode,
  436. RunStatus = yesterEnd.RunStatus,
  437. StartTime = startTime,
  438. EndTime = info.Frame,
  439. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  440. Type = type
  441. });
  442. }
  443. else //状态出现状态变化时或最后一条数据
  444. {
  445. if (start.AutoStatus != info.AutoStatus || start.RunStatus != info.RunStatus ||
  446. info.Frame == end.Frame)
  447. {
  448. var runInfo = new DevRunInfo
  449. {
  450. Frame = info.Frame,
  451. Code = info.Code,
  452. RunMode = start.AutoStatus.GetDescription(),
  453. RunStatus = start.RunStatus.GetDescription(),
  454. StartTime = start.Frame,
  455. Type = type
  456. };
  457. if (info.Frame == end.Frame) runInfo.EndTime = endTime;
  458. else runInfo.EndTime = info.Frame;
  459. runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds);
  460. runInfos.Add(runInfo);
  461. start = info;
  462. }
  463. }
  464. var sql = plcEx.Insertable(runInfos).ToSqlString();
  465. plcEx.Ado.ExecuteCommand(GetString(sql));
  466. }
  467. }
  468. /// <summary>
  469. /// rgv
  470. /// </summary>
  471. /// <param name="db"></param>
  472. public void ExRgvRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  473. {
  474. var startTime = DateTime.Now;
  475. var endTime = DateTime.Now;
  476. IEnumerable<IGrouping<string, WCS_RGV521>> rgv521 = new List<IGrouping<string, WCS_RGV521>>();
  477. var type = DevType.RGV.ToString();
  478. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  479. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  480. {
  481. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  482. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  483. .First();
  484. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  485. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  486. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  487. }
  488. else
  489. {
  490. if (db.Queryable<WCS_RGV521>().Count() <= 0) return;
  491. startTime = db.Queryable<WCS_RGV521>().OrderBy(x => x.Frame).First().Frame;
  492. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  493. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  494. }
  495. //取上一小时的第一秒
  496. var now = DateTime.Now;
  497. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  498. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  499. if (endTime > now) return; //当前时间之前
  500. if (nowEndTime == now) return; //是当前这一个小时
  501. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0);
  502. if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  503. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  504. rgv521 = db.Queryable<WCS_RGV521>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  505. .GroupBy(x => x.Code).ToList();
  506. if (!rgv521.Any())
  507. plcEx.Insertable(new DevRunInfo
  508. {
  509. Frame = endTime,
  510. Code = "当前时段无有效数据",
  511. RunMode = "当前时段无有效数据",
  512. RunStatus = "当前时段无有效数据",
  513. StartTime = startTime,
  514. EndTime = endTime,
  515. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  516. Type = type
  517. }).ExecuteCommand();
  518. foreach (var infos in rgv521)
  519. {
  520. // 获取第一条数据与最后一条数据
  521. var start = infos.OrderBy(x => x.Frame).First();
  522. var end = infos.OrderByDescending(x => x.Frame).First();
  523. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  524. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  525. //获取前一天最后的一条数据
  526. var yesterEnd = plcEx.Queryable<DevRunInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  527. .OrderByDescending(x => x.Frame).First();
  528. var runInfos = new List<DevRunInfo>();
  529. foreach (var info in infos.OrderBy(x => x.Frame))
  530. if (info.Frame == start.Frame) //当天的第一条数据
  531. {
  532. if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算
  533. runInfos.Add(new DevRunInfo
  534. {
  535. Frame = info.Frame,
  536. Code = info.Code,
  537. RunMode = info.WorkMode.GetDescription(),
  538. RunStatus = info.SystemStatus.GetDescription(),
  539. StartTime = startTime,
  540. EndTime = info.Frame,
  541. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  542. Type = type
  543. });
  544. else //如果有就用前一天的最后一条数据做计算
  545. runInfos.Add(new DevRunInfo
  546. {
  547. Frame = info.Frame,
  548. Code = info.Code,
  549. RunMode = yesterEnd.RunMode,
  550. RunStatus = yesterEnd.RunStatus,
  551. StartTime = startTime,
  552. EndTime = info.Frame,
  553. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  554. Type = type
  555. });
  556. }
  557. else //状态出现状态变化时或最后一条数据
  558. {
  559. if (start.WorkMode != info.WorkMode || start.SystemStatus != info.SystemStatus ||
  560. info.Frame == end.Frame)
  561. {
  562. var runInfo = new DevRunInfo
  563. {
  564. Frame = info.Frame,
  565. Code = info.Code,
  566. RunMode = start.WorkMode.GetDescription(),
  567. RunStatus = start.SystemStatus.GetDescription(),
  568. StartTime = start.Frame,
  569. Type = type
  570. };
  571. if (info.Frame == end.Frame) runInfo.EndTime = endTime;
  572. else runInfo.EndTime = info.Frame;
  573. runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds);
  574. runInfos.Add(runInfo);
  575. start = info;
  576. }
  577. }
  578. var sql = plcEx.Insertable(runInfos).ToSqlString();
  579. plcEx.Ado.ExecuteCommand(GetString(sql));
  580. }
  581. }
  582. /// <summary>
  583. /// 桁架
  584. /// </summary>
  585. /// <param name="db"></param>
  586. public void ExTrussRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  587. {
  588. var startTime = DateTime.Now;
  589. var endTime = DateTime.Now;
  590. IEnumerable<IGrouping<string, WCS_Truss521>> truss521 = new List<IGrouping<string, WCS_Truss521>>();
  591. var type = DevType.Truss.ToString();
  592. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  593. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  594. {
  595. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  596. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  597. .First();
  598. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  599. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  600. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  601. }
  602. else
  603. {
  604. if (db.Queryable<WCS_Truss521>().Count() <= 0) return;
  605. startTime = db.Queryable<WCS_Truss521>().OrderBy(x => x.Frame).First().Frame;
  606. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  607. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  608. }
  609. //取上一小时的第一秒
  610. var now = DateTime.Now;
  611. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  612. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  613. if (endTime > now) return; //当前时间之前
  614. if (nowEndTime == now) return; //是当前这一个小时
  615. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0);
  616. if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  617. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  618. truss521 = db.Queryable<WCS_Truss521>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  619. .GroupBy(x => x.Code).ToList();
  620. if (!truss521.Any())
  621. plcEx.Insertable(new DevRunInfo
  622. {
  623. Frame = endTime,
  624. Code = "当前时段无有效数据",
  625. RunMode = "当前时段无有效数据",
  626. RunStatus = "当前时段无有效数据",
  627. StartTime = startTime,
  628. EndTime = endTime,
  629. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  630. Type = type
  631. }).ExecuteCommand();
  632. foreach (var infos in truss521)
  633. {
  634. // 获取第一条数据与最后一条数据
  635. var start = infos.OrderBy(x => x.Frame).First();
  636. var end = infos.OrderByDescending(x => x.Frame).First();
  637. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  638. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  639. //获取前一天最后的一条数据
  640. var yesterEnd = plcEx.Queryable<DevRunInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  641. .OrderByDescending(x => x.Frame).First();
  642. var runInfos = new List<DevRunInfo>();
  643. foreach (var info in infos.OrderBy(x => x.Frame))
  644. if (info.Frame == start.Frame) //当天的第一条数据
  645. {
  646. if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算
  647. runInfos.Add(new DevRunInfo
  648. {
  649. Frame = info.Frame,
  650. Code = info.Code,
  651. RunMode = info.Status.GetDescription(),
  652. StartTime = startTime,
  653. EndTime = info.Frame,
  654. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  655. Type = type
  656. });
  657. else //如果有就用前一天的最后一条数据做计算
  658. runInfos.Add(new DevRunInfo
  659. {
  660. Frame = info.Frame,
  661. Code = info.Code,
  662. RunMode = yesterEnd.RunMode,
  663. RunStatus = yesterEnd.RunStatus,
  664. StartTime = startTime,
  665. EndTime = info.Frame,
  666. Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds),
  667. Type = type
  668. });
  669. }
  670. else //状态出现状态变化时或最后一条数据
  671. {
  672. if (start.Status != info.Status || info.Frame == end.Frame)
  673. {
  674. var runInfo = new DevRunInfo
  675. {
  676. Frame = info.Frame,
  677. Code = info.Code,
  678. RunMode = start.Status.GetDescription(),
  679. StartTime = start.Frame,
  680. Type = type
  681. };
  682. if (info.Frame == end.Frame) runInfo.EndTime = endTime;
  683. else runInfo.EndTime = info.Frame;
  684. runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds);
  685. runInfos.Add(runInfo);
  686. start = info;
  687. }
  688. }
  689. var sql = plcEx.Insertable(runInfos).ToSqlString();
  690. plcEx.Ado.ExecuteCommand(GetString(sql));
  691. }
  692. }
  693. #endregion 设备运行信息收集
  694. #region 异常报警信息
  695. /// <summary>
  696. /// 机械臂
  697. /// </summary>
  698. /// <param name="db"></param>
  699. public void ExRobotAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  700. {
  701. var startTime = DateTime.Now;
  702. var endTime = DateTime.Now;
  703. IEnumerable<IGrouping<string, QuestDb_Robot522>> robot522 = new List<IGrouping<string, QuestDb_Robot522>>();
  704. var type = DevType.Robot.ToString();
  705. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  706. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Type == type))
  707. {
  708. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  709. var alarmInfo = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  710. .First();
  711. startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间
  712. endTime = startTime.AddDays(+1).AddMilliseconds(-1); //
  713. }
  714. else
  715. {
  716. if (db.Queryable<QuestDb_Robot522>().Count() <= 0) return;
  717. startTime = db.Queryable<QuestDb_Robot522>().OrderBy(x => x.Frame).First().Frame.Date;
  718. endTime = startTime.AddDays(+1).AddMilliseconds(-1);
  719. }
  720. if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据
  721. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  722. robot522 = db.Queryable<QuestDb_Robot522>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  723. .GroupBy(x => x.Code).ToList();
  724. if (!robot522.Any())
  725. plcEx.Insertable(new DevAlarmInfo
  726. {
  727. Frame = endTime,
  728. Code = "当前时段无有效数据",
  729. Alarm = "当前时段无有效数据",
  730. StartTime = startTime,
  731. EndTime = endTime,
  732. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  733. Type = type
  734. }).ExecuteCommand();
  735. Parallel.ForEach(robot522, infos =>
  736. {
  737. // 获取第一条数据与最后一条数据
  738. var start = infos.OrderBy(x => x.Frame).First();
  739. var end = infos.OrderByDescending(x => x.Frame).First();
  740. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  741. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  742. //获取前一天最后的一条数据
  743. var yesterEnd = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  744. .OrderByDescending(x => x.Frame).First();
  745. var runInfos = new List<DevAlarmInfo>(); //需要保存的数据
  746. var alarmList = new List<EquipmentAlarm>(); //未结束的报警信息
  747. foreach (var info in infos.OrderBy(x => x.Frame))
  748. if (info.Frame == end.Frame) //最后一条数据
  749. {
  750. if (info.Alarm != "无")
  751. {
  752. //先判断是否有没有记录的报警信息
  753. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  754. .SelectMany(x => x).ToList();
  755. var msgList = alarmList.Select(x => x.Msg);
  756. //将未记录的报警信息增加到缓存中
  757. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  758. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  759. }
  760. if (!alarmList.Any()) continue;
  761. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  762. {
  763. Frame = alarm.Time,
  764. Code = info.Code,
  765. Alarm = alarm.Msg,
  766. StartTime = alarm.Time,
  767. EndTime = endTime,
  768. Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds),
  769. Type = type
  770. }));
  771. }
  772. else
  773. {
  774. if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了
  775. {
  776. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  777. {
  778. Frame = alarm.Time,
  779. Code = info.Code,
  780. Alarm = alarm.Msg,
  781. StartTime = alarm.Time,
  782. EndTime = info.Frame,
  783. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  784. Type = type
  785. }));
  786. alarmList = new List<EquipmentAlarm>(); //清空现有报警信息
  787. }
  788. else if (info.Alarm != "无")
  789. {
  790. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  791. .SelectMany(x => x).ToList();
  792. var msgList = alarmList.Select(x => x.Msg);
  793. //将未记录的报警信息增加到缓存中
  794. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  795. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  796. var treatedAlarm = new List<string>();
  797. //将已记录,但当前信息中没有的报警结束
  798. foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg)))
  799. {
  800. runInfos.Add(new DevAlarmInfo
  801. {
  802. Frame = alarm.Time,
  803. Code = info.Code,
  804. Alarm = alarm.Msg,
  805. StartTime = alarm.Time,
  806. EndTime = info.Frame,
  807. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  808. Type = type
  809. });
  810. treatedAlarm.Add(alarm.Msg);
  811. }
  812. alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList();
  813. }
  814. }
  815. if (runInfos.Any())
  816. {
  817. var sql = plcEx.Insertable(runInfos).ToSqlString();
  818. plcEx.Ado.ExecuteCommand(GetString(sql));
  819. }
  820. else
  821. {
  822. plcEx.Insertable(new DevAlarmInfo
  823. {
  824. Frame = endTime,
  825. Code = infos.Key,
  826. Alarm = "当前时段无有效数据",
  827. StartTime = startTime,
  828. EndTime = endTime,
  829. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  830. Type = type
  831. }).ExecuteCommand();
  832. }
  833. });
  834. }
  835. /// <summary>
  836. /// 堆垛机
  837. /// </summary>
  838. /// <param name="db"></param>
  839. public void ExSrmAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  840. {
  841. var startTime = DateTime.Now;
  842. var endTime = DateTime.Now;
  843. IEnumerable<IGrouping<string, QuestDb_SRM523>> srm523 = new List<IGrouping<string, QuestDb_SRM523>>();
  844. var type = DevType.SRM.ToString();
  845. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  846. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Type == type))
  847. {
  848. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  849. var alarmInfo = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  850. .First();
  851. startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间
  852. endTime = startTime.AddDays(+1).AddMilliseconds(-1); //
  853. }
  854. else
  855. {
  856. if (db.Queryable<QuestDb_SRM523>().Count() <= 0) return;
  857. startTime = db.Queryable<QuestDb_SRM523>().OrderBy(x => x.Frame).First().Frame.Date;
  858. endTime = startTime.AddDays(+1).AddMilliseconds(-1);
  859. }
  860. if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据
  861. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  862. srm523 = db.Queryable<QuestDb_SRM523>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  863. .GroupBy(x => x.Code).ToList();
  864. if (!srm523.Any())
  865. plcEx.Insertable(new DevAlarmInfo
  866. {
  867. Frame = endTime,
  868. Code = "当前时段无有效数据",
  869. Alarm = "当前时段无有效数据",
  870. StartTime = startTime,
  871. EndTime = endTime,
  872. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  873. Type = type
  874. }).ExecuteCommand();
  875. Parallel.ForEach(srm523, infos =>
  876. {
  877. // 获取第一条数据与最后一条数据
  878. var start = infos.OrderBy(x => x.Frame).First();
  879. var end = infos.OrderByDescending(x => x.Frame).First();
  880. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  881. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  882. //获取前一天最后的一条数据
  883. var yesterEnd = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  884. .OrderByDescending(x => x.Frame).First();
  885. var runInfos = new List<DevAlarmInfo>(); //需要保存的数据
  886. var alarmList = new List<EquipmentAlarm>(); //未结束的报警信息
  887. foreach (var info in infos.OrderBy(x => x.Frame))
  888. if (info.Frame == end.Frame) //最后一条数据
  889. {
  890. if (info.Alarm != "无,无")
  891. {
  892. //先判断是否有没有记录的报警信息
  893. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  894. .SelectMany(x => x).Where(x => x != "无").ToList();
  895. var msgList = alarmList.Select(x => x.Msg);
  896. //将未记录的报警信息增加到缓存中
  897. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  898. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  899. }
  900. if (!alarmList.Any()) continue;
  901. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  902. {
  903. Frame = alarm.Time,
  904. Code = info.Code,
  905. Alarm = alarm.Msg,
  906. StartTime = alarm.Time,
  907. EndTime = endTime,
  908. Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds),
  909. Type = type
  910. }));
  911. }
  912. else
  913. {
  914. if (info.Alarm == "无,无" && alarmList.Any()) //代表报警全部清空了
  915. {
  916. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  917. {
  918. Frame = alarm.Time,
  919. Code = info.Code,
  920. Alarm = alarm.Msg,
  921. StartTime = alarm.Time,
  922. EndTime = info.Frame,
  923. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  924. Type = type
  925. }));
  926. alarmList = new List<EquipmentAlarm>(); //清空现有报警信息
  927. }
  928. else if (info.Alarm != "无,无")
  929. {
  930. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  931. .SelectMany(x => x).Where(x => x != "无").ToList();
  932. var msgList = alarmList.Select(x => x.Msg);
  933. //将未记录的报警信息增加到缓存中
  934. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  935. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  936. var treatedAlarm = new List<string>();
  937. //将已记录,但当前信息中没有的报警结束
  938. foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg)))
  939. {
  940. runInfos.Add(new DevAlarmInfo
  941. {
  942. Frame = alarm.Time,
  943. Code = info.Code,
  944. Alarm = alarm.Msg,
  945. StartTime = alarm.Time,
  946. EndTime = info.Frame,
  947. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  948. Type = type
  949. });
  950. treatedAlarm.Add(alarm.Msg);
  951. }
  952. alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList();
  953. }
  954. }
  955. if (runInfos.Any())
  956. {
  957. var sql = plcEx.Insertable(runInfos).ToSqlString();
  958. plcEx.Ado.ExecuteCommand(GetString(sql));
  959. }
  960. else
  961. {
  962. plcEx.Insertable(new DevAlarmInfo
  963. {
  964. Frame = endTime,
  965. Code = infos.Key,
  966. Alarm = "当前时段无有效数据",
  967. StartTime = startTime,
  968. EndTime = endTime,
  969. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  970. Type = type
  971. }).ExecuteCommand();
  972. }
  973. });
  974. }
  975. /// <summary>
  976. /// rgv
  977. /// </summary>
  978. /// <param name="db"></param>
  979. public void ExRgvAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  980. {
  981. var startTime = DateTime.Now;
  982. var endTime = DateTime.Now;
  983. IEnumerable<IGrouping<string, QuestDb_RGV523>> rgv523 = new List<IGrouping<string, QuestDb_RGV523>>();
  984. var type = DevType.RGV.ToString();
  985. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  986. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Type == type))
  987. {
  988. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  989. var alarmInfo = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  990. .First();
  991. startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间
  992. endTime = startTime.AddDays(+1).AddMilliseconds(-1); //
  993. }
  994. else
  995. {
  996. if (db.Queryable<QuestDb_RGV523>().Count() <= 0) return;
  997. startTime = db.Queryable<QuestDb_RGV523>().OrderBy(x => x.Frame).First().Frame.Date;
  998. endTime = startTime.AddDays(+1).AddMilliseconds(-1);
  999. }
  1000. if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据
  1001. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  1002. rgv523 = db.Queryable<QuestDb_RGV523>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  1003. .GroupBy(x => x.Code).ToList();
  1004. if (!rgv523.Any())
  1005. plcEx.Insertable(new DevAlarmInfo
  1006. {
  1007. Frame = endTime,
  1008. Code = "当前时段无有效数据",
  1009. Alarm = "当前时段无有效数据",
  1010. StartTime = startTime,
  1011. EndTime = endTime,
  1012. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1013. Type = type
  1014. }).ExecuteCommand();
  1015. Parallel.ForEach(rgv523 /*.Where(x => x.Key == "RGV4")*/, infos =>
  1016. {
  1017. // 获取第一条数据与最后一条数据
  1018. var start = infos.OrderBy(x => x.Frame).First();
  1019. var end = infos.OrderByDescending(x => x.Frame).First();
  1020. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  1021. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  1022. //获取前一天最后的一条数据
  1023. var yesterEnd = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  1024. .OrderByDescending(x => x.Frame).First();
  1025. var runInfos = new List<DevAlarmInfo>(); //需要保存的数据
  1026. var alarmList = new List<EquipmentAlarm>(); //未结束的报警信息
  1027. foreach (var info in infos.OrderBy(x => x.Frame))
  1028. if (info.Frame == end.Frame) //最后一条数据
  1029. {
  1030. if (info.Alarm != "无")
  1031. {
  1032. //先判断是否有没有记录的报警信息
  1033. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  1034. .SelectMany(x => x).ToList();
  1035. var msgList = alarmList.Select(x => x.Msg);
  1036. //将未记录的报警信息增加到缓存中
  1037. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  1038. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  1039. }
  1040. if (!alarmList.Any()) continue;
  1041. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  1042. {
  1043. Frame = alarm.Time,
  1044. Code = info.Code,
  1045. Alarm = alarm.Msg,
  1046. StartTime = alarm.Time,
  1047. EndTime = endTime,
  1048. Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds),
  1049. Type = type
  1050. }));
  1051. }
  1052. else
  1053. {
  1054. if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了
  1055. {
  1056. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  1057. {
  1058. Frame = alarm.Time,
  1059. Code = info.Code,
  1060. Alarm = alarm.Msg,
  1061. StartTime = alarm.Time,
  1062. EndTime = info.Frame,
  1063. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  1064. Type = type
  1065. }));
  1066. alarmList = new List<EquipmentAlarm>(); //清空现有报警信息
  1067. }
  1068. else if (info.Alarm != "无")
  1069. {
  1070. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  1071. .SelectMany(x => x).ToList();
  1072. var msgList = alarmList.Select(x => x.Msg);
  1073. //将未记录的报警信息增加到缓存中
  1074. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  1075. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  1076. var treatedAlarm = new List<string>();
  1077. //将已记录,但当前信息中没有的报警结束
  1078. foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg)))
  1079. {
  1080. runInfos.Add(new DevAlarmInfo
  1081. {
  1082. Frame = alarm.Time,
  1083. Code = info.Code,
  1084. Alarm = alarm.Msg,
  1085. StartTime = alarm.Time,
  1086. EndTime = info.Frame,
  1087. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  1088. Type = type
  1089. });
  1090. treatedAlarm.Add(alarm.Msg);
  1091. }
  1092. alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList();
  1093. }
  1094. }
  1095. if (runInfos.Any())
  1096. plcEx.Insertable(runInfos).ExecuteCommand();
  1097. else
  1098. plcEx.Insertable(new DevAlarmInfo
  1099. {
  1100. Frame = endTime,
  1101. Code = infos.Key,
  1102. Alarm = "当前时段无有效数据",
  1103. StartTime = startTime,
  1104. EndTime = endTime,
  1105. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1106. Type = type
  1107. }).ExecuteCommand();
  1108. });
  1109. }
  1110. /// <summary>
  1111. /// Truss
  1112. /// </summary>
  1113. /// <param name="db"></param>
  1114. public void ExTrussAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  1115. {
  1116. var startTime = DateTime.Now;
  1117. var endTime = DateTime.Now;
  1118. IEnumerable<IGrouping<string, QuestDb_Truss523>> rgv523 = new List<IGrouping<string, QuestDb_Truss523>>();
  1119. var type = DevType.Truss.ToString();
  1120. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  1121. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Type == type))
  1122. {
  1123. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  1124. var alarmInfo = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  1125. .First();
  1126. startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间
  1127. endTime = startTime.AddDays(+1).AddMilliseconds(-1); //
  1128. }
  1129. else
  1130. {
  1131. if (db.Queryable<QuestDb_Truss523>().Count() <= 0) return;
  1132. startTime = db.Queryable<QuestDb_Truss523>().OrderBy(x => x.Frame).First().Frame.Date;
  1133. endTime = startTime.AddDays(+1).AddMilliseconds(-1);
  1134. }
  1135. if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据
  1136. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  1137. rgv523 = db.Queryable<QuestDb_Truss523>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  1138. .GroupBy(x => x.Code).ToList();
  1139. if (!rgv523.Any())
  1140. plcEx.Insertable(new DevAlarmInfo
  1141. {
  1142. Frame = endTime,
  1143. Code = "当前时段无有效数据",
  1144. Alarm = "当前时段无有效数据",
  1145. StartTime = startTime,
  1146. EndTime = endTime,
  1147. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1148. Type = type
  1149. }).ExecuteCommand();
  1150. Parallel.ForEach(rgv523 /*.Where(x => x.Key == "RGV4")*/, infos =>
  1151. {
  1152. // 获取第一条数据与最后一条数据
  1153. var start = infos.OrderBy(x => x.Frame).First();
  1154. var end = infos.OrderByDescending(x => x.Frame).First();
  1155. //通过是否有最后一条数据来确定当前数据是否有分析存储过
  1156. if (plcEx.Queryable<DevAlarmInfo>().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return;
  1157. //获取前一天最后的一条数据
  1158. var yesterEnd = plcEx.Queryable<DevAlarmInfo>().Where(x => x.Code == infos.Key && x.Frame < endTime)
  1159. .OrderByDescending(x => x.Frame).First();
  1160. var runInfos = new List<DevAlarmInfo>(); //需要保存的数据
  1161. var alarmList = new List<EquipmentAlarm>(); //未结束的报警信息
  1162. foreach (var info in infos.OrderBy(x => x.Frame))
  1163. if (info.Frame == end.Frame) //最后一条数据
  1164. {
  1165. if (info.Alarm != "无")
  1166. {
  1167. //先判断是否有没有记录的报警信息
  1168. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  1169. .SelectMany(x => x).ToList();
  1170. var msgList = alarmList.Select(x => x.Msg);
  1171. //将未记录的报警信息增加到缓存中
  1172. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  1173. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  1174. }
  1175. if (!alarmList.Any()) continue;
  1176. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  1177. {
  1178. Frame = alarm.Time,
  1179. Code = info.Code,
  1180. Alarm = alarm.Msg,
  1181. StartTime = alarm.Time,
  1182. EndTime = endTime,
  1183. Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds),
  1184. Type = type
  1185. }));
  1186. }
  1187. else
  1188. {
  1189. if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了
  1190. {
  1191. runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo
  1192. {
  1193. Frame = alarm.Time,
  1194. Code = info.Code,
  1195. Alarm = alarm.Msg,
  1196. StartTime = alarm.Time,
  1197. EndTime = info.Frame,
  1198. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  1199. Type = type
  1200. }));
  1201. alarmList = new List<EquipmentAlarm>(); //清空现有报警信息
  1202. }
  1203. else if (info.Alarm != "无")
  1204. {
  1205. var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(","))
  1206. .SelectMany(x => x).ToList();
  1207. var msgList = alarmList.Select(x => x.Msg);
  1208. //将未记录的报警信息增加到缓存中
  1209. alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg))
  1210. .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg }));
  1211. var treatedAlarm = new List<string>();
  1212. //将已记录,但当前信息中没有的报警结束
  1213. foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg)))
  1214. {
  1215. runInfos.Add(new DevAlarmInfo
  1216. {
  1217. Frame = alarm.Time,
  1218. Code = info.Code,
  1219. Alarm = alarm.Msg,
  1220. StartTime = alarm.Time,
  1221. EndTime = info.Frame,
  1222. Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds),
  1223. Type = type
  1224. });
  1225. treatedAlarm.Add(alarm.Msg);
  1226. }
  1227. alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList();
  1228. }
  1229. }
  1230. if (runInfos.Any())
  1231. plcEx.Insertable(runInfos).ExecuteCommand();
  1232. else
  1233. plcEx.Insertable(new DevAlarmInfo
  1234. {
  1235. Frame = endTime,
  1236. Code = infos.Key,
  1237. Alarm = "当前时段无有效数据",
  1238. StartTime = startTime,
  1239. EndTime = endTime,
  1240. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1241. Type = type
  1242. }).ExecuteCommand();
  1243. });
  1244. }
  1245. #endregion 异常报警信息
  1246. #region 任务状态分析
  1247. /// <summary>
  1248. /// 机械臂分析单双爪任务占比,需要按照任务类型分类
  1249. /// </summary>
  1250. /// <param name="db"></param>
  1251. public void ExRobotTaskSumRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  1252. {
  1253. var startTime = DateTime.Now;
  1254. var endTime = DateTime.Now;
  1255. IEnumerable<IGrouping<string, WCS_Robot520>> robot520 = new List<IGrouping<string, WCS_Robot520>>();
  1256. var type = DevType.RobotTaskSum.ToString();
  1257. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  1258. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  1259. {
  1260. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  1261. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type).OrderByDescending(x => x.Frame)
  1262. .First();
  1263. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  1264. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  1265. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  1266. }
  1267. else
  1268. {
  1269. if (db.Queryable<WCS_Robot520>().Count() <= 0) return;
  1270. startTime = db.Queryable<WCS_Robot520>().OrderBy(x => x.Frame).First().Frame;
  1271. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间
  1272. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  1273. }
  1274. //取上一小时的第一秒
  1275. var now = DateTime.Now;
  1276. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  1277. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  1278. if (endTime > now) return; //当前时间之前
  1279. if (nowEndTime == now) return; //是当前这一个小时
  1280. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0);
  1281. if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  1282. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type)) return;
  1283. robot520 = db.Queryable<WCS_Robot520>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  1284. .GroupBy(x => x.Code).ToList();
  1285. if (!robot520.Any())
  1286. plcEx.Insertable(new DevRunInfo
  1287. {
  1288. Frame = endTime,
  1289. Code = "当前时段无有效数据",
  1290. RunMode = "当前时段无有效数据",
  1291. RunStatus = "当前时段无有效数据",
  1292. StartTime = startTime,
  1293. EndTime = endTime,
  1294. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1295. Type = type
  1296. }).ExecuteCommand();
  1297. foreach (var infos in robot520)
  1298. {
  1299. var infoList = infos.Where(x => x.TaskNumber1 != 0 || x.TaskNumber2 != 0).ToList()
  1300. .DistinctItemBy(x => x.VoucherNo);
  1301. var runInfos = new List<DevRunInfo>();
  1302. foreach (var info in infoList.OrderBy(x => x.Frame))
  1303. {
  1304. var taskSum = 0;
  1305. if (info.TaskNumber1 != 0) taskSum += 1;
  1306. if (info.TaskNumber2 != 0) taskSum += 1;
  1307. runInfos.Add(new DevRunInfo
  1308. {
  1309. Frame = info.Frame,
  1310. Code = info.Code,
  1311. RunMode = taskSum.ToString(),
  1312. RunStatus = $"{info.TaskNumber1}--{info.TaskNumber2}--{info.TaskType}",
  1313. Duration = 0,
  1314. Type = type
  1315. });
  1316. }
  1317. var sql = plcEx.Insertable(runInfos).ToSqlString();
  1318. plcEx.Ado.ExecuteCommand(GetString(sql));
  1319. }
  1320. }
  1321. /// <summary>
  1322. /// 桁架分析单双爪任务占比,需要按照任务类型分类
  1323. /// </summary>
  1324. /// <param name="db"></param>
  1325. public void ExTrussTaskSumRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx)
  1326. {
  1327. try
  1328. {
  1329. var startTime = DateTime.Now;
  1330. var endTime = DateTime.Now;
  1331. IEnumerable<IGrouping<string, WCS_Truss520>> truss520 = new List<IGrouping<string, WCS_Truss520>>();
  1332. var type = DevType.TrussTaskSum.ToString();
  1333. //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化
  1334. if (plcEx.Queryable<DevRunInfo>().Any(x => x.Type == type))
  1335. {
  1336. //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据
  1337. var runInfo = plcEx.Queryable<DevRunInfo>().Where(x => x.Type == type)
  1338. .OrderByDescending(x => x.Frame).First();
  1339. startTime = runInfo.Frame.AddHours(+1); //后一个小时
  1340. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0,
  1341. 0); //后一个小时的开始时间
  1342. endTime = startTime.AddHours(+1).AddMilliseconds(-1); //
  1343. }
  1344. else
  1345. {
  1346. if (db.Queryable<WCS_Truss520>().Count() <= 0) return;
  1347. startTime = db.Queryable<WCS_Truss520>().OrderBy(x => x.Frame).First().Frame;
  1348. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0,
  1349. 0); //后一个小时的开始时间
  1350. endTime = startTime.AddHours(+1).AddMilliseconds(-1);
  1351. }
  1352. //取上一小时的第一秒
  1353. var now = DateTime.Now;
  1354. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
  1355. var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
  1356. //当前时间之前
  1357. if (endTime > now) throw new KnownException("当前时间之前", LogLevelEnum.High);
  1358. //是当前这一个小时
  1359. if (nowEndTime == now) throw new KnownException("是当前这一个小时", LogLevelEnum.High);
  1360. now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0);
  1361. // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理
  1362. if (DateTime.Now < now)
  1363. throw new KnownException("每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理", LogLevelEnum.High);
  1364. if (plcEx.Queryable<DevRunInfo>().Any(x => x.EndTime == endTime && x.Type == type))
  1365. throw new KnownException("当前小时有数据", LogLevelEnum.High);
  1366. truss520 = db.Queryable<WCS_Truss520>().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList()
  1367. .GroupBy(x => x.Code).ToList();
  1368. if (!truss520.Any())
  1369. plcEx.Insertable(new DevRunInfo
  1370. {
  1371. Frame = endTime,
  1372. Code = "当前时段无有效数据",
  1373. RunMode = "当前时段无有效数据",
  1374. RunStatus = "当前时段无有效数据",
  1375. StartTime = startTime,
  1376. EndTime = endTime,
  1377. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1378. Type = type
  1379. }).ExecuteCommand();
  1380. foreach (var infos in truss520)
  1381. {
  1382. var infoList = infos.Where(x =>
  1383. x.Task1_1 != 0 || x.Task1_2 != 0 || x.Task1_3 != 0 || x.Task1_4 != 0 || x.Task1_5 != 0
  1384. || x.Task2_1 != 0 || x.Task2_2 != 0 || x.Task2_3 != 0 || x.Task2_4 != 0 || x.Task2_5 != 0)
  1385. .ToList().DistinctItemBy(x => x.VoucherNo);
  1386. var runInfos = new List<DevRunInfo>();
  1387. foreach (var info in infoList.OrderBy(x => x.Frame))
  1388. {
  1389. var taskSum = 0;
  1390. if (info.Task1_1 != 0) taskSum += 1;
  1391. if (info.Task1_2 != 0) taskSum += 1;
  1392. if (info.Task1_3 != 0) taskSum += 1;
  1393. if (info.Task1_4 != 0) taskSum += 1;
  1394. if (info.Task1_5 != 0) taskSum += 1;
  1395. if (info.Task2_1 != 0) taskSum += 1;
  1396. if (info.Task2_2 != 0) taskSum += 1;
  1397. if (info.Task2_3 != 0) taskSum += 1;
  1398. if (info.Task2_4 != 0) taskSum += 1;
  1399. if (info.Task2_5 != 0) taskSum += 1;
  1400. runInfos.Add(new DevRunInfo
  1401. {
  1402. Frame = info.Frame,
  1403. Code = info.Code,
  1404. RunMode = taskSum.ToString(),
  1405. RunStatus =
  1406. $"{info.Task1_1}--{info.Task1_2}--{info.Task1_3}--{info.Task1_4}--{info.Task1_5}--{info.Task2_1}--{info.Task2_2}--{info.Task2_3}--{info.Task2_4}--{info.Task2_5}",
  1407. Duration = 0,
  1408. Type = type
  1409. });
  1410. }
  1411. if (!runInfos.Any())
  1412. {
  1413. plcEx.Insertable(new DevRunInfo
  1414. {
  1415. Frame = endTime,
  1416. Code = infos.Key,
  1417. RunMode = "当前时段无有效数据",
  1418. RunStatus = "当前时段无有效数据",
  1419. StartTime = startTime,
  1420. EndTime = endTime,
  1421. Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds),
  1422. Type = type
  1423. }).ExecuteCommand();
  1424. continue;
  1425. }
  1426. var sql = plcEx.Insertable(runInfos).ToSqlString();
  1427. plcEx.Ado.ExecuteCommand(GetString(sql));
  1428. }
  1429. }
  1430. catch (Exception e)
  1431. {
  1432. Console.WriteLine(e);
  1433. throw new KnownException($"{e.Message}:{e.StackTrace}", LogLevelEnum.High);
  1434. }
  1435. }
  1436. #endregion 任务状态分析
  1437. }
  1438. /// <summary>
  1439. /// 数据清理
  1440. /// </summary>
  1441. public class FeedRateDto(short day, short hour, short minute, short number, DateTime frame, string code)
  1442. {
  1443. /// <summary>
  1444. /// 天
  1445. /// </summary>
  1446. public short Day { get; set; } = day;
  1447. /// <summary>
  1448. /// 小时
  1449. /// </summary>
  1450. public short Hour { get; set; } = hour;
  1451. /// <summary>
  1452. /// 分钟
  1453. /// </summary>
  1454. public short Minute { get; set; } = minute;
  1455. /// <summary>
  1456. /// 数量
  1457. /// </summary>
  1458. public short Number { get; set; } = number;
  1459. /// <summary>
  1460. /// 时间
  1461. /// </summary>
  1462. public DateTime Frame { get; set; } = frame;
  1463. /// <summary>
  1464. /// 设备号
  1465. /// </summary>
  1466. public string Code { get; set; } = code;
  1467. }
  1468. /// <summary>
  1469. /// 设备报警
  1470. /// </summary>
  1471. public class EquipmentAlarm
  1472. {
  1473. /// <summary>
  1474. /// 内容
  1475. /// </summary>
  1476. public string Msg { get; set; }
  1477. /// <summary>
  1478. /// 时间
  1479. /// </summary>
  1480. public DateTime Time { get; set; }
  1481. }
  1482. /// <summary>
  1483. /// 设备状态信息
  1484. /// </summary>
  1485. public class EquipmentStatus
  1486. {
  1487. /// <summary>
  1488. /// 设备号
  1489. /// </summary>
  1490. public string Code { get; set; }
  1491. /// <summary>
  1492. /// 内容
  1493. /// </summary>
  1494. public string con { get; set; }
  1495. /// <summary>
  1496. /// 内容
  1497. /// </summary>
  1498. public int Status { get; set; }
  1499. /// <summary>
  1500. /// 时间
  1501. /// </summary>
  1502. public DateTime Time { get; set; }
  1503. }
  1504. /// <summary>
  1505. /// </summary>
  1506. /// <typeparam name="T"></typeparam>
  1507. public class Quest<T>
  1508. {
  1509. public T Data { get; set; }
  1510. }
  1511. public class KeyValue
  1512. {
  1513. public string key { get; set; }
  1514. public string value { get; set; }
  1515. }