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
{
///
/// 机台
///
public class MachineViewModel
{
public MachineViewModel()
{
}
public MachineViewModel(string topic, string date, List keyInInfos,
List 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();
return;
}
WashOutPutPerHours();
CalculateV1();
}
///
/// 解析Topic
///
///
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;
///
/// 日期
///
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; }
///
/// 当前时间
///
public DateTime CurrentTime { get; set; }
///
/// topic
///
public string Topic { get; set; } = string.Empty;
///
/// 楼层
///
public int Floor { get; set; }
///
/// 线别
///
public int Line { get; set; }
///
/// 类型
///
public string Type { get; set; } = string.Empty;
///
/// 生产计划
///
public List ProductionPlans { get; set; }
= new List();
///
/// key in 的异常
///
public List KeyInInfos { get; set; }
= new List();
///
/// 小时产能
///
public List LoadOutPutPerHours { get; set; }
= new List();
///
/// 清理后小时产能
///
public List NewOutPutPerHours { get; set; }
= new List();
///
/// 统计
///
public List Statistics { get; set; }
= new List();
///
/// 获取小时产能
///
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;
}
}
///
/// 根据 key in 时间清洗小时产能
///
public void WashOutPutPerHours()
{
/*
0: 品质异常停线
1: 宕机
2: 换线
3: 实验
4: W/F送样
5: 物料缺料或生管调整影响
6: 放假
7: 停电气等停线
8: 换耗材类
9: 停机未生产
10: 效率爬升
*/
NewOutPutPerHours = new List();
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;
}
///
/// 计算
///
public void Calculate()
{
int len = 10;
if (NewOutPutPerHours.Count() <= 0)
{
return;
}
IEnumerable 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 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);
}
}
}
}