diff --git a/MP.MONO.Core/DTO/DisplayDataDTO.cs b/MP.MONO.Core/DTO/DisplayDataDTO.cs index 15bd43b..e763a47 100644 --- a/MP.MONO.Core/DTO/DisplayDataDTO.cs +++ b/MP.MONO.Core/DTO/DisplayDataDTO.cs @@ -16,6 +16,8 @@ namespace MP.MONO.Core.DTO public string Title { get; set; } = ""; public string Value { get; set; } = ""; public double ValueNum { get; set; } = 0; + public double MinVal { get; set; } = 0; + public double MaxVal { get; set; } = 0; public bool IsNumeric { get; set; } = false; } } diff --git a/MP.MONO.Core/MP.MONO.Core.csproj b/MP.MONO.Core/MP.MONO.Core.csproj index ad72607..c294001 100644 --- a/MP.MONO.Core/MP.MONO.Core.csproj +++ b/MP.MONO.Core/MP.MONO.Core.csproj @@ -7,6 +7,7 @@ + diff --git a/MP.MONO.Data/Controllers/SimController.cs b/MP.MONO.Data/Controllers/SimController.cs index 9e1e1f3..0c8dde3 100644 --- a/MP.MONO.Data/Controllers/SimController.cs +++ b/MP.MONO.Data/Controllers/SimController.cs @@ -16,6 +16,24 @@ namespace MP.MONO.Data.Controllers public class SimController : IDisposable { +#if false + protected List? paramList = null; + + public SimController() + { + paramList = new List(); + } + public SimController(List setSimParam) + { + if (setSimParam == null) + { + setSimParam = new List(); + + } + paramList = setSimParam; + } +#endif + public void Dispose() { // Clear database context @@ -161,7 +179,7 @@ namespace MP.MONO.Data.Controllers ValueNum = currVal, IsNumeric = true, Value = currVal.ToString("P0"), - Type = "ORDER" + Type = "LOAD" }; answ.Add(displ03); @@ -201,9 +219,6 @@ namespace MP.MONO.Data.Controllers }; answ.Add(displ06); - - Task.Delay(200).Wait(); - return answ; } diff --git a/MP.MONO.UI/Data/CurrentDataService.cs b/MP.MONO.UI/Data/CurrentDataService.cs index 86dea0a..6287ca4 100644 --- a/MP.MONO.UI/Data/CurrentDataService.cs +++ b/MP.MONO.UI/Data/CurrentDataService.cs @@ -97,7 +97,9 @@ namespace MP.MONO.UI.Data #region Protected Properties - protected Dictionary ParametersList { get; set; } = new Dictionary(); +#if false + protected Dictionary? ParametersList { get; set; } = new Dictionary(); +#endif #endregion Protected Properties @@ -130,6 +132,7 @@ namespace MP.MONO.UI.Data dbController.Dispose(); } +#if false public async Task> GetCurrentParameters() { ParametersList = new Dictionary(); @@ -146,7 +149,8 @@ namespace MP.MONO.UI.Data await redisDb.StringSetAsync(cacheKey, rawData); } return ParametersList; - } + } +#endif public async Task> MachineDisplay() { @@ -157,11 +161,17 @@ namespace MP.MONO.UI.Data { dbResult = JsonConvert.DeserializeObject>(rawData); } +#if false else { dbResult = simGen.MachineGetParameters(); rawData = JsonConvert.SerializeObject(dbResult); await redisDb.StringSetAsync(cacheKey, rawData); + } +#endif + if (dbResult == null) + { + dbResult = new List(); } #if false @@ -233,12 +243,14 @@ namespace MP.MONO.UI.Data { dbResult = JsonConvert.DeserializeObject(rawData); } +#if false else { dbResult = simGen.MachineGetStatus(); rawData = JsonConvert.SerializeObject(dbResult); redisDb.StringSetAsync(cacheKey, rawData); - } + } +#endif if (dbResult == null) { dbResult = new MachineDTO(); diff --git a/MP.MONO.UI/Pages/Parameters.razor b/MP.MONO.UI/Pages/Parameters.razor index bad5f48..b60a014 100644 --- a/MP.MONO.UI/Pages/Parameters.razor +++ b/MP.MONO.UI/Pages/Parameters.razor @@ -5,22 +5,8 @@

Parameters

-@if (CurrParams != null) -{ -
    - @foreach(var item in CurrParams) - { -
  • @item.Key: @item.Value
  • - } -
-} + @code { - private Dictionary CurrParams { get; set; } - - protected override async Task OnInitializedAsync() - { - CurrParams = await ParDataSrv.GetCurrentParameters(); - } } diff --git a/MachineSim/MachineSim.csproj b/MachineSim/MachineSim.csproj index b73c8ce..1d68fe7 100644 --- a/MachineSim/MachineSim.csproj +++ b/MachineSim/MachineSim.csproj @@ -8,6 +8,7 @@ + @@ -19,4 +20,10 @@ + + + Always + + + diff --git a/MachineSim/Program.cs b/MachineSim/Program.cs index ca9cf4d..c426257 100644 --- a/MachineSim/Program.cs +++ b/MachineSim/Program.cs @@ -1,4 +1,6 @@ // See https://aka.ms/new-console-template for more information +using MachineSim; +using MP.MONO.Core.DTO; using MP.MONO.Data.Controllers; using Newtonsoft.Json; using StackExchange.Redis; @@ -21,6 +23,9 @@ ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf); ISubscriber sub = redis.GetSubscriber(); IDatabase? redisDb = redis.GetDatabase(); +// imposto parametri simulatore +var currSimGen = new Simulator(Directory.GetCurrentDirectory()); + // avvio tutti i thread... Thread threadStatus = new Thread(simStatus); Thread threadAlarms = new Thread(simAlarms); @@ -84,7 +89,7 @@ void simParameters() do { - var newParams = simGen.MachineGetParameters(); + var newParams = currSimGen.MachineGetParameters(); string rawData = JsonConvert.SerializeObject(newParams); saveAndSendMessage(mHash("Machine:Parameters:Current"), rawData, "parameters", rawData); // attesa random diff --git a/MachineSim/SimDisplayDataDTO.cs b/MachineSim/SimDisplayDataDTO.cs new file mode 100644 index 0000000..14d57a6 --- /dev/null +++ b/MachineSim/SimDisplayDataDTO.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MachineSim +{ + public class SimDisplayDataDTO: MP.MONO.Core.DTO.DisplayDataDTO + { + public double SimMean { get; set; } = 0; + public double SimStd { get; set; } = 1; + } +} diff --git a/MachineSim/SimParams.json b/MachineSim/SimParams.json new file mode 100644 index 0000000..39c30db --- /dev/null +++ b/MachineSim/SimParams.json @@ -0,0 +1,68 @@ +[ + { + "Order": 0, + "Type": "SPEED-5000-10000", + "Title": "SPEED", + "Value": "6000", + "ValueNum": 6000, + "MinVal": 1000, + "MaxVal": 10000, + "SimMean": 100, + "SimStd": 50 + }, + { + "Order": 0, + "Type": "FEED-3000-5000", + "Title": "FEED", + "Value": "3500", + "ValueNum": 3500, + "MinVal": 1000, + "MaxVal": 5000, + "SimMean": 50, + "SimStd": 5 + }, + { + "Order": 0, + "Type": "LOAD", + "Title": "SPINDLE LOAD", + "Value": "0", + "ValueNum": 0, + "MinVal": 0, + "MaxVal": 100, + "SimMean": 5, + "SimStd": 1 + }, + { + "Order": 0, + "Type": "POS", + "Title": "X POS", + "Value": "500", + "ValueNum": 500, + "MinVal": 0, + "MaxVal": 5000, + "SimMean": 100, + "SimStd": 20 + }, + { + "Order": 0, + "Type": "POS", + "Title": "Y POS", + "Value": "3000", + "ValueNum": 3000, + "MinVal": 0, + "MaxVal": 10000, + "SimMean": 100, + "SimStd": 10 + }, + { + "Order": 0, + "Type": "POS", + "Title": "Z POS", + "Value": "-500", + "ValueNum": -500, + "MinVal": -3000, + "MaxVal": 0, + "SimMean": 50, + "SimStd": 5 + } +] \ No newline at end of file diff --git a/MachineSim/Simulator.cs b/MachineSim/Simulator.cs new file mode 100644 index 0000000..fbdeefe --- /dev/null +++ b/MachineSim/Simulator.cs @@ -0,0 +1,216 @@ +using MathNet.Numerics.Distributions; +using MP.MONO.Core.DTO; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MachineSim +{ + /// + /// Definizione parametri simulati + /// + public class Simulator + { + protected string basePath = ""; + protected string paramFileName = "SimParams.json"; + + protected List? currSimPar = new List(); + + public Simulator(string _basePath) + { + basePath = _basePath; + setupConfig(); + } + + private void setupConfig() + { + string fullPath = Path.Combine(basePath, paramFileName); + if (File.Exists(fullPath)) + { + var rawData = File.ReadAllText(fullPath); + if (!string.IsNullOrEmpty(rawData)) + { + currSimPar = JsonConvert.DeserializeObject>(rawData); + } + } + } + + /// + /// Calcola prox valore simulato dati i parametri rand configurati + /// + /// + /// + /// + /// + /// + /// + public double getNext(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; + } + + public List MachineGetParameters() + { + List answ = new List(); + + // 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 = getNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd) + //Value = $"{getNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd):N3}", + }).ToList(); + + foreach (var item in answ) + { + item.Value = $"{item.ValueNum:N3}"; + } + + // !!!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 + +#if false + Random rand = new Random(); + int stdCycle = 5; + + double currVal = 0; + currVal = rand.Next(10, 120) * 100; + DisplayDataDTO displ01 = new DisplayDataDTO() + { + Order = 0, + Title = "SPEED", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("N0"), + Type = "SPEED-5000-10000" + }; + answ.Add(displ01); + + currVal = rand.Next(10, 100) * 100; + DisplayDataDTO displ02 = new DisplayDataDTO() + { + Order = 0, + Title = "FEED", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("N0"), + Type = "FEED-3000-5000" + }; + answ.Add(displ02); + + currVal = rand.NextDouble() * 1.2; + DisplayDataDTO displ03 = new DisplayDataDTO() + { + Order = 0, + Title = "SPINDLE LOAD", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("P0"), + Type = "LOAD" + }; + answ.Add(displ03); + + currVal = rand.NextDouble() * 5000; + DisplayDataDTO displ04 = new DisplayDataDTO() + { + Order = 0, + Title = "X POS", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("N1"), + Type = "POS" + }; + answ.Add(displ04); + + currVal = rand.NextDouble() * 10000; + DisplayDataDTO displ05 = new DisplayDataDTO() + { + Order = 0, + Title = "Y POS", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("N1"), + Type = "POS" + }; + answ.Add(displ05); + + currVal = rand.NextDouble() * -3000; + DisplayDataDTO displ06 = new DisplayDataDTO() + { + Order = 0, + Title = "Z POS", + ValueNum = currVal, + IsNumeric = true, + Value = currVal.ToString("N1"), + Type = "POS" + }; + answ.Add(displ06); +#endif + + return answ; + } + } +}