123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- using OfficeOpenXml.VBA;
- using ProductionLineMonitor.Application.Services.FaultService.Dtos;
- using ProductionLineMonitor.Application.Services.LineService.Dtos;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Threading;
- using System.Timers;
- namespace ProductionLineMonitor.Web.Services.LineService
- {
- /// <summary>
- /// 产线详情
- /// </summary>
- public class ProductionLineViewModel
- {
- public ProductionLineViewModel() { }
- public ProductionLineViewModel(int floor, int line, string date, string topic, string lineName)
- {
- Floor = floor;
- Line = line;
- Date = date;
- LineName = lineName;
- ProductionPlans = MesApiService.GetProductionPlansV1(Floor, Line, Date);
- KeyInInfos = MesApiService.GetKeyInInfos(Floor, Line, Date);
- HourKeyInInfos = GetHourKeyInInfos(KeyInInfos);
- try
- {
- DateTime dateTime = Convert.ToDateTime($"{date} 08:00:00");
- DateTime[] m = new DateTime[] { dateTime, dateTime.AddHours(12), dateTime.AddHours(24) };
- MorningReplaceConsumables = AccumulativeReplaceConsumableTime(KeyInInfos.Where(x => x.StartTime >= m[0] && x.StartTime < m[1]));
- NightReplaceConsumables = AccumulativeReplaceConsumableTime(KeyInInfos.Where(x => x.StartTime >= m[1] && x.StartTime < m[2]));
- }
- catch (Exception)
- {
- return;
- }
- MachineViewModel machineViewModel = new MachineViewModel(
- topic, date,
- KeyInInfos,
- ProductionPlans, true);
- if (machineViewModel.Statistics.Count() == 0)
- {
- return;
- }
- ModuleType = machineViewModel.Statistics.Last().ModuleType;
- Capa = machineViewModel.Statistics.Last().Capa;
- Capacity = machineViewModel.Statistics.Last().Capacity;
- PlanCapacity = machineViewModel.Statistics.Last().PlanCapacity;
- OEE = machineViewModel.Statistics.Last().OEE;
- Statistics = machineViewModel.Statistics;
- LoadOutPutPerHours = machineViewModel.LoadOutPutPerHours;
- NewOutPutPerHours = machineViewModel.NewOutPutPerHours;
- UpdateDown();
- }
- private List<ReplaceConsumable> AccumulativeReplaceConsumableTime(IEnumerable<KeyInInfo> keyInInfos)
- {
- List<ReplaceConsumable> rev = new List<ReplaceConsumable>();
- foreach (var keyInInfo in keyInInfos)
- {
- if (keyInInfo.KeyInType != 8)
- {
- continue;
- }
- var temp = rev.Find(x => x.Name == keyInInfo.Description);
- if (temp != null)
- {
- temp.Count += 1;
- temp.AccumulativeTime += keyInInfo.AffectTime;
- }
- else
- {
- var replaceConsumable = new ReplaceConsumable()
- {
- Name = keyInInfo.Description,
- Count = 1,
- AccumulativeTime = keyInInfo.AffectTime
- };
- rev.Add(replaceConsumable);
- }
- }
- return rev;
- }
- private IEnumerable<KeyInInfo> GetHourKeyInInfos(List<KeyInInfo> keyInInfos)
- {
- IList<KeyInInfo> dtos = new List<KeyInInfo>();
- foreach (var key in keyInInfos)
- {
- if (key.StartTime == null || key.EndTime == null)
- continue;
- IList<DateTime> dateTimes = new List<DateTime>
- {
- key.StartTime.Value
- };
- DateTime d1 = key.StartTime.Value;
- int j = 1;
- while (d1 < key.EndTime.Value)
- {
- d1 = key.StartTime.Value.AddHours(j);
- DateTime d2 = Convert.ToDateTime($"{d1:yyyy-MM-dd HH}:00:00");
- j++;
- if (d2 < key.EndTime.Value)
- {
- dateTimes.Add(d2);
- }
- }
- dateTimes.Add(key.EndTime.Value);
- for (int i = 0; i < dateTimes.Count - 1; i++)
- {
- KeyInInfo dto = new KeyInInfo
- {
- KeyInType = key.KeyInType,
- Description = key.Description,
- Id = key.Id,
- StartTime = dateTimes[i],
- EndTime = dateTimes[i + 1]
- };
- dto.AffectTime = (int)(dto.EndTime - dto.StartTime).Value.TotalMinutes;
- if (dto.AffectTime > 1)
- {
- dtos.Add(dto);
- }
- }
- }
- return dtos;
- }
- private void UpdateDown()
- {
- if (Statistics != null)
- {
- if (Statistics.Count == 1)
- {
- Statistics[0].Reload = KeyInInfos.Where(x => x.KeyInType == 8).Sum(x => x.AffectTime);
- double d = Statistics[0].IdelTime - Statistics[0].Reload;
- if (d < 0)
- d = 0;
- Statistics[0].DownTime += d;
- }
- else
- {
- foreach (var item in Statistics)
- {
- var outs = NewOutPutPerHours.Where(x => x.ModuleType != "" && x.ModuleType[..8] == item.ModuleType).ToList();
- if (outs.Count() > 0)
- {
- DateTime start = outs[0].DataTime;
- DateTime end = outs.Last().DataTime.AddHours(1);
- item.Reload = KeyInInfos.Where(
- x => x.KeyInType == 8 && x.StartTime >= start && x.StartTime.Value < end).Sum(x => x.AffectTime);
- double d = item.IdelTime - item.Reload;
- if (d < 0)
- d = 0;
- item.DownTime += d;
- }
- }
- }
- }
- }
- private void CheckFault()
- {
- DateTime startTime = Convert.ToDateTime($"{Date} 08:00:00");
- DateTime endTime = startTime.AddDays(1);
- foreach (var item in Machines)
- {
- FaultStatistic faultStatistic = new FaultStatistic();
- faultStatistic.Name = item.Type;
- switch (item.Type)
- {
- case "AG":
- faultStatistic.Name = "AG + FPL";
- List<LineDayFaultRecord> tempFaults = new List<LineDayFaultRecord>();
- tempFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "FPL", endTime));
- tempFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "FPL01", endTime));
- tempFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "FPL02", endTime));
- tempFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "FPL03", endTime));
- tempFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "FPL04", endTime));
- double time1 = tempFaults.Sum(x => x.Duration);
- double time2 = item.Statistics.Sum(x => x.DownTime);
- faultStatistic.DownTime = Math.Round(time1 + time2);
- break;
- case "FOG":
- // 在 FOG 前增加COG
- List<LineDayFaultRecord> tempCogFaults = new List<LineDayFaultRecord>();
- tempCogFaults.AddRange(getKeyInLineDayFaultRecord(Floor, Line, Date, "COG", endTime));
- FaultStatistic cog = new FaultStatistic
- {
- Name = "COG",
- DownTime = Math.Round(tempCogFaults.Sum(x => x.Duration))
- };
- FaultStatistics.Add(cog);
- // FOG 故障时间
- faultStatistic.DownTime = Math.Round(item.Statistics.Sum(x => x.DownTime));
- break;
- default:
- faultStatistic.DownTime = Math.Round(item.Statistics.Sum(x => x.DownTime));
- break;
- }
- FaultStatistics.Add(faultStatistic);
- }
- }
- private List<LineDayFaultRecord> getKeyInLineDayFaultRecord(int floor, int line, string date, string type, DateTime endTime)
- {
- List<LineDayFaultRecord> lineDayFaultRecords = new List<LineDayFaultRecord>();
- var fs = MesApiService.GetKeyInFaults(floor, line, date, type);
- foreach (var f in fs)
- {
- LineDayFaultRecord fLineDayFaultRecord = new LineDayFaultRecord
- {
- MechineName = type,
- FaultCode = f.FaultCode,
- FaultInfo = f.FaultInfo,
- StartTime = f.StartTime,
- DataSource = 1
- };
- if (f.EndTime == null)
- fLineDayFaultRecord.EndTime = endTime;
- else
- fLineDayFaultRecord.EndTime = f.EndTime.Value;
- fLineDayFaultRecord.Duration = (fLineDayFaultRecord.EndTime.Value - fLineDayFaultRecord.StartTime).TotalMinutes;
- lineDayFaultRecords.Add(fLineDayFaultRecord);
- }
- return lineDayFaultRecords;
- }
- private void CheckModuleType()
- {
- if (ModuleType != null && ModuleType != "")
- {
- if (ProductionPlans
- .Where(x => x.ModuleType.Length >= 8)
- .Where(x => x.ModuleType.Substring(0, 8) == ModuleType).Count() == 0)
- {
- State = 99;
- StateMessage = "生产机种与排程不符";
- }
- }
- }
- public virtual void CheckState()
- {
- DateTime now = DateTime.Now;
- DateTime time = Convert.ToDateTime($"{Date} {now:HH:mm:ss}");
- if (time.Day != now.Day || time.Year != now.Year || time.Month != now.Month)
- {
- time = Convert.ToDateTime($"{Date} 07:59:00").AddDays(1);
- }
- foreach (var item in KeyInInfos)
- {
- if (item.KeyInType == 2 || item.KeyInType == 3 || item.KeyInType == 4 ||
- item.KeyInType == 6 || item.KeyInType == 7 || item.KeyInType == 9)
- {
- if (time >= item.StartTime && time <= item.EndTime)
- {
- State = item.KeyInType;
- StateMessage = item.Description;
- return;
- }
- }
- }
- if (ProductionPlans.Count == 0)
- {
- State = 11;
- StateMessage = "";
- return;
- }
- if (ProductionPlans.Count == 1)
- {
- if (ProductionPlans[0].ModuleType == "未指定")
- {
- State = 11;
- StateMessage = "";
- return;
- }
- }
- State = 99;
- StateMessage = "";
- }
- public int Floor { get; set; }
- public int Line { get; set; }
- public string LineName { get; set; } = string.Empty;
- public string Date { get; set; } = string.Empty;
- private int _state = -1;
- public int State
- {
- get { return _state; }
- set
- {
- /// 0:品质异常停线
- /// ---------------1:宕机
- /// 2:换线
- /// 3:实验
- /// 4:W/F送样
- /// ---------------5:物料缺料或生管调整影响
- /// 6:放假
- /// 7:停电气等停线
- /// ---------------8:换耗材类
- /// 9:停机未生产
- /// ----------------10:效率爬升
- _state = value;
- switch (_state)
- {
- case 0: StateName = "品质异常停线"; break;
- case 1: break;
- case 2: StateName = "换线"; break;
- case 3: StateName = "实验"; break;
- case 4: StateName = "W/F送样"; break;
- case 5: break;
- case 6: StateName = "放假"; break;
- case 7: StateName = "停电气等停线"; break;
- case 8: break;
- case 9: StateName = "停机未生产"; break;
- case 10: break;
- case 11: StateName = "未排产"; break;
- default: StateName = "正常生产"; break;
- }
- }
- }
- public string StateName { get; set; } = string.Empty;
- /// <summary>
- /// 状态描述
- /// </summary>
- public string StateMessage { get; set; } = string.Empty;
- /// <summary>
- /// 机种
- /// </summary>
- public string ModuleType { get; set; } = string.Empty;
- /// <summary>
- /// Capa
- /// </summary>
- public int Capa { get; set; }
- /// <summary>
- /// 计划产能
- /// </summary>
- public int PlanCapacity { get; set; }
- /// <summary>
- /// 产能
- /// </summary>
- public int Capacity { get; set; }
- /// <summary>
- /// OEE
- /// </summary>
- public double OEE { get; set; }
- public double TheoryRefueledTime { get; set; }
- /// <summary>
- /// 生产计划
- /// </summary>
- public List<ProductionPlanDtoV1> ProductionPlans { get; set; }
- = new List<ProductionPlanDtoV1>();
- /// <summary>
- /// key in 的异常
- /// </summary>
- public List<KeyInInfo> KeyInInfos { get; set; }
- = new List<KeyInInfo>();
- public IEnumerable<KeyInInfo> HourKeyInInfos { get; set; }
- = new List<KeyInInfo>();
- /// <summary>
- /// 小时产能
- /// </summary>
- public List<MachineDayOutPutPerHour> LoadOutPutPerHours { get; set; }
- = new List<MachineDayOutPutPerHour>();
- /// <summary>
- /// 清理后小时产能
- /// </summary>
- public List<NewMachineDayOutPutPerHour> NewOutPutPerHours { get; set; }
- = new List<NewMachineDayOutPutPerHour>();
- /// <summary>
- /// 统计
- /// </summary>
- public List<Statistic> Statistics { get; set; }
- = new List<Statistic>();
- /// <summary>
- /// 机台
- /// </summary>
- public List<MachineViewModel> Machines { get; set; }
- = new List<MachineViewModel>();
- /// <summary>
- /// key in 故障
- /// </summary>
- public List<LineDayFaultRecord> KeyInFaults { get; set; }
- = new List<LineDayFaultRecord>();
- public List<FaultStatistic> FaultStatistics { get; set; }
- = new List<FaultStatistic>();
- public class FaultStatistic
- {
- public string Name { get; set; } = string.Empty;
- public double DownTime { get; set; }
- }
- public List<ReplaceConsumable> ReplaceConsumables { get; set; }
- = new List<ReplaceConsumable>();
- public List<ReplaceConsumable> MorningReplaceConsumables { get; set; }
- = new List<ReplaceConsumable>();
- public List<ReplaceConsumable> NightReplaceConsumables { get; set; }
- = new List<ReplaceConsumable>();
- }
- }
|