OK display sim parameters in HOME

This commit is contained in:
Samuele Locatelli
2022-03-07 12:06:41 +01:00
parent 4a7b75ab7c
commit bb50053fa8
9 changed files with 345 additions and 109 deletions
@@ -26,33 +26,6 @@ namespace MP.MONO.Data.Controllers
//Log.Info("Dispose di GWMSController");
}
/// <summary>
/// Restituisce stato Macchina
/// </summary>
/// <returns></returns>
public MachineDTO MachineGetStatus()
{
// !!!FIXME TODO... è fake...
Random rand = new Random();
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)}"
};
Task.Delay(200).Wait();
return currMachDto;
}
public ProductionDTO MachineGetProd()
{
// !!!FIXME TODO... è fake...
+179
View File
@@ -44,5 +44,184 @@ namespace MP.MONO.Data.Controllers
return currMachDto;
}
public ProductionDTO MachineGetProd()
{
// !!!FIXME TODO... è fake...
Random rand = new Random();
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..."
};
Task.Delay(400).Wait();
return currMachDto;
}
public List<DisplayDataDTO> MachineGetParameters()
{
List<DisplayDataDTO> answ = new List<DisplayDataDTO>();
// !!!FIXME TODO... è fake...
Random rand = new Random();
int stdCycle = 5;
#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
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 = "ORDER"
};
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);
Task.Delay(200).Wait();
return answ;
}
public Dictionary<string, string> GetCurrentParameters()
{
Dictionary<string, string>? ParametersList = new Dictionary<string, string>();
ParametersList.Add("Speed", $"{Random.Shared.Next(0, 5000)}");
ParametersList.Add("Feed", $"{Random.Shared.Next(0, 10000)}");
ParametersList.Add("Load", $"{Random.Shared.Next(0, 100)}");
//return ParametersList;
var newParamList = Enumerable.Range(1, 10)
.ToDictionary(x => $"Par{x:00}", x => $"{Random.Shared.Next(0, 1000)}");
foreach (var item in newParamList)
{
ParametersList.Add(item.Key, item.Value);
}
return ParametersList;
}
}
}
+3 -3
View File
@@ -36,7 +36,7 @@ namespace MP.MONO.Data
{
//Output received message
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {message}");
MessageEventArgs mea = new MessageEventArgs(message);
PubSubEventArgs mea = new PubSubEventArgs(message);
// se qualcuno ascolta sollevo evento nuovo valore...
if (EA_NewMessage != null)
{
@@ -62,11 +62,11 @@ namespace MP.MONO.Data
}
}
public class MessageEventArgs : EventArgs
public class PubSubEventArgs : EventArgs
{
public string newMessage { get; set; } = "";
public MessageEventArgs(string messaggio)
public PubSubEventArgs(string messaggio)
{
this.newMessage = messaggio;
}
@@ -31,7 +31,7 @@ namespace MP.MONO.UI.Components
private void AlarmPipe_EA_NewMessage(object? sender, EventArgs e)
{
MessageEventArgs currArgs = (MessageEventArgs)e;
PubSubEventArgs currArgs = (PubSubEventArgs)e;
if (currArgs.newMessage == "reset")
{
ListRecords = new List<DisplayDataDTO>();
+1 -1
View File
@@ -32,7 +32,7 @@ namespace MP.MONO.UI.Components
private void StatusPipe_EA_NewMessage(object? sender, EventArgs e)
{
MessageEventArgs currArgs = (MessageEventArgs)e;
PubSubEventArgs currArgs = (PubSubEventArgs)e;
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
-17
View File
@@ -30,21 +30,4 @@ else
</ul>
<LoadingDataSmall></LoadingDataSmall>
}
@code {
protected bool dataLoaded = false;
private List<DisplayDataDTO>? ListRecords { get; set; } = null;
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected async Task ReloadData()
{
await Task.Delay(10);
ListRecords = await MMDataService.MachineDisplay();
await Task.Delay(500);
dataLoaded = true;
}
}
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using MP.MONO.Core.DTO;
using MP.MONO.Data;
using MP.MONO.UI;
using MP.MONO.UI.Shared;
using MP.MONO.UI.Components;
using MP.MONO.UI.Data;
using Newtonsoft.Json;
namespace MP.MONO.UI.Components
{
public partial class ParamOverview
{
protected bool dataLoaded = false;
private List<DisplayDataDTO>? ListRecords { get; set; } = null;
protected override async Task OnInitializedAsync()
{
await ReloadData();
MMDataService.parametersPipe.EA_NewMessage += ParametersPipe_EA_NewMessage;
}
private void ParametersPipe_EA_NewMessage(object? sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
ListRecords = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(currArgs.newMessage);
}
catch
{ }
}
InvokeAsync(() =>
{
StateHasChanged();
});
}
protected async Task ReloadData()
{
await Task.Delay(10);
ListRecords = await MMDataService.MachineDisplay();
await Task.Delay(500);
dataLoaded = true;
}
}
}
+51 -21
View File
@@ -8,6 +8,7 @@ using NLog;
using StackExchange.Redis;
using System.Diagnostics;
using System.Text;
using StackExchange.Redis;
namespace MP.MONO.UI.Data
{
@@ -19,6 +20,15 @@ namespace MP.MONO.UI.Data
private static ILogger<CurrentDataService> _logger;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private readonly IDistributedCache distributedCache;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer redisConn = null!;
//ISubscriber sub = redis.GetSubscriber();
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
/// <summary>
/// Durata assoluta massima della cache IN SECONDI
@@ -42,12 +52,13 @@ namespace MP.MONO.UI.Data
/// <summary>
/// Controller dati simulati
/// </summary>
public static SimController simController;
public static SimController simGen;
#endregion Public Fields
public MessagePipe alarmPipe { get; set; } = null!;
public MessagePipe parametersPipe { get; set; } = null!;
public MessagePipe statusPipe { get; set; } = null!;
#region Public Constructors
@@ -56,10 +67,18 @@ namespace MP.MONO.UI.Data
{
_logger = logger;
_configuration = configuration;
// setup compoenti REDIS
this.redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
this.redisDb = this.redisConn.GetDatabase();
// setup canali pub/sub
alarmPipe = new MessagePipe(redisConn, "allarms");
parametersPipe = new MessagePipe(redisConn, "parameters");
statusPipe = new MessagePipe(redisConn, "status");
// conf cache
this.distributedCache = distributedCache;
// conf DB
string connStr = _configuration.GetConnectionString("MP.MONO.Data");
if (string.IsNullOrEmpty(connStr))
@@ -71,7 +90,7 @@ namespace MP.MONO.UI.Data
dbController = new MpDbController(configuration);
_logger.LogInformation("DbController OK");
}
simController = new SimController();
simGen = new SimController();
}
#endregion Public Constructors
@@ -114,25 +133,38 @@ namespace MP.MONO.UI.Data
public async Task<Dictionary<string, string>> GetCurrentParameters()
{
ParametersList = new Dictionary<string, string>();
ParametersList.Add("Speed", $"{Random.Shared.Next(0, 5000)}");
ParametersList.Add("Feed", $"{Random.Shared.Next(0, 10000)}");
ParametersList.Add("Load", $"{Random.Shared.Next(0, 100)}");
//return ParametersList;
var newParamList = Enumerable.Range(1, 10)
.ToDictionary(x => $"Par{x:00}", x => $"{Random.Shared.Next(0, 1000)}");
foreach (var item in newParamList)
string cacheKey = mHash("Machine:Parameters:Current");
string rawData = await redisDb.StringGetAsync(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
ParametersList.Add(item.Key, item.Value);
ParametersList = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
}
else
{
ParametersList = simGen.GetCurrentParameters();
rawData = JsonConvert.SerializeObject(ParametersList);
await redisDb.StringSetAsync(cacheKey, rawData);
}
await Task.Delay(1);
return ParametersList;
}
public async Task<List<DisplayDataDTO>> MachineDisplay()
{
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
string cacheKey = mHash("Machine:DisplayData");
string cacheKey = mHash("Machine:Parameters:Current");
string rawData = await redisDb.StringGetAsync(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
}
else
{
dbResult = simGen.MachineGetParameters();
rawData = JsonConvert.SerializeObject(dbResult);
await redisDb.StringSetAsync(cacheKey, rawData);
}
#if false
string rawData;
var redisDataList = await distributedCache.GetAsync(cacheKey);
if (redisDataList != null)
@@ -156,7 +188,8 @@ namespace MP.MONO.UI.Data
if (dbResult == null)
{
dbResult = new List<DisplayDataDTO>();
}
}
#endif
return await Task.FromResult(dbResult);
}
@@ -195,19 +228,16 @@ namespace MP.MONO.UI.Data
{
MachineDTO? dbResult = new MachineDTO();
string cacheKey = mHash("Machine:Status:Current");
string rawData;
var redisDataList = await distributedCache.GetAsync(cacheKey);
if (redisDataList != null)
string rawData = await redisDb.StringGetAsync(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<MachineDTO>(rawData);
}
else
{
dbResult = simController.MachineGetStatus();
dbResult = simGen.MachineGetStatus();
rawData = JsonConvert.SerializeObject(dbResult);
redisDataList = Encoding.UTF8.GetBytes(rawData);
//await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(true));
redisDb.StringSetAsync(cacheKey, rawData);
}
if (dbResult == null)
{
+50 -39
View File
@@ -2,7 +2,6 @@
using MP.MONO.Data.Controllers;
using Newtonsoft.Json;
using StackExchange.Redis;
using System.Configuration;
string lineSep = "------------------------------------------------------";
string redisConf = "127.0.0.1:6379";
@@ -22,45 +21,24 @@ ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
ISubscriber sub = redis.GetSubscriber();
IDatabase? redisDb = redis.GetDatabase();
// avvio tutti i thread...
Thread threadStatus = new Thread(simStatus);
Thread threadAlarms = new Thread(simAlarms);
Thread threadParams = new Thread(simParameters);
threadStatus.Start();
threadAlarms.Start();
threadParams.Start();
void simStatus()
/// <summary>
/// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...)
/// </summary>
/// <param name="dataType"></param>
/// <returns></returns>
string mHash(string dataType)
{
int minPeriod = 2000;
int maxPeriod = 3000;
do {
// recupero uno stato simulato
var newStatus = simGen.MachineGetStatus();
string rawData = JsonConvert.SerializeObject(newStatus);
saveAndSendMessage(mHash("Machine:Status:Current"), rawData, "status", rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
return $"MAPO-MONO:{dataType}";
}
void simAlarms()
{
int minPeriod = 1000;
int maxPeriod = 2000;
do
{
var alarmCode = rand.Next(1, 100);
saveAndSendMessage(mHash("Machine:Alarms:Current"), $"{alarmCode:000} | Allarme PLC {alarmCode}", "allarms", $"{alarmCode:000}");
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
void saveAndSendMessage(string memKey, string value, string notifyChannel, string message)
{
@@ -73,13 +51,46 @@ void saveAndSendMessage(string memKey, string value, string notifyChannel, strin
sub.Publish(notifyChannel, message);
Console.WriteLine($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}");
}
/// <summary>
/// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...)
/// </summary>
/// <param name="dataType"></param>
/// <returns></returns>
string mHash(string dataType)
void simAlarms()
{
return $"MAPO-MONO:{dataType}";
int minPeriod = 1000;
int maxPeriod = 2000;
do
{
var alarmCode = rand.Next(1, 100);
saveAndSendMessage(mHash("Machine:Alarms:Current"), $"{alarmCode:000} | Allarme PLC {alarmCode}", "allarms", $"{alarmCode:000}");
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
void simParameters()
{
int minPeriod = 100;
int maxPeriod = 500;
do
{
var newParams = simGen.MachineGetParameters();
string rawData = JsonConvert.SerializeObject(newParams);
saveAndSendMessage(mHash("Machine:Parameters:Current"), rawData, "parameters", rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}
void simStatus()
{
int minPeriod = 2000;
int maxPeriod = 3000;
do
{
// recupero uno stato simulato
var newStatus = simGen.MachineGetStatus();
string rawData = JsonConvert.SerializeObject(newStatus);
saveAndSendMessage(mHash("Machine:Status:Current"), rawData, "status", rawData);
// attesa random
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
} while (true);
}