488 lines
20 KiB
C#
488 lines
20 KiB
C#
using Newtonsoft.Json;
|
|
using YamlDotNet.Serialization.NamingConventions;
|
|
using YamlDotNet.Serialization;
|
|
using NLog;
|
|
using System.IO;
|
|
using System;
|
|
using static IOB_UT_NEXT.Config.EnumConf;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using IOB_UT_NEXT.Config;
|
|
using IOB_UT_NEXT.Config.Base;
|
|
using IOB_UT_NEXT.Config.Special;
|
|
using static System.Net.Mime.MediaTypeNames;
|
|
|
|
// <Auto-Generated>
|
|
// This is here so CodeMaid doesn't reorganize this document
|
|
// </Auto-Generated>
|
|
namespace IOB_UT_NEXT.Config
|
|
{
|
|
/// <summary>
|
|
/// Albero configurazione globale IOB in formato serializable
|
|
/// </summary>
|
|
[Serializable]
|
|
public class IobConfTree
|
|
{
|
|
/// <summary>
|
|
/// Init classe configurazione
|
|
/// </summary>
|
|
public IobConfTree()
|
|
{
|
|
Log = LogManager.GetCurrentClassLogger();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Init classe configurazione da file
|
|
/// </summary>
|
|
public IobConfTree(string confFilePath)
|
|
{
|
|
Log = LogManager.GetCurrentClassLogger();
|
|
if (File.Exists(confFilePath))
|
|
{
|
|
IobConfTree newConfObj = new IobConfTree();
|
|
// verifico TIPO file...
|
|
string fileExt = Path.GetExtension(confFilePath);
|
|
string fileName = Path.GetFileName(confFilePath);
|
|
string rawData = File.ReadAllText(confFilePath);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
// leggo in base al tipo...
|
|
switch (fileExt)
|
|
{
|
|
case "yaml":
|
|
case "yml":
|
|
var deserializer = new DeserializerBuilder()
|
|
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
|
.Build();
|
|
try
|
|
{
|
|
newConfObj = deserializer.Deserialize<IobConfTree>(rawData);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
//lgError($"Eccezione in LoadFromYaml{Environment.NewLine}{exc}");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (newConfObj != null)
|
|
{
|
|
// ora copio in oggetto corrente...
|
|
GenConf = newConfObj.GenConf;
|
|
DeviceConf = newConfObj.DeviceConf;
|
|
ProcInputConf = newConfObj.ProcInputConf;
|
|
OptParConf = newConfObj.OptParConf;
|
|
MapoMesConf = newConfObj.MapoMesConf;
|
|
SpecialConf = newConfObj.SpecialConf;
|
|
TCDataConf = newConfObj.TCDataConf;
|
|
ActionConf = newConfObj.ActionConf;
|
|
// sovrascrivo filename
|
|
GenConf.ConfFileName = fileName;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce un oggetto di conf leggendo INI ed effettuando conversione
|
|
/// </summary>
|
|
/// <param name="iniFilePath"></param>
|
|
/// <returns></returns>
|
|
public static IobConfTree LoadFromINI(string iniFilePath)
|
|
{
|
|
IobConfTree newConfObj = new IobConfTree();
|
|
try
|
|
{
|
|
// leggo file INI
|
|
IniFile fIni = new IniFile(iniFilePath);
|
|
string dirPath = Path.GetDirectoryName(iniFilePath);
|
|
string codIob = Path.GetFileNameWithoutExtension(iniFilePath);
|
|
|
|
// Dati generali (vendor, modello...)
|
|
newConfObj.GenConf = new IobDto()
|
|
{
|
|
CodIOB = fIni.ReadString("IOB", "IOB_NAME", codIob),
|
|
ConfFileName = Path.GetFileName(iniFilePath),
|
|
Customer = fIni.ReadString("TAGS", "Customer", "EgalWare"),
|
|
DisableExeTask = bool.Parse(fIni.ReadString("IOB", "DIS_EXE_TASK", "false")),
|
|
DisableStateCh = bool.Parse(fIni.ReadString("IOB", "DIS_STATE_CH", "false")),
|
|
EnableRedisQueue = bool.Parse(fIni.ReadString("IOB", "EnableRedisQueue", "false")),
|
|
MinDeltaSec = fIni.ReadInteger("IOB", "MinDeltaSec", 6),
|
|
ReleaseVers = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Version}"
|
|
};
|
|
// tipo adapter// verifico tipo adapter
|
|
try
|
|
{
|
|
newConfObj.GenConf.IobType = (tipoAdapter)Enum.Parse(typeof(tipoAdapter), fIni.ReadString("IOB", "CNCTYPE", "ND"));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
newConfObj.GenConf.IobType = tipoAdapter.ND;
|
|
string rawVal = fIni.ReadString("IOB", "CNCTYPE", "DEMO");
|
|
newConfObj.lgError($"Eccezione in conversione tipo adapter: richiesto {rawVal} | tipo non codificato...{Environment.NewLine}{exc}");
|
|
}
|
|
|
|
|
|
newConfObj.DeviceConf = new DeviceDto()
|
|
{
|
|
Vendor = fIni.ReadString("MACHINE", "VENDOR", "STEAMWARE"),
|
|
Model = fIni.ReadString("MACHINE", "MODEL", "ND"),
|
|
ConnectConf = new ConnectionDto()
|
|
{
|
|
pingMsTimeout = fIni.ReadInteger("IOB", "PING_MS_TIMEOUT", 500),
|
|
IpAddr = fIni.ReadString("CNC", "IP", "::1"),
|
|
Port = fIni.ReadString("CNC", "PORT", "0")
|
|
}
|
|
};
|
|
// parametri opzionali Memory
|
|
string[] memSection = fIni.ReadSection("MEMORY");
|
|
// in primis SE ho qualcosa...
|
|
if (memSection != null && memSection.Count() > 0)
|
|
{
|
|
// trasformo in array...
|
|
Dictionary<string, string> memDict = new Dictionary<string, string>();
|
|
foreach (var item in memSection)
|
|
{
|
|
// verifica preliminare NON sia commento (inizia per ";")
|
|
if (!item.StartsWith(";") && item.Contains("="))
|
|
{
|
|
var KVP = item.Split('=');
|
|
memDict.Add(KVP[0], KVP[1]);
|
|
}
|
|
}
|
|
// ora se ho qualcosa proseguo...
|
|
if (memDict.Count() > 0)
|
|
{
|
|
// cerco dati x popolare SignalLUT
|
|
foreach (var item in memDict.Where(x => x.Key.StartsWith("BIT")))
|
|
{
|
|
if (newConfObj.DeviceConf.SignalLUT.ContainsKey(item.Key))
|
|
{
|
|
newConfObj.DeviceConf.SignalLUT[item.Key] = item.Value;
|
|
}
|
|
else
|
|
{
|
|
newConfObj.DeviceConf.SignalLUT.Add(item.Key, item.Value);
|
|
}
|
|
}
|
|
// cerco dati specifici x popolare l'area Fanuc
|
|
if (memDict.Where(x => x.Key.StartsWith("AREA") || x.Key.StartsWith("PAR")).Count() > 0)
|
|
{
|
|
// init fanuc...
|
|
newConfObj.DeviceConf.FanucConf = new FanucDto();
|
|
// inizio setup prendendo quelli con valori addrSize
|
|
foreach (var item in memDict.Where(x => x.Key.EndsWith("SIZE")))
|
|
{
|
|
int addrSize = 0;
|
|
int.TryParse(item.Value, out addrSize);
|
|
// salvo solo quelli con valori addrSize > 0
|
|
if (addrSize > 0)
|
|
{
|
|
string mId = item.Key.Replace("_SIZE", "");
|
|
// cerco record inizio
|
|
var valStart = memDict.Where(x => x.Key == item.Key.Replace("_SIZE", "_START")).Select(x => x.Value).FirstOrDefault();
|
|
if (!string.IsNullOrEmpty(valStart))
|
|
{
|
|
int addrStart = 0;
|
|
int.TryParse(valStart, out addrStart);
|
|
var memArea = new Mem.MemAreaDto()
|
|
{
|
|
AddressStart = addrStart,
|
|
AddressSize = addrSize
|
|
};
|
|
newConfObj.DeviceConf.FanucConf.MemConf.Add(mId, memArea);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// parametri opzionali Siemens
|
|
if (!string.IsNullOrEmpty(fIni.ReadString("CNC", "CPUTYPE", "")))
|
|
{
|
|
newConfObj.DeviceConf.SiemensConf = new SiemensDto();
|
|
newConfObj.DeviceConf.SiemensConf.CpuType = fIni.ReadString("CNC", "CPUTYPE", "");
|
|
newConfObj.DeviceConf.SiemensConf.Rack = (short)fIni.ReadInteger("CNC", "RACK", 0);
|
|
newConfObj.DeviceConf.SiemensConf.Slot = (short)fIni.ReadInteger("CNC", "SLOT", 0);
|
|
}
|
|
|
|
// BLINK
|
|
newConfObj.ProcInputConf.BlinkMaxCounter = Convert.ToInt32(fIni.ReadString("BLINK", "MAX_COUNTER_BLINK", "1"));
|
|
newConfObj.ProcInputConf.BlinkFilterMask = Convert.ToInt32(fIni.ReadString("BLINK", "BLINK_FILT", "0"));
|
|
newConfObj.TCDataConf.MaxDelayFactor = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_TC_FACTOR", "1.2").Replace(".", ","));
|
|
newConfObj.TCDataConf.Lambda = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_LAMBDA", "0.5").Replace(".", ","));
|
|
newConfObj.TCDataConf.MaxIncrPz = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_INCR", "5").Replace(".", ","));
|
|
|
|
// Server
|
|
string MpIp = fIni.ReadString("SERVER", "MPIP", "::1");
|
|
#if false
|
|
string[] serverSection = fIni.ReadSection("SERVER");
|
|
// trasformo in array...
|
|
Dictionary<string, string> servDict = new Dictionary<string, string>();
|
|
foreach (var item in serverSection)
|
|
{
|
|
var KVP = item.Split('=');
|
|
servDict.Add(KVP[0], KVP[1]);
|
|
}
|
|
// processo array appena acquisito
|
|
if (servDict.ContainsKey("MPIP"))
|
|
{
|
|
string MpIp = servDict["MPIP"];
|
|
}
|
|
#endif
|
|
if (!string.IsNullOrEmpty(MpIp))
|
|
{
|
|
newConfObj.MapoMesConf.Transport = MpIp.StartsWith("https://") ? "https" : "http";
|
|
newConfObj.MapoMesConf.IpAddr = MpIp.Replace($"{newConfObj.MapoMesConf.Transport}://", ""); // tolgo http/https...
|
|
}
|
|
|
|
// Altro
|
|
newConfObj.IobManConf.MinDeltaSec = fIni.ReadInteger("IOB", "MinDeltaSec", 6);
|
|
|
|
// OptParConf
|
|
Dictionary<string, string> optParRead = new Dictionary<string, string>();
|
|
string[] optParRows = fIni.ReadSection("OPTPAR");
|
|
if (optParRows.Length > 0)
|
|
{
|
|
try
|
|
{
|
|
string[] kvp;
|
|
foreach (var item in optParRows)
|
|
{
|
|
kvp = item.Split('=');
|
|
optParRead.Add(kvp[0], kvp[1]);
|
|
}
|
|
newConfObj.lgDebug($"Caricati {optParRead.Count} parametri opzionali da OPTPAR");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
newConfObj.lgError($"EXCEPTION in fase di lettura OPTPAR: {Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
// riordino alfabeticamente
|
|
optParRead = optParRead.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);
|
|
newConfObj.OptParConf = optParRead;
|
|
|
|
newConfObj.SpecialConf = new SpecializedDto();
|
|
// verifico se ho conf json speciali: LUT decodifica PARAMETRI
|
|
if (optParRead.ContainsKey("PARAM_CONF"))
|
|
{
|
|
string jsonParams = optParRead["PARAM_CONF"];
|
|
if (!string.IsNullOrEmpty(jsonParams))
|
|
{
|
|
string jsonFileName = Path.Combine(dirPath, jsonParams);
|
|
if (File.Exists(jsonFileName))
|
|
{
|
|
newConfObj.lgInfo($"Apertura file {jsonFileName}");
|
|
using (StreamReader reader = new StreamReader(jsonFileName))
|
|
{
|
|
string jsonData = reader.ReadToEnd();
|
|
if (!string.IsNullOrEmpty(jsonData))
|
|
{
|
|
newConfObj.SpecialConf.MemMap = new plcMemMapExt();
|
|
try
|
|
{
|
|
newConfObj.SpecialConf.MemMap = JsonConvert.DeserializeObject<plcMemMapExt>(jsonData);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
newConfObj.lgError($"Eccezione in decodifica conf json{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
newConfObj.lgError("Errore in loadMemConf: file json vuoto!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
newConfObj.lgInfo("loadMemConf: non trovata opzione PARAM_CONF in file INI");
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
newConfObj.lgError($"EXCEPTION in decodifica IobConfTree: {Environment.NewLine}{exc}");
|
|
}
|
|
return newConfObj;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Info generali delative all'IOB impiegato
|
|
/// </summary>
|
|
public IobDto GenConf { get; set; } = new IobDto();
|
|
|
|
/// <summary>
|
|
/// Info relative al device interconnesso
|
|
/// </summary>
|
|
public DeviceDto DeviceConf { get; set; } = new DeviceDto();
|
|
|
|
/// <summary>
|
|
/// Parametri server Mapo MES
|
|
/// </summary>
|
|
public ServerMapoDto MapoMesConf { get; set; } = new ServerMapoDto();
|
|
|
|
/// <summary>
|
|
/// Setup info verso IOB-MAN
|
|
/// </summary>
|
|
public IobManDto IobManConf { get; set; } = new IobManDto();
|
|
|
|
/// <summary>
|
|
/// Setup processing dati in ingresso (es: blink segnali)
|
|
/// </summary>
|
|
public InputSignalDto ProcInputConf { get; set; } = new InputSignalDto();
|
|
|
|
/// <summary>
|
|
/// Dati relativi ai parametri gestione tempo ciclo
|
|
/// </summary>
|
|
public TCDataDto TCDataConf { get; set; } = new TCDataDto();
|
|
|
|
/// <summary>
|
|
/// Configurazione speciale/opzionale per tipo IOB
|
|
/// </summary>
|
|
public SpecializedDto SpecialConf { get; set; }
|
|
|
|
/// <summary>
|
|
/// Configurazione speciale comportamenti IOB (es setup)
|
|
/// </summary>
|
|
public ActionDto ActionConf { get; set; }
|
|
|
|
/// <summary>
|
|
/// Dizionario dei parametri opzionali
|
|
/// </summary>
|
|
public Dictionary<string, string> OptParConf { get; set; } = new Dictionary<string, string>();
|
|
|
|
/// <summary>
|
|
/// Dizionario delle chiavi opz da dizionario
|
|
/// </summary>
|
|
public Dictionary<string, string> OptKVP { get; set; } = new Dictionary<string, string>();
|
|
|
|
|
|
#region Metodi Serializzazione
|
|
|
|
/// <summary>
|
|
/// Restituisce conf serializzata in formato JSON
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public string GetJson()
|
|
{
|
|
string rawdata = JsonConvert.SerializeObject(this, Formatting.Indented);
|
|
return rawdata;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce conf serializzata in formato YAML
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public string GetYaml()
|
|
{
|
|
// opzioni alternative: PascalCaseNamingConvention (iniziale masiucola) o lowerCaseNamingConvention
|
|
var serializer = new SerializerBuilder()
|
|
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
|
.Build();
|
|
var rawdata = serializer.Serialize(this);
|
|
return rawdata;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Metodi Load/Save
|
|
|
|
/// <summary>
|
|
/// Scrive conf serializzata in formato JSON
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public bool SaveJson(string filePath)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
string rawdata = GetJson();
|
|
File.WriteAllText(filePath, rawdata);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Scrive conf serializzata in formato YAML
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public bool SaveYaml(string filePath)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
var rawdata = GetYaml();
|
|
File.WriteAllText(filePath, rawdata);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Logging
|
|
|
|
/// <summary>
|
|
/// oggetto logging
|
|
/// </summary>
|
|
protected Logger Log;// = LogManager.GetCurrentClassLogger();
|
|
|
|
/// <summary>
|
|
/// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="txt2log"></param>
|
|
protected void lgDebug(string txt2log)
|
|
{
|
|
Log.Factory.Configuration.Variables["codIOB"] = GenConf.CodIOB;
|
|
Log.Debug(txt2log);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="txt2log"></param>
|
|
protected void lgError(string txt2log)
|
|
{
|
|
if (!string.IsNullOrEmpty(txt2log))
|
|
{
|
|
Log.Factory.Configuration.Variables["codIOB"] = GenConf.CodIOB;
|
|
Log.Error(txt2log);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="txt2log"></param>
|
|
protected void lgInfo(string txt2log)
|
|
{
|
|
Log.Factory.Configuration.Variables["codIOB"] = GenConf.CodIOB;
|
|
Log.Info(txt2log);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="txt2log"></param>
|
|
protected void lgTrace(string txt2log)
|
|
{
|
|
Log.Factory.Configuration.Variables["codIOB"] = GenConf.CodIOB;
|
|
Log.Trace(txt2log);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |