Files
mapo-mono/MP.MONO.ADAPTER.OPC/Program.cs
T
Samuele Locatelli 71b338077e refresh UI
2023-03-29 11:02:55 +02:00

233 lines
8.1 KiB
C#

using Microsoft.Extensions.Configuration;
using MP.MONO.Core;
using MP.MONO.Core.CONF;
using MP.MONO.Core.DTO;
using Newtonsoft.Json;
using NLog;
using Opc.Ua;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using static MP.MONO.Core.Enums;
namespace MP.MONO.ADAPTER.OPC
{
/// <summary>
/// The program.
/// </summary>
public static class Program
{
#region Public Methods
/// <summary>
/// Main entry point.
/// </summary>
public static async Task Main(string[] args)
{
await Task.Delay(1);
TextWriter output = Console.Out;
output.WriteLine(lineSep);
output.WriteLine("Egalware | MP.MONO.ADAPTER | OPC UA Console Client");
output.WriteLine($"vers.{Assembly.GetExecutingAssembly().GetName().Version}");
output.WriteLine(lineSep);
output.WriteLine();
output.WriteLine("OPC UA library: {0} @ {1} -- {2}",
Utils.GetAssemblyBuildNumber(),
Utils.GetAssemblyTimestamp().ToString("G", CultureInfo.InvariantCulture),
Utils.GetAssemblySoftwareVersion());
// init parte config, vedere https://blog.hildenco.com/2020/05/configuration-in-net-core-console.html
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json", true, true)
.AddJsonFile($"appsettings.{env}.json", true, true)
.AddEnvironmentVariables();
IConfigurationRoot config = builder.Build();
// imposto variabili di base
redisConf = config.GetConnectionString("Redis");
confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
Random rand = new Random();
List<MachineStatus>? statusList = new List<MachineStatus>();
List<MachineMode>? modeList = new List<MachineMode>();
// fix numero minimo dei thread pool x evitare collasso chiamate redis
ThreadPool.SetMinThreads(10, 10);
logInfo(lineSep, true, true);
logInfo($"Starting Machine ADAPTER", true, true);
logInfo($"Redis server param: {redisConf.Substring(0, 20)}...", false, true);
logInfo(lineSep, true, true);
logInfo("", true, true);
// Setup REDIS
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
sub = redis.GetSubscriber();
redisDb = redis.GetDatabase();
// salvo configurazioni in redis
setupConfRedis(config);
// avvio il vero e proprio programma di comunicaizone OPC-UA
var currIob = new IobOpcUa(confPath, config);
logInfo($"Started IOB at path {confPath}", true, true);
logInfo("Running - press CTRL-C to stop ADAPTER", false, true);
logInfo("", false, true);
// wait for timeout or Ctrl-C
var quitEvent = ConsoleUtils.CtrlCHandler();
bool quit = false;
DateTime start = DateTime.UtcNow;
int waitTime = int.MaxValue;
// Ciclo infinito x attesa chiusura con CTRL-C
do
{
// se non fosse connesso... riprovo la connessione...
currIob.tryConnect();
// attesa...
Thread.Sleep(100);
// aggiunta condizioni check dati "recenti" x ri-connessione: se NON si fosse
// aggiornato entro limite indicato --> disconnect/reconnect
if (currIob.dataIsStale)
{
currIob.tryDisconnect();
Thread.Sleep(500);
currIob.tryConnect();
}
// verifico se c'è evento quit
quit = quitEvent.WaitOne(Math.Min(1_000, waitTime));
} while (!quit);
// disconnetto alla fine...
if (currIob.connectionOk)
{
currIob.tryDisconnect();
}
}
#endregion Public Methods
#region Private Fields
private static AlarmReportingMode alarmMode = AlarmReportingMode.ND;
private static string confPath = "";
private static DateTime lastLog = DateTime.Now.AddMinutes(-1);
private static Dictionary<string, DateTime> LastSend = new Dictionary<string, DateTime>();
private static string lineSep = "---------------------------------------------";
private static Logger Log = LogManager.GetCurrentClassLogger();
private static Dictionary<string, int> LogSimulator = new Dictionary<string, int>();
private static bool logWriting = false;
private static string redisConf = "";
private static bool verboseLog = false;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Redis DB
/// </summary>
private static IDatabase? redisDb { get; set; }
/// <summary>
/// Redis channel manager
/// </summary>
private static ISubscriber sub { get; set; }
#endregion Private Properties
#region Private Methods
/// <summary>
/// verifica esistenza file oppure lo crea...
/// </summary>
private static void checkFilePresent(string filePath)
{
// verific presenza file log...
if (!File.Exists(filePath))
{
File.WriteAllText(filePath, $"{filePath} created!");
}
}
/// <summary>
/// Effettua log ERROR su file e se richiesto su console
/// </summary>
private static void logError(string msg, bool log2file = true, bool log2console = false)
{
if (log2console)
{
Console.WriteLine(msg);
}
if (log2file)
{
Log.Error(msg);
}
}
/// <summary>
/// Effettua log INFO su file e se richiesto su console
/// </summary>
private static void logInfo(string msg, bool log2file = true, bool log2console = false)
{
if (log2console)
{
Console.WriteLine(msg);
}
if (log2file)
{
Log.Info(msg);
}
}
/// <summary>
/// Setup e salvataggio redis delle conf (es modi/stati)
/// </summary>
private static void setupConfRedis(IConfigurationRoot appConf)
{
// fix configuraizoni di base
MachineDTO currMach = new MachineDTO()
{
Manufacturer = appConf.GetValue<string>("Machine:Manufacturer"),
Model = appConf.GetValue<string>("Machine:Model"),
SerNumber = appConf.GetValue<string>("Machine:SerialNumber"),
Name = appConf.GetValue<string>("Machine:Name"),
ModeId = 0,
StatusId = 0
};
redisDb.StringSet(Constants.MACHINE_CONF_PLATE, JsonConvert.SerializeObject(currMach));
// allarmi
alarmMode = appConf.GetValue<AlarmReportingMode>("OptPar:AlarmMode");
redisDb.StringSet(Constants.ALARMS_MODE_KEY, JsonConvert.SerializeObject(alarmMode));
// gestore specifico configurazioni
ConfigManager configManager = new ConfigManager(redisConf, confPath);
if (alarmMode == AlarmReportingMode.RawList)
{
_ = configManager.getAlarmsRawConf();
}
else
{
_ = configManager.getAlarmsBankConf();
}
// altre conf
_ = configManager.getMachineModeConf();
_ = configManager.getMachineStatusConf();
_ = configManager.getPalletStatusConf();
_ = configManager.getParamsConf();
}
#endregion Private Methods
}
}