243 lines
7.6 KiB
C#
243 lines
7.6 KiB
C#
using MathNet.Numerics.Distributions;
|
|
using MP.MONO.Core;
|
|
using MP.MONO.Core.DTO;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace MachineSim
|
|
{
|
|
/// <summary>
|
|
/// Definizione parametri simulati
|
|
/// </summary>
|
|
public class Simulator
|
|
{
|
|
#region Protected Fields
|
|
|
|
protected string basePath = "";
|
|
protected List<SimDisplayDataDTO> currSimMachStat = new List<SimDisplayDataDTO>();
|
|
protected List<SimDisplayDataDTO> currSimPar = new List<SimDisplayDataDTO>();
|
|
protected string paramFileName = "SimParams.json";
|
|
|
|
protected Random rand = new Random();
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Public Constructors
|
|
|
|
public Simulator(string _basePath)
|
|
{
|
|
basePath = _basePath;
|
|
setupConfig();
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Methods
|
|
|
|
private void setupConf(string paramFileName, ref List<SimDisplayDataDTO> localObj)
|
|
{
|
|
string fullPath = Path.Combine(basePath, paramFileName);
|
|
if (File.Exists(fullPath))
|
|
{
|
|
var rawData = File.ReadAllText(fullPath);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
localObj = JsonConvert.DeserializeObject<List<SimDisplayDataDTO>>(rawData);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setupConfig()
|
|
{
|
|
// setup conf parametri
|
|
setupConf("SimParams.json", ref currSimPar);
|
|
// setup conf machStat
|
|
setupConf("SimMachStat.json", ref currSimMachStat);
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Public Methods
|
|
|
|
public List<String> getAlarms()
|
|
{
|
|
List<string> activeAlarms = new List<string>();
|
|
//int alarmCode = rand.Next(0, 255);
|
|
int alarmCode = rand.Next(0, 160);
|
|
// se >= 128 --> 0 (no alarm)
|
|
alarmCode = alarmCode <= 127 ? alarmCode : 0;
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if ((alarmCode & (1 << i)) != 0)
|
|
{
|
|
activeAlarms.Add($"Alarm {i:000}");
|
|
}
|
|
}
|
|
return activeAlarms;
|
|
}
|
|
|
|
public List<DisplayDataDTO> getParameters()
|
|
{
|
|
List<DisplayDataDTO> answ = new List<DisplayDataDTO>();
|
|
|
|
// genero a partire dall'elenco configurato da simulare...
|
|
answ = currSimPar.Select(i => new DisplayDataDTO()
|
|
{
|
|
IsNumeric = i.IsNumeric,
|
|
MaxVal = i.MaxVal,
|
|
MinVal = i.MinVal,
|
|
Order = i.Order,
|
|
Title = i.Title,
|
|
Type = i.Type,
|
|
ValueNum = simNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd),
|
|
DisplFormat = i.DisplFormat
|
|
//Value = $"{getNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd):N3}",
|
|
}).ToList();
|
|
|
|
foreach (var item in answ)
|
|
{
|
|
item.Value = $"{item.ValueNum.ToString(item.DisplFormat)}";
|
|
}
|
|
|
|
// !!!FIXME TODO... è fake...
|
|
|
|
#if false
|
|
var currVal = rand.NextDouble();
|
|
DisplayDataDTO displ01 = new DisplayDataDTO()
|
|
{
|
|
Order = 0,
|
|
Title = "OEE",
|
|
ValueNum = currVal,
|
|
IsNumeric = true,
|
|
Value = currVal.ToString("P1"),
|
|
Type = "OEE-75-90"
|
|
};
|
|
answ.Add(displ01);
|
|
|
|
currVal = rand.NextDouble();
|
|
DisplayDataDTO displ02 = new DisplayDataDTO()
|
|
{
|
|
Order = 0,
|
|
Title = "Avail",
|
|
ValueNum = currVal,
|
|
IsNumeric = true,
|
|
Value = currVal.ToString("P1"),
|
|
Type = "AVAIL-50-80"
|
|
};
|
|
answ.Add(displ02);
|
|
|
|
currVal = rand.NextDouble();
|
|
DisplayDataDTO displ03 = new DisplayDataDTO()
|
|
{
|
|
Order = 0,
|
|
Title = "Order fulfill",
|
|
ValueNum = currVal,
|
|
IsNumeric = true,
|
|
Value = currVal.ToString("P1"),
|
|
Type = "ORDER"
|
|
};
|
|
answ.Add(displ03);
|
|
|
|
double minTCiclo = stdCycle * rand.NextDouble();
|
|
TimeSpan durTCycle = TimeSpan.FromMinutes(minTCiclo);
|
|
DisplayDataDTO displ04 = new DisplayDataDTO()
|
|
{
|
|
Order = 0,
|
|
Title = "Cycle time",
|
|
ValueNum = 0,
|
|
IsNumeric = false,
|
|
Value = $"{durTCycle.Hours:00}:{durTCycle.Minutes:00}:{durTCycle.Seconds:00}",
|
|
Type = "TCycle"
|
|
};
|
|
answ.Add(displ04);
|
|
#endif
|
|
|
|
return answ;
|
|
}
|
|
|
|
public ProductionDTO getProd()
|
|
{
|
|
int stdCycle = 5;
|
|
|
|
ProductionDTO currMachDto = new ProductionDTO()
|
|
{
|
|
Order = "ODL Test",
|
|
ItemCode = "ART.0000123",
|
|
ProgName = "P000012",
|
|
CurrQty = DateTime.Now.Minute + rand.Next(1, 40),
|
|
OrderQty = 100,
|
|
CycleTimeMin = rand.NextDouble() * stdCycle,
|
|
Message = "...simulated data..."
|
|
};
|
|
return currMachDto;
|
|
}
|
|
|
|
public List<DisplayDataDTO> getProdStats()
|
|
{
|
|
List<DisplayDataDTO> answ = new List<DisplayDataDTO>();
|
|
|
|
// genero a partire dall'elenco configurato da simulare...
|
|
answ = currSimMachStat.Select(i => new DisplayDataDTO()
|
|
{
|
|
IsNumeric = i.IsNumeric,
|
|
MaxVal = i.MaxVal,
|
|
MinVal = i.MinVal,
|
|
Order = i.Order,
|
|
Title = i.Title,
|
|
Type = i.Type,
|
|
ValueNum = simNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd),
|
|
DisplFormat = i.DisplFormat
|
|
//Value = $"{getNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd):N3}",
|
|
}).ToList();
|
|
|
|
foreach (var item in answ)
|
|
{
|
|
item.Value = $"{item.ValueNum.ToString(item.DisplFormat)}";
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce stato Macchina simulato come DTO
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public MachineDTO getStatus()
|
|
{
|
|
int maxRun = 5;
|
|
int maxExe = 7;
|
|
|
|
MachineDTO currMachDto = new MachineDTO()
|
|
{
|
|
Manufacturer = "Egalware",
|
|
Model = "SIM Machine",
|
|
Name = "DEMO 01",
|
|
SerNumber = "2022-0001",
|
|
Mode = $"{(Enums.MachRunMode)rand.Next(0, maxRun)}",
|
|
Status = $"{(Enums.MachExeStatus)rand.Next(0, maxExe)}"
|
|
};
|
|
|
|
return currMachDto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola prox valore simulato dati i parametri rand configurati
|
|
/// </summary>
|
|
/// <param name="CurrVal"></param>
|
|
/// <param name="MinVal"></param>
|
|
/// <param name="MaxVal"></param>
|
|
/// <param name="sMean"></param>
|
|
/// <param name="sStd"></param>
|
|
/// <returns></returns>
|
|
public double simNext(double CurrVal, double MinVal, double MaxVal, double sMean, double sStd)
|
|
{
|
|
double innov = Normal.Sample(sMean, sStd);
|
|
CurrVal += innov;
|
|
// verifico estremi...
|
|
CurrVal = CurrVal > MaxVal ? MaxVal : CurrVal;
|
|
CurrVal = CurrVal < MinVal ? MinVal : CurrVal;
|
|
return CurrVal;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |