using ServiceCenter.Extensions; using ServiceCenter.SqlSugars; using SqlSugar; using System.Collections.Concurrent; using System.ComponentModel; using System.Data; using WCS.Core; using WCS.Entity.Protocol.DataStructure; using WCS.Entity.Protocol.HUB; using WCS.Entity.Protocol.Robot; using WCS.Entity.Protocol.SRM; using WCS.Entity.Protocol.Station; 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); //ExRobotAlarmInfo(db); //ExSrmAlarmInfo(db); //ExRgvAlarmInfo(db); ExSrmTaskSumRunInfo(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.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().Any()) 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; 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(); 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.Mode.GetDescription(), RunStatus = 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.Mode != info.Mode || start.Status != info.Status || info.Frame == end.Frame) { var runInfo = new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.Mode.GetDescription(), RunStatus = 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)); } } /// /// 堆垛机 /// /// 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().Any()) 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(); 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.Mode.GetDescription(), RunStatus = 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.Mode != info.Mode || start.Status != info.Status || info.Frame == end.Frame) { var runInfo = new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = start.Mode.GetDescription(), RunStatus = 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) //{ // var startTime = DateTime.Now; // var endTime = DateTime.Now; // IEnumerable> robot522 = new List>(); // //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 // if (db.Queryable().Any(x => x.Type == DevType.Robot)) // { // //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 // var alarmInfo = db.Queryable().Where(x => x.Type == DevType.Robot).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 (db.Queryable().Any(x => x.EndTime == endTime && x.Type == DevType.Robot)) return; // robot522 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); // if (!robot522.Any()) // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = "当前时段无有效数据", // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.Robot // }).ExecuteCommand(); // } // Parallel.ForEach(robot522, infos => // { // // 获取第一条数据与最后一条数据 // var start = infos.OrderBy(x => x.Frame).First(); // var end = infos.OrderByDescending(x => x.Frame).First(); // //通过是否有最后一条数据来确定当前数据是否有分析存储过 // if (db.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; // //获取前一天最后的一条数据 // var yesterEnd = db.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 = DevType.Robot // })); // } // 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 = DevType.Robot // })); // 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 = DevType.Robot // }); // treatedAlarm.Add(alarm.Msg); // } // alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); // } // } // } // if (runInfos.Any()) // { // var sql = db.Insertable(runInfos).ToSqlString(); // db.Ado.ExecuteCommand(GetString(sql)); // } // else // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = infos.Key, // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.Robot // }).ExecuteCommand(); // } // }); //} ///// ///// 堆垛机 ///// ///// //public void ExSrmAlarmInfo(SqlSugarScopeProvider db) //{ // var startTime = DateTime.Now; // var endTime = DateTime.Now; // IEnumerable> srm523 = new List>(); // //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 // if (db.Queryable().Any(x => x.Type == DevType.SRM)) // { // //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 // var alarmInfo = db.Queryable().Where(x => x.Type == DevType.SRM).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 (db.Queryable().Any(x => x.EndTime == endTime && x.Type == DevType.SRM)) return; // srm523 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); // if (!srm523.Any()) // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = "当前时段无有效数据", // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.SRM // }).ExecuteCommand(); // } // Parallel.ForEach(srm523, infos => // { // // 获取第一条数据与最后一条数据 // var start = infos.OrderBy(x => x.Frame).First(); // var end = infos.OrderByDescending(x => x.Frame).First(); // //通过是否有最后一条数据来确定当前数据是否有分析存储过 // if (db.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; // //获取前一天最后的一条数据 // var yesterEnd = db.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 = DevType.SRM // })); // } // 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 = DevType.SRM // })); // 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 = DevType.SRM // }); // treatedAlarm.Add(alarm.Msg); // } // alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); // } // } // } // if (runInfos.Any()) // { // var sql = db.Insertable(runInfos).ToSqlString(); // db.Ado.ExecuteCommand(GetString(sql)); // } // else // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = infos.Key, // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.SRM // }).ExecuteCommand(); // } // }); //} ///// ///// rgv ///// ///// //public void ExRgvAlarmInfo(SqlSugarScopeProvider db) //{ // var startTime = DateTime.Now; // var endTime = DateTime.Now; // IEnumerable> rgv523 = new List>(); // //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 // if (db.Queryable().Any(x => x.Type == DevType.RGV)) // { // //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 // var alarmInfo = db.Queryable().Where(x => x.Type == DevType.RGV).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 (db.Queryable().Any(x => x.EndTime == endTime && x.Type == DevType.RGV)) return; // rgv523 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); // if (!rgv523.Any()) // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = "当前时段无有效数据", // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.RGV // }).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 (db.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; // //获取前一天最后的一条数据 // var yesterEnd = db.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 = DevType.RGV // })); // } // 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 = DevType.RGV // })); // 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 = DevType.RGV // }); // treatedAlarm.Add(alarm.Msg); // } // alarmList = alarmList.Where(x => !treatedAlarm.Contains(x.Msg)).ToList(); // } // } // } // if (runInfos.Any()) // { // db.Insertable(runInfos).ExecuteCommand(); // } // else // { // db.Insertable(new DevAlarmInfo() // { // Frame = endTime, // Code = infos.Key, // Alarm = "当前时段无有效数据", // StartTime = startTime, // EndTime = endTime, // Duration = Convert.ToInt64((endTime - startTime).TotalMilliseconds), // Type = DevType.RGV // }).ExecuteCommand(); // } // }); //} #endregion 异常报警信息 #region 任务状态分析 /// /// 机械臂 /// /// public void ExRobotTaskSumRunInfo(SqlSugarScopeProvider db) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> robot520 = new List>(); var type = DevType.RobotTaskSum.ToString(); //查看rgv类型是否存在运行信息,用于系统被第一次启用时进行初始化 if (db.Queryable().Any(x => x.Type == type)) { //已有信息,查找最后一条信息用于获取开始时间,最后一条通常是前一天的最后条数据 var runInfo = db.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 (db.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()) { db.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 => { //infos = infos.Where(x => x.TaskNumber1 != 0 || x.TaskNumber2 != 0).ToList(); // 获取第一条数据与最后一条数据 var start = infos.OrderBy(x => x.Frame).First(); var end = infos.OrderByDescending(x => x.Frame).First(); //通过是否有最后一条数据来确定当前数据是否有分析存储过 if (db.Queryable().Any(x => x.Code == infos.Key && x.EndTime == end.Frame)) return; //获取前一天最后的一条数据 var yesterEnd = db.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 = DevType.RobotTaskSum // }); // } // 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 = DevType.RobotTaskSum // }); // } // } // 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 = DevType.RobotTaskSum // }); // } // 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 = DevType.RobotTaskSum // }); // start = info; // } //} var sql = db.Insertable(runInfos).ToSqlString(); db.Ado.ExecuteCommand(GetString(sql)); }); } /// /// 堆垛机任务数量统计 /// /// public void ExSrmTaskSumRunInfo(SqlSugarScopeProvider db, SqlSugarScopeProvider plcEx) { var startTime = DateTime.Now; var endTime = DateTime.Now; IEnumerable> srm520 = new List>(); var type = DevType.SrmTaskSum.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, 01, 0); if (DateTime.Now < now) return;// 每个小时的前十分钟不进行数据分析处理,仅在每小时的10-59之内进行处理 if (plcEx.Queryable().Any(x => x.EndTime == endTime && x.Type == type)) return; srm520 = db.Queryable().Where(x => x.Frame > startTime && x.Frame <= endTime).ToList().GroupBy(x => x.Code).ToList(); if (!srm520.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 srm520) { var infoList = infos.Where(x => x.TaskID1 != 0 || x.TaskID2 != 0).ToList().DistinctItemBy(x => x.VoucherNo); List runInfos = new List(); foreach (var info in infoList.OrderBy(x => x.Frame)) { var taskSum = 0; if (info.TaskID1 != 0) taskSum += 1; if (info.TaskID2 != 0) taskSum += 1; var taskType = info.TaskType1 == 0 ? info.TaskType2 : info.TaskType1; runInfos.Add(new DevRunInfo() { Frame = info.Frame, Code = info.Code, RunMode = taskSum.ToString(), RunStatus = $"{info.TaskID1}--{info.TaskID2}--{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; } } }