using Microsoft.AspNetCore.DataProtection.KeyManagement; using ServiceCenter.Extensions; using ServiceCenter.SqlSugars; using SqlSugar; using System.Collections.Concurrent; using System.ComponentModel; using System.Data; using System.Reflection; using System.Text; using PlcSiemens.Core.Extension; using WCS.Core; using WCS.Entity.Protocol.DataStructure; using WCS.Entity.Protocol.HUB; using WCS.Entity.Protocol.Protocol.Robot; 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 DeviceDataPack(); private static object locker = new object(); public DataCollectionSysyem() { } /// /// 所有设备数据 /// Key 是不同设备所使用的类型 例如DeviceDataCollection /// value 不同设备的具体数据 /// public static ConcurrentDictionary AllDatas = new ConcurrentDictionary(); 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); } #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.AddDays(+1).Date;//后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1);// } else { if (!db.Queryable().Any()) 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; 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(); } Parallel.ForEach(robot521, 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(); List 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.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 (info.Frame == end.Frame) //当天的最后一条数据 { runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = info.RobotMode.GetDescription(), RunStatus = info.RunStatus.GetDescription(), StartTime = info.Frame, EndTime = endTime, Duration = Convert.ToInt64((endTime - info.Frame).TotalMilliseconds), Type = type }); } else //中间数据 { if (start.RobotMode == info.RobotMode && start.RunStatus == info.RunStatus) continue; runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.RobotMode.GetDescription(), RunStatus = start.RunStatus.GetDescription(), StartTime = start.Frame, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - start.Frame).TotalMilliseconds), Type = type }); 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.AddDays(+1).Date;//后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1);// } else { if (!db.Queryable().Any()) 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; 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(); } Parallel.ForEach(srm521, 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(); List 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 (info.Frame == end.Frame) //当天的最后一条数据 { runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = info.AutoStatus.GetDescription(), RunStatus = info.RunStatus.GetDescription(), StartTime = info.Frame, EndTime = endTime, Duration = Convert.ToInt64((endTime - info.Frame).TotalMilliseconds), Type = type }); } else //中间数据 { if (start.AutoStatus == info.AutoStatus && start.RunStatus == info.RunStatus) continue; runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.AutoStatus.GetDescription(), RunStatus = start.RunStatus.GetDescription(), StartTime = start.Frame, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - start.Frame).TotalMilliseconds), Type = type }); 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.AddDays(+1).Date;//后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1);// } else { if (!db.Queryable().Any()) 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; rgv521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); if (!rgv521.Any()) { db.Insertable(new DevRunInfo() { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); } Parallel.ForEach(rgv521, 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(); List 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 (info.Frame == end.Frame) //当天的最后一条数据 { runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = info.WorkMode.GetDescription(), RunStatus = info.SystemStatus.GetDescription(), StartTime = info.Frame, EndTime = endTime, Duration = Convert.ToInt64((endTime - info.Frame).TotalMilliseconds), Type = type }); } else //中间数据 { if (start.WorkMode == info.WorkMode && start.SystemStatus == info.SystemStatus) continue; runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.WorkMode.GetDescription(), RunStatus = start.SystemStatus.GetDescription(), StartTime = start.Frame, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - start.Frame).TotalMilliseconds), Type = type }); 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.AddDays(+1).Date;//后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1);// } else { if (!db.Queryable().Any()) 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; truss521 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); if (!truss521.Any()) { db.Insertable(new DevRunInfo() { Frame = endTime, Code = "当前时段无有效数据", RunMode = "当前时段无有效数据", RunStatus = "当前时段无有效数据", StartTime = startTime, EndTime = endTime, Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), Type = type }).ExecuteCommand(); } Parallel.ForEach(truss521, 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(); List 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 (info.Frame == end.Frame) //当天的最后一条数据 { runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = info.Status.GetDescription(), StartTime = info.Frame, EndTime = endTime, Duration = Convert.ToInt64((endTime - info.Frame).TotalMilliseconds), Type = type }); } else //中间数据 { if (start.Status == info.Status) continue; runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.Status.GetDescription(), StartTime = start.Frame, EndTime = info.Frame, Duration = Convert.ToInt64((info.Frame - start.Frame).TotalMilliseconds), Type = type }); 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().Any()) 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(); List 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().Any()) 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(); List 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().Any()) 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(); List 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().Any()) 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(); List 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.AddDays(+1).Date;//后一天的初始时间 endTime = startTime.AddDays(+1).AddMilliseconds(-1);// } else { if (!db.Queryable().Any()) 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; 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(); } Parallel.ForEach(robot520, infos => { var infoList = infos.Where(x => x.TaskNumber1 != 0 || x.TaskNumber2 != 0).ToList().DistinctItemBy(x => x.VoucherNo); List 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)); }); } #endregion 任务状态分析 public string GetString(string value) { return value.Replace(",N'", ",'") .Replace("\0", "") .Replace("(N'", "('") + "\r"; } } /// /// 设备报警 /// 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; } } }