123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- using NPOI.SS.Formula.Functions;
- using NPOI.XWPF.UserModel;
- using ProductionLineMonitor.Application.Services.LineService.Dtos;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- namespace ProductionLineMonitor.Web.Services.LineService
- {
- /// <summary>
- /// 机台
- /// </summary>
- public class MachineViewModel
- {
- public MachineViewModel()
- {
- }
- public MachineViewModel(string topic, string date, List<KeyInInfo> keyInInfos,
- List<ProductionPlanDtoV1> productionPlans, bool isLine)
- {
- CurrentTime = DateTime.Now;
- Date = date;
- if (!isLine)
- AnalysisTopic(topic);
- else
- Topic = topic;
- ProductionPlans = productionPlans;
- KeyInInfos = keyInInfos;
- LoadOutPutPerHours = MesApiService.GetOutPutPerHours(Topic, Date);
- if (LoadOutPutPerHours.Count() < 24)
- {
- Statistics = new List<Statistic>();
- return;
- }
- WashOutPutPerHours();
- CalculateV1();
- }
- /// <summary>
- /// 解析Topic
- /// </summary>
- /// <param name="topic"></param>
- protected void AnalysisTopic(string topic)
- {
- Topic = topic;
- int index = topic.IndexOf('-');
- Floor = Convert.ToInt16(topic.Substring(index + 1, 1));
- Line = Convert.ToInt16(topic.Substring(index - 2, 2));
- index = topic.IndexOf("Data");
- Type = topic[..index];
- }
- private string _date = string.Empty;
- /// <summary>
- /// 日期
- /// </summary>
- public string Date
- {
- get
- {
- return _date;
- }
- set
- {
- _date = value;
- StartTime = Convert.ToDateTime($"{_date} 08:00:00");
- EndTime = StartTime.AddDays(1);
- }
- }
- public DateTime StartTime { get; set; }
-
- public DateTime EndTime { get; set; }
- /// <summary>
- /// 当前时间
- /// </summary>
- public DateTime CurrentTime { get; set; }
- /// <summary>
- /// topic
- /// </summary>
- public string Topic { get; set; } = string.Empty;
- /// <summary>
- /// 楼层
- /// </summary>
- public int Floor { get; set; }
- /// <summary>
- /// 线别
- /// </summary>
- public int Line { get; set; }
- /// <summary>
- /// 类型
- /// </summary>
- public string Type { get; set; } = string.Empty;
- /// <summary>
- /// 生产计划
- /// </summary>
- public List<ProductionPlanDtoV1> ProductionPlans { get; set; }
- = new List<ProductionPlanDtoV1>();
- /// <summary>
- /// key in 的异常
- /// </summary>
- public List<KeyInInfo> KeyInInfos { 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 void UpdateModuleType()
- {
- if (Type != "AG"
- && Type != "FPL"
- && Type != "BT"
- && Type != "PS"
- && Type != "EC"
- && Type != "TP")
- return;
- string topic = $"FOGData#{Line}#{Line}-{Floor}FOG01";
- if (Line < 10)
- topic = $"FOGData#{Line}#0{Line}-{Floor}FOG01";
- var outs = MesApiService.GetOutPutPerHours(topic, Date);
- foreach (var item in outs)
- {
- var t = LoadOutPutPerHours.Find(x => x.DataTime == item.DataTime);
- if (t != null)
- t.ModuleType = item.ModuleType;
- }
- }
- /// <summary>
- /// 根据 key in 时间清洗小时产能
- /// </summary>
- public void WashOutPutPerHours()
- {
- /*
- 0: 品质异常停线
- 1: 宕机
- 2: 换线
- 3: 实验
- 4: W/F送样
- 5: 物料缺料或生管调整影响
- 6: 放假
- 7: 停电气等停线
- 8: 换耗材类
- 9: 停机未生产
- 10: 效率爬升
- */
- NewOutPutPerHours = new List<NewMachineDayOutPutPerHour>();
- if (LoadOutPutPerHours == null)
- {
- return;
- }
- if (LoadOutPutPerHours.Count() == 0)
- {
- return;
- }
- foreach (var item in LoadOutPutPerHours)
- {
- NewMachineDayOutPutPerHour outPutPerHour = new NewMachineDayOutPutPerHour()
- {
- DataTime = item.DataTime,
- ModuleType = item.ModuleType,
- OutPut = item.OutPut,
- AutoRunTime = item.AutoRunTime,
- AlarmTime = item.AlarmTime,
- IdleTime = item.IdleTime,
- IdleTimeDownstream = item.IdleTimeDownstream,
- IdleTimeUpstream = item.IdleTimeUpstream,
- AlarmSum = item.AlarmSum,
- IdleTimeSelf = item.IdleTimeSelf,
- TargetTT = item.TargetTT,
- ActualTT = item.ActualTT,
- LoadMATSum = item.LoadMATSum,
- LoadMATTime = item.LoadMATTime,
- LoadTime = 0,
- };
- if (item.DataTime > DateTime.Now)
- {
- outPutPerHour.ModuleType = "";
- }
- NewOutPutPerHours.Add(outPutPerHour);
- }
- if (NewOutPutPerHours.Count == 0)
- return;
- foreach (var key in KeyInInfos)
- {
- if (key.KeyInType == 2 || key.KeyInType == 3 || key.KeyInType == 4 ||
- key.KeyInType == 6 || key.KeyInType == 7 || key.KeyInType == 9)
- {
- if (key.StartTime == null)
- continue;
- if (key.EndTime == null || key.EndTime.Value.Year < 2000)
- {
- if (key.StartTime.Value.Hour >= 0 || key.StartTime.Value.Hour <= 7)
- key.EndTime = Convert.ToDateTime($"{key.StartTime.Value:yyyy-MM-dd} 08:00:00");
- else
- key.EndTime = Convert.ToDateTime($"{key.StartTime.Value.AddDays(1):yyyy-MM-dd} 08:00:00");
- if (key.EndTime > EndTime)
- key.EndTime = EndTime;
- }
- var ds = GetLoadTime(key.StartTime.Value, key.EndTime.Value);
- for (int i = 0; i < ds.Length; i++)
- {
- if (ds[i] > 0)
- {
- if (ds[i] == 60)
- {
- NewOutPutPerHours[i].ModuleType = "";
- NewOutPutPerHours[i].OutPut = 0;
- NewOutPutPerHours[i].AutoRunTime = 0;
- NewOutPutPerHours[i].AlarmTime = 0;
- NewOutPutPerHours[i].IdleTime = 0;
- NewOutPutPerHours[i].IdleTimeDownstream = 0;
- NewOutPutPerHours[i].IdleTimeUpstream = 0;
- NewOutPutPerHours[i].AlarmSum = 0;
- NewOutPutPerHours[i].IdleTimeSelf = 0;
- NewOutPutPerHours[i].TargetTT = 0;
- NewOutPutPerHours[i].ActualTT = 0;
- NewOutPutPerHours[i].LoadMATSum = 0;
- NewOutPutPerHours[i].LoadMATTime = 0;
- NewOutPutPerHours[i].LoadTime = 60;
- }
- else
- {
- NewOutPutPerHours[i].LoadTime += (int)ds[i];
- if (NewOutPutPerHours[i].LoadTime > 60)
- NewOutPutPerHours[i].LoadTime = 60;
- }
- }
- }
- }
- }
- }
- private double[] GetLoadTime(DateTime startTime, DateTime endTime)
- {
- // [00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
- // [08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 01 02 03 04 05 06 07]
- // [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
- double[] loadTimes = new double[24];
- startTime = Convert.ToDateTime($"{startTime:yyyy-MM-dd HH:mm:00}");
- endTime = Convert.ToDateTime($"{endTime:yyyy-MM-dd HH:mm:00}");
- if ((endTime - startTime).TotalMinutes <= 60 && endTime.Hour == startTime.Hour)
- {
- loadTimes[endTime.Hour >= 8 ? endTime.Hour - 8 : endTime.Hour + 16] = Math.Ceiling((endTime - startTime).TotalMinutes);
- return loadTimes;
- }
- DateTime d1 = Convert.ToDateTime($"{startTime.AddHours(1):yyyy-MM-dd HH}:00:00");
- DateTime d2 = Convert.ToDateTime($"{endTime:yyyy-MM-dd HH}:00:00");
- for (DateTime dt = d1; dt < d2; dt = dt.AddHours(+1))
- {
- loadTimes[dt.Hour >= 8 ? dt.Hour - 8 : dt.Hour + 16] = 60;
- }
- loadTimes[startTime.Hour >= 8 ? startTime.Hour - 8 : startTime.Hour + 16] = Math.Ceiling((d1 - startTime).TotalMinutes);
- if (endTime > d2)
- loadTimes[endTime.Hour >= 8 ? endTime.Hour - 8 : endTime.Hour + 16] = Math.Ceiling((endTime - d2).TotalMinutes);
- return loadTimes;
- }
- /// <summary>
- /// 计算
- /// </summary>
- public void Calculate()
- {
- int len = 10;
- if (NewOutPutPerHours.Count() <= 0)
- {
- return;
- }
- IEnumerable<string> moduleTypes = NewOutPutPerHours
- .Where(x => x.ModuleType != null && x.ModuleType != "" && x.ModuleType.Length >= len)
- .Select(x => x.ModuleType[..len])
- .Distinct();
- if (moduleTypes.Count() == 0)
- {
- Statistic statistic = new Statistic();
- Statistics.Add(statistic);
- return;
- }
- foreach (var moduleType in moduleTypes)
- {
- string str = moduleType[..len];
- Statistic statistic = new Statistic()
- {
- ModuleType = str
- };
- var plan = ProductionPlans.Where(
- x =>
- x.ModuleType != "" &&
- x.ModuleType.Length >= 8 &&
- x.ModuleType[..len] == str).ToList();
- if (plan != null && plan.Count() > 0)
- {
- statistic.Capa = plan[0].Capa == -1 ? 0 : plan[0].Capa;
- statistic.TT = plan[0].TT == -1 ? 0 : plan[0].TT;
- statistic.PlanCapacity = plan.Where(x => x.PlanCapacity > 0).Select(x => x.PlanCapacity).Sum();
- var newOutPuts = NewOutPutPerHours.Where(
- x =>
- x.ModuleType != null &&
- x.ModuleType != "" &&
- x.ModuleType[..len] == str &&
- x.DataTime <= CurrentTime).ToList();
- statistic.RunTime = newOutPuts.Sum(x => x.AutoRunTime);
- double loadTime = newOutPuts.Sum(x => x.LoadTime);
- DateTime endTime = Convert.ToDateTime($"{Date} 08:00:00").AddDays(1);
- if (CurrentTime > endTime)
- statistic.LoadTime = newOutPuts.Count() * 60 - loadTime;
- else
- statistic.LoadTime = (newOutPuts.Count() - 1) * 60 - loadTime
- + Math.Round((CurrentTime - newOutPuts.Last().DataTime).TotalMinutes);
- statistic.DownTime = newOutPuts.Sum(x => x.AlarmTime);
- statistic.IdelTime = statistic.LoadTime - statistic.DownTime - statistic.RunTime;
- statistic.Capacity = newOutPuts.Sum(x => x.OutPut);
- statistic.MorningShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 8 && x.DataTime.Hour < 20).Sum(x => x.OutPut);
- statistic.NightShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 20 || x.DataTime.Hour < 7).Sum(x => x.OutPut);
- statistic.Availability = Math.Round(statistic.LoadTime == 0 ? 0 : statistic.RunTime / statistic.LoadTime, 2);
- statistic.Performance = Math.Round(statistic.RunTime == 0 ? 0 : statistic.TT / 60 * statistic.Capacity / statistic.RunTime, 2);
- statistic.Quality = 1;
- statistic.OEE = Math.Round(statistic.Availability * statistic.Performance * statistic.Quality, 2);
- }
- else
- {
- var newOutPuts = NewOutPutPerHours.Where(
- x =>
- x.ModuleType != null &&
- x.ModuleType != "" &&
- x.ModuleType[..len] == str &&
- x.DataTime <= CurrentTime).ToList();
- statistic.RunTime = newOutPuts.Sum(x => x.AutoRunTime);
- double loadTime = newOutPuts.Sum(x => x.LoadTime);
- DateTime endTime = Convert.ToDateTime($"{Date} 08:00:00").AddDays(1);
- if (CurrentTime > endTime)
- statistic.LoadTime = newOutPuts.Count() * 60 - loadTime;
- else
- statistic.LoadTime = (newOutPuts.Count() - 1) * 60 - loadTime
- + Math.Round((CurrentTime - newOutPuts.Last().DataTime).TotalMinutes);
- statistic.DownTime = newOutPuts.Sum(x => x.AlarmTime);
- statistic.IdelTime = statistic.LoadTime - statistic.DownTime - statistic.RunTime;
- statistic.Capacity = newOutPuts.Sum(x => x.OutPut);
- statistic.MorningShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 8 && x.DataTime.Hour < 20).Sum(x => x.OutPut);
- statistic.NightShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 20 || x.DataTime.Hour < 7).Sum(x => x.OutPut);
- statistic.Availability = Math.Round(statistic.LoadTime == 0 ? 0 : statistic.RunTime / statistic.LoadTime, 2);
- }
- Statistics.Add(statistic);
- }
- }
- public void CalculateV1()
- {
- IEnumerable<string> moduleTypes = ProductionPlans
- .Where(x => x.ModuleType != null && x.ModuleType != "")
- .Select(x => x.ModuleType)
- .Distinct();
- if (moduleTypes.Count() == 0)
- {
- Statistic statistic = new Statistic();
- Statistics.Add(statistic);
- return;
- }
- foreach (var moduleType in moduleTypes)
- {
- Statistic statistic = new Statistic()
- {
- ModuleType = moduleType
- };
- var plan = ProductionPlans.Where(
- x =>
- x.ModuleType != "" &&
- x.ModuleType == moduleType).ToList();
- if (plan == null || plan.Count() <= 0)
- {
- Statistics.Add(statistic);
- continue;
- }
- statistic.Capa = plan[0].Capa == -1 ? 0 : plan[0].Capa;
- statistic.TT = plan[0].TT == -1 ? 0 : plan[0].TT;
- statistic.PlanCapacity = plan.Where(x => x.PlanCapacity > 0).Select(x => x.PlanCapacity).Sum();
- var newOutPuts = NewOutPutPerHours.Where(
- x =>
- x.ModuleType != null &&
- x.ModuleType != "" &&
- x.ModuleType.Length >= moduleType.Length &&
- x.ModuleType[..moduleType.Length] == moduleType &&
- x.DataTime <= CurrentTime).ToList();
- if (newOutPuts == null || newOutPuts.Count <= 0)
- {
- Statistics.Add(statistic);
- continue;
- }
- statistic.RunTime = newOutPuts.Sum(x => x.AutoRunTime);
- double loadTime = newOutPuts.Sum(x => x.LoadTime);
- DateTime endTime = Convert.ToDateTime($"{Date} 08:00:00").AddDays(1);
- if (CurrentTime > endTime)
- statistic.LoadTime = newOutPuts.Count() * 60 - loadTime;
- else
- statistic.LoadTime = (newOutPuts.Count() - 1) * 60 - loadTime
- + Math.Round((CurrentTime - newOutPuts.Last().DataTime).TotalMinutes);
- statistic.DownTime = newOutPuts.Sum(x => x.AlarmTime);
- statistic.IdelTime = statistic.LoadTime - statistic.DownTime - statistic.RunTime;
- statistic.Capacity = newOutPuts.Sum(x => x.OutPut);
- statistic.MorningShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 8 && x.DataTime.Hour < 20).Sum(x => x.OutPut);
- statistic.NightShiftCapacity = newOutPuts.Where(x => x.DataTime.Hour >= 20 || x.DataTime.Hour < 7).Sum(x => x.OutPut);
- statistic.Availability = Math.Round(statistic.LoadTime == 0 ? 0 : statistic.RunTime / statistic.LoadTime, 2);
- statistic.Performance = Math.Round(statistic.RunTime == 0 ? 0 : statistic.TT / 60 * statistic.Capacity / statistic.RunTime, 2);
- statistic.Quality = 1;
- statistic.OEE = Math.Round(statistic.Availability * statistic.Performance * statistic.Quality, 2);
- Statistics.Add(statistic);
- }
- }
- }
- }
|