using System.Collections.Concurrent; using System.ComponentModel; using PlcSiemens.Core.Extension; using ServiceCenter.Extensions; using ServiceCenter.Logs; using ServiceCenter.SqlSugars; using SqlSugar; using WCS.Core; using WCS.Entity.Protocol.DataStructure; using WCS.Entity.Protocol.HUB; using WCS.Entity.Protocol.RGV; using WCS.Entity.Protocol.Robot; using WCS.Entity.Protocol.SRM; using WCS.Entity.Protocol.Station; using WCS.Entity.Protocol.Truss; using WCS.WorkEngineering.Worlds; namespace WCS.WorkEngineering.Systems; /// /// 数据处理系统 /// [BelongTo(typeof(MainWorld))] [Description("数据处理系统")] public class DataCollectionSysyem : DeviceSystem> { public static DeviceDataPack pack = new(); private static object locker = new(); /// /// 所有设备数据 /// Key 是不同设备所使用的类型 例如DeviceDataCollection /// /// value 不同设备的具体数据 /// public static ConcurrentDictionary AllDatas = new(); protected override bool ParallelDo => true; public override bool Select(Device dev) { return dev.Code == "1"; } public override void Do(Device objDev) { //通过数据条数处理 var db = new SqlSugarHelper().PLC; var plcEx = new SqlSugarHelper().PLCEX; ExRobotRunInfo(db, plcEx); ExSrmRunInfo(db, plcEx); ExRgvRunInfo(db, plcEx); ExTrussRunInfo(db, plcEx); //ExRobotAlarmInfo(db, plcEx); //ExSrmAlarmInfo(db, plcEx); //ExRgvAlarmInfo(db, plcEx); //ExTrussAlarmInfo(db, plcEx); ExRobotTaskSumRunInfo(db, plcEx); ExTrussTaskSumRunInfo(db, plcEx); SummarizeInboundMaterialByRegion(db, plcEx); } /// /// 汇总并分析南北区域的来料数量。 /// /// public void SummarizeInboundMaterialByRegion(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { try { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> station5 = new List>(); var type = DevType.FeedRate.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type) .OrderByDescending(x => x.Frame).First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); //当前时间之前 if (endTime > now) throw new KnownException("当前时间之前", LogLevelEnum.High); //是当前这一个小时 if (nowEndTime == now) throw new KnownException("是当前这一个小时", LogLevelEnum.High); now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0); // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (DateTime.Now < now) throw new KnownException("每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理", LogLevelEnum.High); if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) throw new KnownException("当前小时有数据", LogLevelEnum.High); station5 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!station5.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in station5) { var infoList = infos.SelectMany(FeedRateMethod).ToList().GroupBy(x => x.Day); var feedRateList = new List(); //获取每一分钟最大的数据 infoList.ForEach(day => { day.GroupBy(x => x.Hour).ForEach(hour => { hour.GroupBy(x => x.Minute).ForEach(minute => { var feedRate = minute.MaxBy(x => x.Number); feedRateList.Add(new DevRunInfo { Frame = feedRate.Frame, Code = feedRate.Code, RunMode = $"{feedRate.Day} {feedRate.Hour}:{feedRate.Minute}", RunStatus = feedRate.Number.ToString(), Duration = 0, Type = type }); }); }); }); if (!feedRateList.Any()) { plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = infos.Key, RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); continue; } var sql = plcEx.Insertable(feedRateList).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } catch (Exception e) { Console.WriteLine(e); throw new KnownException($"{e.Message}:{e.StackTrace}", LogLevelEnum.High); } } public List FeedRateMethod(WCS_Station5 st) { List res = [ new(st.Day0, st.Hour0, st.Minute0, st.Number0, st.Frame, st.Code), new(st.Day1, st.Hour1, st.Minute1, st.Number1, st.Frame, st.Code), new(st.Day2, st.Hour2, st.Minute2, st.Number2, st.Frame, st.Code), new(st.Day3, st.Hour3, st.Minute3, st.Number3, st.Frame, st.Code), new(st.Day4, st.Hour4, st.Minute4, st.Number4, st.Frame, st.Code), new(st.Day5, st.Hour5, st.Minute5, st.Number5, st.Frame, st.Code), new(st.Day6, st.Hour6, st.Minute6, st.Number6, st.Frame, st.Code), new(st.Day7, st.Hour7, st.Minute7, st.Number7, st.Frame, st.Code), new(st.Day8, st.Hour8, st.Minute8, st.Number8, st.Frame, st.Code), new(st.Day9, st.Hour9, st.Minute9, st.Number9, st.Frame, st.Code), new(st.Day10, st.Hour10, st.Minute10, st.Number10, st.Frame, st.Code), new(st.Day11, st.Hour11, st.Minute11, st.Number11, st.Frame, st.Code), new(st.Day12, st.Hour12, st.Minute12, st.Number12, st.Frame, st.Code), new(st.Day13, st.Hour13, st.Minute13, st.Number13, st.Frame, st.Code), new(st.Day14, st.Hour14, st.Minute14, st.Number14, st.Frame, st.Code), new(st.Day15, st.Hour15, st.Minute15, st.Number15, st.Frame, st.Code), new(st.Day16, st.Hour16, st.Minute16, st.Number16, st.Frame, st.Code), new(st.Day17, st.Hour17, st.Minute17, st.Number17, st.Frame, st.Code), new(st.Day18, st.Hour18, st.Minute18, st.Number18, st.Frame, st.Code), new(st.Day19, st.Hour19, st.Minute19, st.Number19, st.Frame, st.Code), new(st.Day20, st.Hour20, st.Minute20, st.Number20, st.Frame, st.Code), new(st.Day21, st.Hour21, st.Minute21, st.Number21, st.Frame, st.Code), new(st.Day22, st.Hour22, st.Minute22, st.Number22, st.Frame, st.Code), new(st.Day23, st.Hour23, st.Minute23, st.Number23, st.Frame, st.Code), new(st.Day24, st.Hour24, st.Minute24, st.Number24, st.Frame, st.Code), new(st.Day25, st.Hour25, st.Minute25, st.Number25, st.Frame, st.Code), new(st.Day26, st.Hour26, st.Minute26, st.Number26, st.Frame, st.Code), new(st.Day27, st.Hour27, st.Minute27, st.Number27, st.Frame, st.Code), new(st.Day28, st.Hour28, st.Minute28, st.Number28, st.Frame, st.Code), new(st.Day29, st.Hour29, st.Minute29, st.Number29, st.Frame, st.Code), new(st.Day30, st.Hour30, st.Minute30, st.Number30, st.Frame, st.Code), new(st.Day31, st.Hour31, st.Minute31, st.Number31, st.Frame, st.Code), new(st.Day32, st.Hour32, st.Minute32, st.Number32, st.Frame, st.Code), new(st.Day33, st.Hour33, st.Minute33, st.Number33, st.Frame, st.Code), new(st.Day34, st.Hour34, st.Minute34, st.Number34, st.Frame, st.Code), new(st.Day35, st.Hour35, st.Minute35, st.Number35, st.Frame, st.Code), new(st.Day36, st.Hour36, st.Minute36, st.Number36, st.Frame, st.Code), new(st.Day37, st.Hour37, st.Minute37, st.Number37, st.Frame, st.Code), new(st.Day38, st.Hour38, st.Minute38, st.Number38, st.Frame, st.Code), new(st.Day39, st.Hour39, st.Minute39, st.Number39, st.Frame, st.Code), new(st.Day40, st.Hour40, st.Minute40, st.Number40, st.Frame, st.Code), new(st.Day41, st.Hour41, st.Minute41, st.Number41, st.Frame, st.Code), new(st.Day42, st.Hour42, st.Minute42, st.Number42, st.Frame, st.Code), new(st.Day43, st.Hour43, st.Minute43, st.Number43, st.Frame, st.Code), new(st.Day44, st.Hour44, st.Minute44, st.Number44, st.Frame, st.Code), new(st.Day45, st.Hour45, st.Minute45, st.Number45, st.Frame, st.Code), new(st.Day46, st.Hour46, st.Minute46, st.Number46, st.Frame, st.Code), new(st.Day47, st.Hour47, st.Minute47, st.Number47, st.Frame, st.Code), new(st.Day48, st.Hour48, st.Minute48, st.Number48, st.Frame, st.Code), new(st.Day49, st.Hour49, st.Minute49, st.Number49, st.Frame, st.Code), new(st.Day50, st.Hour50, st.Minute50, st.Number50, st.Frame, st.Code), new(st.Day51, st.Hour51, st.Minute51, st.Number51, st.Frame, st.Code), new(st.Day52, st.Hour52, st.Minute52, st.Number52, st.Frame, st.Code), new(st.Day53, st.Hour53, st.Minute53, st.Number53, st.Frame, st.Code), new(st.Day54, st.Hour54, st.Minute54, st.Number54, st.Frame, st.Code), new(st.Day55, st.Hour55, st.Minute55, st.Number55, st.Frame, st.Code), new(st.Day56, st.Hour56, st.Minute56, st.Number56, st.Frame, st.Code), new(st.Day57, st.Hour57, st.Minute57, st.Number57, st.Frame, st.Code), new(st.Day58, st.Hour58, st.Minute58, st.Number58, st.Frame, st.Code), new(st.Day59, st.Hour59, st.Minute59, st.Number59, st.Frame, st.Code) ]; return res; } public string GetString(string value) { return value.Replace(",N'", ",'") .Replace("\0", "") .Replace("(N'", "('") + "\r"; } #region 设备运行信息收集 /// /// 机械臂 /// /// public void ExRobotRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> robot521 = new List>(); var type = DevType.Robot.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); if (endTime > now) return; //当前时间之前 if (nowEndTime == now) return; //是当前这一个小时 now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0); if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; var sqls = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToSqlString(); var aaa = db.Ado.GetDataTable(sqls); robot521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!robot521.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in robot521) { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); foreach (var info in infos) if (info.Frame == start.Frame) //当天的第一条数据 { if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = info.RobotMode.GetDescription(), RunStatus = info.RunStatus.GetDescription(), StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); else //如果有就用前一天的最后一条数据做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = yesterEnd.RunMode, RunStatus = yesterEnd.RunStatus, StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); } else //状态出现状态变化时或最后一条数据 { if (start.RobotMode != info.RobotMode || start.RunStatus != info.RunStatus || info.Frame == end.Frame) { var runInfo = new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = start.RobotMode.GetDescription(), RunStatus = start.RunStatus.GetDescription(), StartTime = start.Frame, Type = type }; if (info.Frame == end.Frame) runInfo.EndTime = endTime; else runInfo.EndTime = info.Frame; runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds); runInfos.Add(runInfo); start = info; } } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } /// /// 堆垛机 /// /// public void ExSrmRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> srm521 = new List>(); var type = DevType.SRM.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); if (endTime > now) return; //当前时间之前 if (nowEndTime == now) return; //是当前这一个小时 now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0); if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; srm521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!srm521.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in srm521) { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == start.Frame) //当天的第一条数据 { if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = info.AutoStatus.GetDescription(), RunStatus = info.RunStatus.GetDescription(), StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); else //如果有就用前一天的最后一条数据做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = yesterEnd.RunMode, RunStatus = yesterEnd.RunStatus, StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); } else //状态出现状态变化时或最后一条数据 { if (start.AutoStatus != info.AutoStatus || start.RunStatus != info.RunStatus || info.Frame == end.Frame) { var runInfo = new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = start.AutoStatus.GetDescription(), RunStatus = start.RunStatus.GetDescription(), StartTime = start.Frame, Type = type }; if (info.Frame == end.Frame) runInfo.EndTime = endTime; else runInfo.EndTime = info.Frame; runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds); runInfos.Add(runInfo); start = info; } } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } /// /// rgv /// /// public void ExRgvRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> rgv521 = new List>(); var type = DevType.RGV.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); if (endTime > now) return; //当前时间之前 if (nowEndTime == now) return; //是当前这一个小时 now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0); if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; rgv521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!rgv521.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in rgv521) { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == start.Frame) //当天的第一条数据 { if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = info.WorkMode.GetDescription(), RunStatus = info.SystemStatus.GetDescription(), StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); else //如果有就用前一天的最后一条数据做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = yesterEnd.RunMode, RunStatus = yesterEnd.RunStatus, StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); } else //状态出现状态变化时或最后一条数据 { if (start.WorkMode != info.WorkMode || start.SystemStatus != info.SystemStatus || info.Frame == end.Frame) { var runInfo = new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = start.WorkMode.GetDescription(), RunStatus = start.SystemStatus.GetDescription(), StartTime = start.Frame, Type = type }; if (info.Frame == end.Frame) runInfo.EndTime = endTime; else runInfo.EndTime = info.Frame; runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds); runInfos.Add(runInfo); start = info; } } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } /// /// 桁架 /// /// public void ExTrussRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> truss521 = new List>(); var type = DevType.Truss.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); if (endTime > now) return; //当前时间之前 if (nowEndTime == now) return; //是当前这一个小时 now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0); if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; truss521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!truss521.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in truss521) { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == start.Frame) //当天的第一条数据 { if (yesterEnd == null) //如果没有前一天的最后一条数据,就有用当天的第一条数据状态做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = info.Status.GetDescription(), StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); else //如果有就用前一天的最后一条数据做计算 runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = yesterEnd.RunMode, RunStatus = yesterEnd.RunStatus, StartTime = startTime, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - startTime).TotalMilliseconds), Type = type }); } else //状态出现状态变化时或最后一条数据 { if (start.Status != info.Status || info.Frame == end.Frame) { var runInfo = new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = start.Status.GetDescription(), StartTime = start.Frame, Type = type }; if (info.Frame == end.Frame) runInfo.EndTime = endTime; else runInfo.EndTime = info.Frame; runInfo.Duration = Convert.ToInt64((runInfo.EndTime - runInfo.StartTime).TotalMilliseconds); runInfos.Add(runInfo); start = info; } } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } #endregion 设备运行信息收集 #region 异常报警信息 /// /// 机械臂 /// /// public void ExRobotAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> robot522 = new List>(); var type = DevType.Robot.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var alarmInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame.Date; endTime = startTime.AddDays(+1).AddMilliseconds(-1); } if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; robot522 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!robot522.Any()) plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = "当前时段无有效数据", Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); Parallel.ForEach(robot522, infos => { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); //需要保存的数据 var alarmList = new List(); //未结束的报警信息 foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == end.Frame) //最后一条数据 { if (info.Alarm != "无") { //先判断是否有没有记录的报警信息 var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); } if (!alarmList.Any()) continue; runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = endTime, Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds), Type = type })); } else { if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了 { runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type })); alarmList = new List(); //清空现有报警信息 } else if (info.Alarm != "无") { var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); var treatedAlarm = new List(); //将已记录,但当前信息中没有的报警结束 foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg))) { runInfos.Add(new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type }); treatedAlarm.Add(alarm.Msg); } alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); } } if (runInfos.Any()) { var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } else { plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = infos.Key, Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); } }); } /// /// 堆垛机 /// /// public void ExSrmAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> srm523 = new List>(); var type = DevType.SRM.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var alarmInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame.Date; endTime = startTime.AddDays(+1).AddMilliseconds(-1); } if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; srm523 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!srm523.Any()) plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = "当前时段无有效数据", Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); Parallel.ForEach(srm523, infos => { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); //需要保存的数据 var alarmList = new List(); //未结束的报警信息 foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == end.Frame) //最后一条数据 { if (info.Alarm != "无,无") { //先判断是否有没有记录的报警信息 var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).Where(x => x != "无").ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); } if (!alarmList.Any()) continue; runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = endTime, Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds), Type = type })); } else { if (info.Alarm == "无,无" && alarmList.Any()) //代表报警全部清空了 { runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type })); alarmList = new List(); //清空现有报警信息 } else if (info.Alarm != "无,无") { var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).Where(x => x != "无").ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); var treatedAlarm = new List(); //将已记录,但当前信息中没有的报警结束 foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg))) { runInfos.Add(new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type }); treatedAlarm.Add(alarm.Msg); } alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); } } if (runInfos.Any()) { var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } else { plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = infos.Key, Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); } }); } /// /// rgv /// /// public void ExRgvAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> rgv523 = new List>(); var type = DevType.RGV.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var alarmInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame.Date; endTime = startTime.AddDays(+1).AddMilliseconds(-1); } if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; rgv523 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!rgv523.Any()) plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = "当前时段无有效数据", Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); Parallel.ForEach(rgv523 /*.Where(x => x.Key == "RGV4")*/, infos => { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); //需要保存的数据 var alarmList = new List(); //未结束的报警信息 foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == end.Frame) //最后一条数据 { if (info.Alarm != "无") { //先判断是否有没有记录的报警信息 var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); } if (!alarmList.Any()) continue; runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = endTime, Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds), Type = type })); } else { if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了 { runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type })); alarmList = new List(); //清空现有报警信息 } else if (info.Alarm != "无") { var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); var treatedAlarm = new List(); //将已记录,但当前信息中没有的报警结束 foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg))) { runInfos.Add(new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type }); treatedAlarm.Add(alarm.Msg); } alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); } } if (runInfos.Any()) plcEx.Insertable(runInfos).ExecuteCommand(); else plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = infos.Key, Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); }); } /// /// Truss /// /// public void ExTrussAlarmInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> rgv523 = new List>(); var type = DevType.Truss.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var alarmInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = alarmInfo.Frame.AddDays(+1).Date; //后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame.Date; endTime = startTime.AddDays(+1).AddMilliseconds(-1); } if (endTime > DateTime.Now.AddHours(1)) return; //一次处理24小时的数据 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; rgv523 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!rgv523.Any()) plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = "当前时段无有效数据", Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); Parallel.ForEach(rgv523 /*.Where(x => x.Key == "RGV4")*/, infos => { // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (plcEx.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = plcEx.Queryable().Where(x => x.Code == infos.Key && x.Frame < endTime) .OrderByDescending(x => x.Frame).First(); var runInfos = new List(); //需要保存的数据 var alarmList = new List(); //未结束的报警信息 foreach (var info in infos.OrderBy(x => x.Frame)) if (info.Frame == end.Frame) //最后一条数据 { if (info.Alarm != "无") { //先判断是否有没有记录的报警信息 var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); } if (!alarmList.Any()) continue; runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = endTime, Duration = Convert.ToInt64((endTime - alarm.Time).TotalMilliseconds), Type = type })); } else { if (info.Alarm == "无" && alarmList.Any()) //代表报警全部清空了 { runInfos.AddRange(alarmList.Select(alarm => new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type })); alarmList = new List(); //清空现有报警信息 } else if (info.Alarm != "无") { var alarmMsg = Convert.ToString(info.Alarm).Split(",").Select(x => x.Split(",")) .SelectMany(x => x).ToList(); var msgList = alarmList.Select(x => x.Msg); //将未记录的报警信息增加到缓存中 alarmList.AddRange(alarmMsg.Where(msg => !msgList.Contains(msg)) .Select(msg => new EquipmentAlarm { Time = info.Frame, Msg = msg })); var treatedAlarm = new List(); //将已记录,但当前信息中没有的报警结束 foreach (var alarm in alarmList.Where(x => !alarmMsg.Contains(x.Msg))) { runInfos.Add(new DevAlarmInfo { Frame = alarm.Time, Code = info.Code, Alarm = alarm.Msg, StartTime = alarm.Time, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - alarm.Time).TotalMilliseconds), Type = type }); treatedAlarm.Add(alarm.Msg); } alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); } } if (runInfos.Any()) plcEx.Insertable(runInfos).ExecuteCommand(); else plcEx.Insertable(new DevAlarmInfo { Frame = endTime, Code = infos.Key, Alarm = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); }); } #endregion 异常报警信息 #region 任务状态分析 /// /// 机械臂分析单双爪任务占比,需要按照任务类型分类 /// /// public void ExRobotTaskSumRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> robot520 = new List>(); var type = DevType.RobotTaskSum.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type).OrderByDescending(x => x.Frame) .First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); if (endTime > now) return; //当前时间之前 if (nowEndTime == now) return; //是当前这一个小时 now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 10, 0); if (DateTime.Now < now) return; // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; robot520 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!robot520.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in robot520) { var infoList = infos.Where(x => x.TaskNumber1 != 0 || x.TaskNumber2 != 0).ToList() .DistinctItemBy(x => x.VoucherNo); var runInfos = new List(); foreach (var info in infoList.OrderBy(x => x.Frame)) { var taskSum = 0; if (info.TaskNumber1 != 0) taskSum += 1; if (info.TaskNumber2 != 0) taskSum += 1; runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = taskSum.ToString(), RunStatus = $"{info.TaskNumber1}--{info.TaskNumber2}--{info.TaskType}", Duration = 0, Type = type }); } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } /// /// 桁架分析单双爪任务占比,需要按照任务类型分类 /// /// public void ExTrussTaskSumRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { try { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> truss520 = new List>(); var type = DevType.TrussTaskSum.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (plcEx.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = plcEx.Queryable().Where(x => x.Type == type) .OrderByDescending(x => x.Frame).First(); startTime = runInfo.Frame.AddHours(+1); //后一个小时 startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); // } else { if (db.Queryable().Count() <= 0) return; startTime = db.Queryable().OrderBy(x => x.Frame).First().Frame; startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0); //后一个小时的开始时间 endTime = startTime.AddHours(+1).AddMilliseconds(-1); } //取上一小时的第一秒 var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0); var nowEndTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0); //当前时间之前 if (endTime > now) throw new KnownException("当前时间之前", LogLevelEnum.High); //是当前这一个小时 if (nowEndTime == now) throw new KnownException("是当前这一个小时", LogLevelEnum.High); now = new DateTime(now.Year, now.Month, now.Day, now.Hour, 1, 0); // 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (DateTime.Now < now) throw new KnownException("每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理", LogLevelEnum.High); if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) throw new KnownException("当前小时有数据", LogLevelEnum.High); truss520 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList() .GroupBy(x => x.Code).ToList(); if (!truss520.Any()) plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); foreach (var infos in truss520) { var infoList = infos.Where(x => x.Task1_1 != 0 || x.Task1_2 != 0 || x.Task1_3 != 0 || x.Task1_4 != 0 || x.Task1_5 != 0 || x.Task2_1 != 0 || x.Task2_2 != 0 || x.Task2_3 != 0 || x.Task2_4 != 0 || x.Task2_5 != 0) .ToList().DistinctItemBy(x => x.VoucherNo); var runInfos = new List(); foreach (var info in infoList.OrderBy(x => x.Frame)) { var taskSum = 0; if (info.Task1_1 != 0) taskSum += 1; if (info.Task1_2 != 0) taskSum += 1; if (info.Task1_3 != 0) taskSum += 1; if (info.Task1_4 != 0) taskSum += 1; if (info.Task1_5 != 0) taskSum += 1; if (info.Task2_1 != 0) taskSum += 1; if (info.Task2_2 != 0) taskSum += 1; if (info.Task2_3 != 0) taskSum += 1; if (info.Task2_4 != 0) taskSum += 1; if (info.Task2_5 != 0) taskSum += 1; runInfos.Add(new DevRunInfo { Frame = info.Frame, Code = info.Code, RunMode = taskSum.ToString(), RunStatus = $"{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}", Duration = 0, Type = type }); } if (!runInfos.Any()) { plcEx.Insertable(new DevRunInfo { Frame = endTime, Code = infos.Key, RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); continue; } var sql = plcEx.Insertable(runInfos).ToSqlString(); plcEx.Ado.ExecuteCommand(GetString(sql)); } } catch (Exception e) { Console.WriteLine(e); throw new KnownException($"{e.Message}:{e.StackTrace}", LogLevelEnum.High); } } #endregion 任务状态分析 } /// /// 数据清理 /// public class FeedRateDto(short day, short hour, short minute, short number, DateTime frame, string code) { /// /// 天 /// public short Day { get; set; } = day; /// /// 小时 /// public short Hour { get; set; } = hour; /// /// 分钟 /// public short Minute { get; set; } = minute; /// /// 数量 /// public short Number { get; set; } = number; /// /// 时间 /// public DateTime Frame { get; set; } = frame; /// /// 设备号 /// public string Code { get; set; } = code; } /// /// 设备报警 /// public class EquipmentAlarm { /// /// 内容 /// public string Msg { get; set; } /// /// 时间 /// public DateTime Time { get; set; } } /// /// 设备状态信息 /// public class EquipmentStatus { /// /// 设备号 /// public string Code { get; set; } /// /// 内容 /// public string con { get; set; } /// /// 内容 /// public int Status { get; set; } /// /// 时间 /// public DateTime Time { get; set; } } /// /// /// public class Quest { public T Data { get; set; } } public class KeyValue { public string key { get; set; } public string value { get; set; } }