Merge branch 'develop' into Feature/Giacovelli
This commit is contained in:
@@ -251,15 +251,15 @@ namespace IOB_UT_NEXT
|
||||
{
|
||||
// problema certificati locali...
|
||||
// https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html
|
||||
// hack x certificati locali in 10.74.82.*
|
||||
if (URL.Contains("10.74.82."))
|
||||
// hack x certificati locali in 10.74.*
|
||||
if (URL.Contains("10.74."))
|
||||
{
|
||||
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
|
||||
}
|
||||
answ = clientPayload.UploadString(URL, payload);
|
||||
if (answ != "OK")
|
||||
{
|
||||
lg.Error($"Invio dati fallito:{Environment.NewLine}- URL{Environment.NewLine}{URL}{Environment.NewLine}- payload{Environment.NewLine}{payload}");
|
||||
lg.Error($"Invio dati fallito, ricevuto messaggio [{answ}]:{Environment.NewLine}- URL{Environment.NewLine}{URL}{Environment.NewLine}- payload{Environment.NewLine}{payload}");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
|
||||
+963
-944
File diff suppressed because it is too large
Load Diff
+420
-375
@@ -1,12 +1,9 @@
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using Opc.Ua;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IOB_WIN_NEXT
|
||||
{
|
||||
@@ -17,127 +14,10 @@ namespace IOB_WIN_NEXT
|
||||
Manuale = 2,
|
||||
Automatico = 3
|
||||
}
|
||||
public class MesItemStatus
|
||||
{
|
||||
public IcoelStatus Stato { get; set; } = 0;
|
||||
public UInt16 Velocita { get; set; } = 0;
|
||||
public bool Termico { get; set; } = false;
|
||||
public bool MagnetoTermico { get; set; } = false;
|
||||
public bool AvariaInverter { get; set; } = false;
|
||||
|
||||
public MesItemStatus(byte[] rawData)
|
||||
{
|
||||
Stato = (IcoelStatus)BitConverter.ToUInt16(rawData, 0);
|
||||
Velocita = BitConverter.ToUInt16(rawData, 2);
|
||||
Termico = !rawData.Skip(4).Take(1).FirstOrDefault().Equals(0);
|
||||
MagnetoTermico = !rawData.Skip(5).Take(1).FirstOrDefault().Equals(0);
|
||||
AvariaInverter = !rawData.Skip(6).Take(1).FirstOrDefault().Equals(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] serialize()
|
||||
{
|
||||
byte[] answ = new byte[7];
|
||||
Buffer.BlockCopy(BitConverter.GetBytes((short)Stato), 0, answ, 0, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Velocita), 0, answ, 2, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Termico), 0, answ, 4, 1);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(MagnetoTermico), 0, answ, 5, 1);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(AvariaInverter), 0, answ, 6, 1);
|
||||
return answ;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// Object is not a GaugeModel instance
|
||||
if (!(obj is MesItemStatus item))
|
||||
return false;
|
||||
|
||||
if (Stato != item.Stato)
|
||||
return false;
|
||||
if (Velocita != item.Velocita)
|
||||
return false;
|
||||
if (Termico != item.Termico)
|
||||
return false;
|
||||
if (MagnetoTermico != item.MagnetoTermico)
|
||||
return false;
|
||||
if (AvariaInverter != item.AvariaInverter)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PlantStatus
|
||||
{
|
||||
public bool InMarcia { get; set; } = false;
|
||||
public bool InEmergenza { get; set; } = false;
|
||||
public bool InStop { get; set; } = false;
|
||||
public PlantStatus(byte[] rawData)
|
||||
{
|
||||
InMarcia = !rawData.Skip(0).Take(1).FirstOrDefault().Equals(0);
|
||||
InEmergenza = !rawData.Skip(1).Take(1).FirstOrDefault().Equals(0);
|
||||
InStop = !rawData.Skip(2).Take(1).FirstOrDefault().Equals(0);
|
||||
|
||||
//var valore = BitConverter.ToUInt16(rawData, 0);
|
||||
|
||||
|
||||
//byte b = rawData.Skip(0).Take(1).FirstOrDefault();
|
||||
//InMarcia = (b & (1 << (1 - 1))) != 0;
|
||||
//InEmergenza = (b & (1 << (2 - 1))) != 0;
|
||||
//InStop = (b & (1 << (3 - 1))) != 0; ;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// Object is not a GaugeModel instance
|
||||
if (!(obj is PlantStatus item))
|
||||
return false;
|
||||
|
||||
if (InMarcia != item.InMarcia)
|
||||
return false;
|
||||
if (InEmergenza != item.InEmergenza)
|
||||
return false;
|
||||
if (InStop != item.InStop)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class DatiMesIcoel
|
||||
{
|
||||
public MesItemStatus Calibratrice_L1 { get; set; }
|
||||
public MesItemStatus Calibratrice_L2 { get; set; }
|
||||
public MesItemStatus Dewatering_L1 { get; set; }
|
||||
public MesItemStatus Dewatering_L2 { get; set; }
|
||||
public MesItemStatus Precalibro_L1 { get; set; }
|
||||
public MesItemStatus Precalibro_L2 { get; set; }
|
||||
public MesItemStatus Taglierina_L1 { get; set; }
|
||||
public MesItemStatus Taglierina_L2 { get; set; }
|
||||
public MesItemStatus NastroTaglierina_L1 { get; set; }
|
||||
public MesItemStatus NastroTaglierina_L2 { get; set; }
|
||||
public MesItemStatus Elevatore_L1 { get; set; }
|
||||
public MesItemStatus Elevatore_L2 { get; set; }
|
||||
public MesItemStatus ImmergitoreBins_L1 { get; set; }
|
||||
public MesItemStatus ImmergitoreBins_L2 { get; set; }
|
||||
public MesItemStatus ImmergitoreCasse_L1 { get; set; }
|
||||
public MesItemStatus ImmergitoreCasse_L2 { get; set; }
|
||||
public PlantStatus Varie { get; set; }
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione classe con dati RAW da byte[]
|
||||
@@ -169,6 +49,31 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public MesItemStatus Calibratrice_L1 { get; set; }
|
||||
public MesItemStatus Calibratrice_L2 { get; set; }
|
||||
public MesItemStatus Dewatering_L1 { get; set; }
|
||||
public MesItemStatus Dewatering_L2 { get; set; }
|
||||
public MesItemStatus Elevatore_L1 { get; set; }
|
||||
public MesItemStatus Elevatore_L2 { get; set; }
|
||||
public MesItemStatus ImmergitoreBins_L1 { get; set; }
|
||||
public MesItemStatus ImmergitoreBins_L2 { get; set; }
|
||||
public MesItemStatus ImmergitoreCasse_L1 { get; set; }
|
||||
public MesItemStatus ImmergitoreCasse_L2 { get; set; }
|
||||
public MesItemStatus NastroTaglierina_L1 { get; set; }
|
||||
public MesItemStatus NastroTaglierina_L2 { get; set; }
|
||||
public MesItemStatus Precalibro_L1 { get; set; }
|
||||
public MesItemStatus Precalibro_L2 { get; set; }
|
||||
public MesItemStatus Taglierina_L1 { get; set; }
|
||||
public MesItemStatus Taglierina_L2 { get; set; }
|
||||
public PlantStatus Varie { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
@@ -218,17 +123,193 @@ namespace IOB_WIN_NEXT
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
|
||||
public class IobOpcUaOmronIcoel : IobOpcUaOmron
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la
|
||||
/// gestione specifica per Omron (es ICOEL) https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// </summary>
|
||||
/// <param name="caller"></param>
|
||||
/// <param name="IOBConf"></param>
|
||||
public IobOpcUaOmronIcoel(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
// inizializzo classe base...
|
||||
if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
|
||||
{
|
||||
CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
|
||||
}
|
||||
sendKeyRichiesta = true;
|
||||
doByteRead = true;
|
||||
lgInfo($"Avviato IobOpcUaOmronIcoel | encodeReadData: {doByteRead}");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Processo i task richiesti e li elimino dalla coda 1:1
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// uso metodo base x ora
|
||||
return base.executeTasks(task2exe);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua vero processing contapezzi
|
||||
/// </summary>
|
||||
public override void processContapezzi()
|
||||
{
|
||||
#if false
|
||||
if (utils.CRB("enableContapezzi"))
|
||||
{
|
||||
// check condizione validazione
|
||||
if (checkMultiCondition(opcUaParams.condCountEnabled) || opcUaParams.condCountEnabled.checkList.Count == 0)
|
||||
{
|
||||
// cerco parametro contapezzi...
|
||||
string currPzCount = getDataItemValue(opcUaParams.keyPartCount);
|
||||
|
||||
// se ho un contapezzi... processo...
|
||||
if (!string.IsNullOrEmpty(currPzCount))
|
||||
{
|
||||
int newVal = -1;
|
||||
bool fatto = Int32.TryParse(currPzCount, out newVal);
|
||||
|
||||
if (fatto)
|
||||
{
|
||||
// gestione decremento contapezzi: viene "messo via" solo SE c'è un
|
||||
// effettivo decremento contapezzi...
|
||||
if (newVal < contapezziPLC)
|
||||
{
|
||||
pzCountResetted = true;
|
||||
// incremento contatore richiesta
|
||||
countKeyRichiesta = countKeyRichiesta + 1;
|
||||
// log
|
||||
lgInfo("Contapezzi resettato (PLC) --> pzCountResetted = true");
|
||||
}
|
||||
|
||||
// salvo nuovo valore contapezziPLC
|
||||
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Errore in decodifica valore contapezzi, valore rilevato: {currPzCount}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Errore in decodifica valore contapezzi, valore vuoto!");
|
||||
}
|
||||
}
|
||||
|
||||
if (CHANGE_ODL_MODE == "PZCOUNT_RESET")
|
||||
{
|
||||
// controllo comunque, se è ZERO il contapezzi, e sul server è maggiore il
|
||||
// valore x ODL e NON abilitato il trigger reset --> abilito trigger...
|
||||
if (!pzCountResetted && contapezziPLC == 0 && contapezziIOB > 0)
|
||||
{
|
||||
pzCountResetted = true;
|
||||
// incremento contatore richiesta
|
||||
countKeyRichiesta = countKeyRichiesta + 1;
|
||||
// log
|
||||
lgInfo("Contapezzi resettato (PLC==0 e IOB>PLC) --> pzCountResetted = true");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua reset del contapezzi, NON POSSIBILE in questa versione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool resetcontapezziPLC()
|
||||
{
|
||||
bool answ = false;
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE in questa versione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool setcontapezziPLC(int newPzCount)
|
||||
{
|
||||
bool answ = false;
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
/// Verifica ed invia variazioni DAL FORMATO RAW data (byte[]) --> esplode oggetti e li
|
||||
/// testa 1:1
|
||||
/// </summary>
|
||||
/// <param name="MonIt"></param>
|
||||
/// <param name="NotifyValue"></param>
|
||||
/// <param name="forceSend"></param>
|
||||
internal override bool checkAndSendRaw(Opc.Ua.Client.MonitoredItem MonIt, byte[] NotifyValue, bool forceSend)
|
||||
{
|
||||
bool changed = false;
|
||||
if (MonIt != null)
|
||||
{
|
||||
if (NotifyValue != null && NotifyValue.Length > 0)
|
||||
{
|
||||
// verifico variazione "globale"
|
||||
if (!lastData.Equals(currData))
|
||||
{
|
||||
// effettuo test/invio x ogni info
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Calibratrice_L1", lastData.Calibratrice_L1, currData.Calibratrice_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Calibratrice_L2", lastData.Calibratrice_L2, currData.Calibratrice_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Dewatering_L1", lastData.Dewatering_L1, currData.Dewatering_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Dewatering_L2", lastData.Dewatering_L2, currData.Dewatering_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Elevatore_L1", lastData.Elevatore_L1, currData.Elevatore_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Elevatore_L2", lastData.Elevatore_L2, currData.Elevatore_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "ImmergitoreBins_L1", lastData.ImmergitoreBins_L1, currData.ImmergitoreBins_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "ImmergitoreBins_L2", lastData.ImmergitoreBins_L2, currData.ImmergitoreBins_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "ImmergitoreCasse_L1", lastData.ImmergitoreCasse_L1, currData.ImmergitoreCasse_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "ImmergitoreCasse_L2", lastData.ImmergitoreCasse_L2, currData.ImmergitoreCasse_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "NastroTaglierina_L1", lastData.NastroTaglierina_L1, currData.NastroTaglierina_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "NastroTaglierina_L2", lastData.NastroTaglierina_L2, currData.NastroTaglierina_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Precalibro_L1", lastData.Precalibro_L1, currData.Precalibro_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Precalibro_L2", lastData.Precalibro_L2, currData.Precalibro_L2, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Taglierina_L1", lastData.Taglierina_L1, currData.Taglierina_L1, forceSend);
|
||||
changed = changed || testSendDataBlock(MonIt.StartNodeId, "Taglierina_L2", lastData.Taglierina_L2, currData.Taglierina_L2, forceSend);
|
||||
// salvo lastData...
|
||||
lastData = currData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("checkAndSend ERROR: MonIt null");
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
internal override void UA_ref_eh_MonItChange(object sender, opcUaMonitItemChange e)
|
||||
{
|
||||
base.UA_ref_eh_MonItChange(sender, e);
|
||||
}
|
||||
|
||||
#endregion Internal Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Valore corrente dei dati ICOEL (traduzione JIT da byte[])
|
||||
/// </summary>
|
||||
@@ -250,139 +331,49 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato POWER ON (multicondizione)
|
||||
/// </summary>
|
||||
protected override bool hasPowerOn
|
||||
{
|
||||
get
|
||||
{
|
||||
// da rivedere
|
||||
return true;
|
||||
//return checkMultiCondition(opcUaParams.condPowerOn);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato MANUAL (condizioni varie, es stopped)
|
||||
/// </summary>
|
||||
protected override bool isManual
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
//return checkMultiCondition(opcUaParams.condManual);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
|
||||
/// </summary>
|
||||
protected override bool isReady
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
//return checkMultiCondition(opcUaParams.condReady);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ultima versione validata delle info x confronto
|
||||
/// </summary>
|
||||
protected DatiMesIcoel lastData { get; set; } = new DatiMesIcoel(new byte[115]);
|
||||
|
||||
internal override void UA_ref_eh_MonItChange(object sender, opcUaMonitItemChange e)
|
||||
{
|
||||
base.UA_ref_eh_MonItChange(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la gestione specifica per Omron (es ICOEL)
|
||||
/// https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// </summary>
|
||||
/// <param name="caller"></param>
|
||||
/// <param name="IOBConf"></param>
|
||||
public IobOpcUaOmronIcoel(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
// inizializzo classe base...
|
||||
if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
|
||||
{
|
||||
CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
|
||||
}
|
||||
sendKeyRichiesta = true;
|
||||
doByteRead = true;
|
||||
lgInfo($"Avviato IobOpcUaOmronIcoel | encodeReadData: {doByteRead}");
|
||||
}
|
||||
/// <summary>
|
||||
/// Verifico se salvare e inviare proprietà specificata
|
||||
/// </summary>
|
||||
/// <param name="MonIt"></param>
|
||||
protected void testSendProperty(Opc.Ua.Client.MonitoredItem MonIt, string NotifyValue, bool forceSend)
|
||||
{
|
||||
DateTime locTStamp = DateTime.Now;
|
||||
string sVal = "";
|
||||
string descr = "";
|
||||
descr = itemTranslation("OPC", MonIt.DisplayName);
|
||||
sVal = $"Change: {locTStamp.ToString()} | descr: {descr} | Id: {MonIt.StartNodeId} | Val: {NotifyValue}";
|
||||
lgInfo($"TSP | {sVal}");
|
||||
|
||||
bool changed = checkSaveValue(MonIt, NotifyValue);
|
||||
// cerco se non sia un dato filtrato in FLUXLOG...
|
||||
bool isFiltered = opcUaParams.fluxLogVeto.Contains(MonIt.DisplayName);
|
||||
if (isFiltered)
|
||||
{
|
||||
lgTrace($"TSP | NON ACCODATO sample per {MonIt.DisplayName} - trovato VETO in fluxLogVeto", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (changed || forceSend)
|
||||
{
|
||||
accodaFLog(sVal, qEncodeFLog(descr, $"{NotifyValue}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
lgTrace($"TSP | NON ACCODATO sample per {MonIt.DisplayName} - verifica variazione ha dato esito negativo", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// effettua verifica del datablock icoel invianod eventualmente i dati variati
|
||||
/// </summary>
|
||||
/// <param name="startNodeId"></param>
|
||||
/// <param name="blockName"></param>
|
||||
/// <param name="currBlock"></param>
|
||||
/// <param name="newBlock"></param>
|
||||
/// <param name="forceSend"></param>
|
||||
/// <returns></returns>
|
||||
protected void testSendDataBlock(NodeId startNodeId, string blockName, MesItemStatus currBlock, MesItemStatus newBlock, bool forceSend)
|
||||
{
|
||||
// verifica globale blocchi old/new...
|
||||
if (!currBlock.Equals(newBlock))
|
||||
{
|
||||
// creo un nuovo monitoredItem se non ci fosse x ogni variabile dell'oggetto...
|
||||
testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Stato", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Stato}", forceSend);
|
||||
testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Velocita", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Velocita}", forceSend);
|
||||
testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Termico", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Termico}", forceSend);
|
||||
testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_MagnetoTermico", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.MagnetoTermico}", forceSend);
|
||||
testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_AvariaInverter", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.AvariaInverter}", forceSend);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifica ed invia variazioni DAL FORMATO RAW data (byte[]) --> esplode oggetti e li testa 1:1
|
||||
/// </summary>
|
||||
/// <param name="MonIt"></param>
|
||||
/// <param name="NotifyValue"></param>
|
||||
/// <param name="forceSend"></param>
|
||||
internal override void checkAndSendRaw(Opc.Ua.Client.MonitoredItem MonIt, byte[] NotifyValue, bool forceSend)
|
||||
{
|
||||
if (MonIt != null)
|
||||
{
|
||||
if (NotifyValue != null && NotifyValue.Length > 0)
|
||||
{
|
||||
|
||||
// verifico variazione "globale"
|
||||
if (!lastData.Equals(currData))
|
||||
{
|
||||
// effettuo test/invio x ogni info
|
||||
testSendDataBlock(MonIt.StartNodeId, "Calibratrice_L1", lastData.Calibratrice_L1, currData.Calibratrice_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Calibratrice_L2", lastData.Calibratrice_L2, currData.Calibratrice_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Dewatering_L1", lastData.Dewatering_L1, currData.Dewatering_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Dewatering_L2", lastData.Dewatering_L2, currData.Dewatering_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Elevatore_L1", lastData.Elevatore_L1, currData.Elevatore_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Elevatore_L2", lastData.Elevatore_L2, currData.Elevatore_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "ImmergitoreBins_L1", lastData.ImmergitoreBins_L1, currData.ImmergitoreBins_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "ImmergitoreBins_L2", lastData.ImmergitoreBins_L2, currData.ImmergitoreBins_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "ImmergitoreCasse_L1", lastData.ImmergitoreCasse_L1, currData.ImmergitoreCasse_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "ImmergitoreCasse_L2", lastData.ImmergitoreCasse_L2, currData.ImmergitoreCasse_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "NastroTaglierina_L1", lastData.NastroTaglierina_L1, currData.NastroTaglierina_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "NastroTaglierina_L2", lastData.NastroTaglierina_L2, currData.NastroTaglierina_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Precalibro_L1", lastData.Precalibro_L1, currData.Precalibro_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Precalibro_L2", lastData.Precalibro_L2, currData.Precalibro_L2, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Taglierina_L1", lastData.Taglierina_L1, currData.Taglierina_L1, forceSend);
|
||||
testSendDataBlock(MonIt.StartNodeId, "Taglierina_L2", lastData.Taglierina_L2, currData.Taglierina_L2, forceSend);
|
||||
// salvo lastData...
|
||||
lastData = currData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("checkAndSend ERROR: MonIt null");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
@@ -460,150 +451,204 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato POWER ON (multicondizione)
|
||||
/// </summary>
|
||||
protected override bool hasPowerOn
|
||||
{
|
||||
get
|
||||
{
|
||||
// da rivedere
|
||||
return true;
|
||||
//return checkMultiCondition(opcUaParams.condPowerOn);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato MANUAL (condizioni varie, es stopped)
|
||||
/// </summary>
|
||||
protected override bool isManual
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
//return checkMultiCondition(opcUaParams.condManual);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
|
||||
/// </summary>
|
||||
protected override bool isReady
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
//return checkMultiCondition(opcUaParams.condReady);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua vera scrittura parametri
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// effettua verifica del datablock icoel invianod eventualmente i dati variati
|
||||
/// </summary>
|
||||
/// <param name="startNodeId"></param>
|
||||
/// <param name="blockName"></param>
|
||||
/// <param name="currBlock"></param>
|
||||
/// <param name="newBlock"></param>
|
||||
/// <param name="forceSend"></param>
|
||||
/// <returns></returns>
|
||||
protected bool testSendDataBlock(NodeId startNodeId, string blockName, MesItemStatus currBlock, MesItemStatus newBlock, bool forceSend)
|
||||
{
|
||||
bool changed = false;
|
||||
// verifica globale blocchi old/new...
|
||||
if (!currBlock.Equals(newBlock))
|
||||
{
|
||||
// creo un nuovo monitoredItem se non ci fosse x ogni variabile dell'oggetto...
|
||||
changed = changed || testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Stato", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Stato}", forceSend);
|
||||
changed = changed || testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Velocita", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Velocita}", forceSend);
|
||||
changed = changed || testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_Termico", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.Termico}", forceSend);
|
||||
changed = changed || testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_MagnetoTermico", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.MagnetoTermico}", forceSend);
|
||||
changed = changed || testSendProperty(new Opc.Ua.Client.MonitoredItem() { DisplayName = $"{blockName}_AvariaInverter", NodeClass = NodeClass.Variable, StartNodeId = startNodeId }, $"{newBlock.AvariaInverter}", forceSend);
|
||||
|
||||
// spostare sotto in checkAndSendRaw ??? FIXME todo
|
||||
if (changed)
|
||||
{
|
||||
sendDataItemListToServer(startNodeId);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifico se salvare e inviare proprietà specificata
|
||||
/// </summary>
|
||||
/// <param name="MonIt"></param>
|
||||
protected bool testSendProperty(Opc.Ua.Client.MonitoredItem MonIt, string NotifyValue, bool forceSend)
|
||||
{
|
||||
bool changed = false;
|
||||
DateTime locTStamp = DateTime.Now;
|
||||
string sVal = "";
|
||||
string descr = "";
|
||||
descr = itemTranslation("OPC", MonIt.DisplayName);
|
||||
sVal = $"Change: {locTStamp.ToString()} | descr: {descr} | Id: {MonIt.StartNodeId} | Val: {NotifyValue}";
|
||||
lgInfo($"TSP | {sVal}");
|
||||
|
||||
changed = checkSaveValue(MonIt, NotifyValue, false);
|
||||
// cerco se non sia un dato filtrato in FLUXLOG...
|
||||
bool isFiltered = opcUaParams.fluxLogVeto.Contains(MonIt.DisplayName);
|
||||
if (isFiltered)
|
||||
{
|
||||
lgTrace($"TSP | NON ACCODATO sample per {MonIt.DisplayName} - trovato VETO in fluxLogVeto", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (changed || forceSend)
|
||||
{
|
||||
accodaFLog(sVal, qEncodeFLog(descr, $"{NotifyValue}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
lgTrace($"TSP | NON ACCODATO sample per {MonIt.DisplayName} - verifica variazione ha dato esito negativo", false);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
|
||||
public class MesItemStatus
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public MesItemStatus(byte[] rawData)
|
||||
{
|
||||
Stato = (IcoelStatus)BitConverter.ToUInt16(rawData, 0);
|
||||
Velocita = BitConverter.ToUInt16(rawData, 2);
|
||||
Termico = !rawData.Skip(4).Take(1).FirstOrDefault().Equals(0);
|
||||
MagnetoTermico = !rawData.Skip(5).Take(1).FirstOrDefault().Equals(0);
|
||||
AvariaInverter = !rawData.Skip(6).Take(1).FirstOrDefault().Equals(0);
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public bool AvariaInverter { get; set; } = false;
|
||||
public bool MagnetoTermico { get; set; } = false;
|
||||
public IcoelStatus Stato { get; set; } = 0;
|
||||
public bool Termico { get; set; } = false;
|
||||
public UInt16 Velocita { get; set; } = 0;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Processo i task richiesti e li elimino dalla coda 1:1
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// uso metodo base x ora
|
||||
return base.executeTasks(task2exe);
|
||||
// Object is not a GaugeModel instance
|
||||
if (!(obj is MesItemStatus item))
|
||||
return false;
|
||||
|
||||
if (Stato != item.Stato)
|
||||
return false;
|
||||
if (Velocita != item.Velocita)
|
||||
return false;
|
||||
if (Termico != item.Termico)
|
||||
return false;
|
||||
if (MagnetoTermico != item.MagnetoTermico)
|
||||
return false;
|
||||
if (AvariaInverter != item.AvariaInverter)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua vero processing contapezzi
|
||||
/// </summary>
|
||||
public override void processContapezzi()
|
||||
{
|
||||
#if false
|
||||
if (utils.CRB("enableContapezzi"))
|
||||
{
|
||||
// check condizione validazione
|
||||
if (checkMultiCondition(opcUaParams.condCountEnabled) || opcUaParams.condCountEnabled.checkList.Count == 0)
|
||||
{
|
||||
// cerco parametro contapezzi...
|
||||
string currPzCount = getDataItemValue(opcUaParams.keyPartCount);
|
||||
|
||||
// se ho un contapezzi... processo...
|
||||
if (!string.IsNullOrEmpty(currPzCount))
|
||||
{
|
||||
int newVal = -1;
|
||||
bool fatto = Int32.TryParse(currPzCount, out newVal);
|
||||
|
||||
if (fatto)
|
||||
{
|
||||
// gestione decremento contapezzi: viene "messo via" solo SE c'è un effettivo decremento contapezzi...
|
||||
if (newVal < contapezziPLC)
|
||||
{
|
||||
pzCountResetted = true;
|
||||
// incremento contatore richiesta
|
||||
countKeyRichiesta = countKeyRichiesta + 1;
|
||||
// log
|
||||
lgInfo("Contapezzi resettato (PLC) --> pzCountResetted = true");
|
||||
}
|
||||
|
||||
// salvo nuovo valore contapezziPLC
|
||||
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Errore in decodifica valore contapezzi, valore rilevato: {currPzCount}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Errore in decodifica valore contapezzi, valore vuoto!");
|
||||
}
|
||||
}
|
||||
|
||||
if (CHANGE_ODL_MODE == "PZCOUNT_RESET")
|
||||
{
|
||||
// controllo comunque, se è ZERO il contapezzi, e sul server è maggiore il valore x ODL e NON abilitato il trigger reset --> abilito trigger...
|
||||
if (!pzCountResetted && contapezziPLC == 0 && contapezziIOB > 0)
|
||||
{
|
||||
pzCountResetted = true;
|
||||
// incremento contatore richiesta
|
||||
countKeyRichiesta = countKeyRichiesta + 1;
|
||||
// log
|
||||
lgInfo("Contapezzi resettato (PLC==0 e IOB>PLC) --> pzCountResetted = true");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua reset del contapezzi, NON POSSIBILE in questa versione
|
||||
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool resetcontapezziPLC()
|
||||
public byte[] serialize()
|
||||
{
|
||||
bool answ = false;
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE in questa versione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool setcontapezziPLC(int newPzCount)
|
||||
{
|
||||
bool answ = false;
|
||||
byte[] answ = new byte[7];
|
||||
Buffer.BlockCopy(BitConverter.GetBytes((short)Stato), 0, answ, 0, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Velocita), 0, answ, 2, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Termico), 0, answ, 4, 1);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(MagnetoTermico), 0, answ, 5, 1);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(AvariaInverter), 0, answ, 6, 1);
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
|
||||
public class PlantStatus
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public PlantStatus(byte[] rawData)
|
||||
{
|
||||
InMarcia = !rawData.Skip(0).Take(1).FirstOrDefault().Equals(0);
|
||||
InEmergenza = !rawData.Skip(1).Take(1).FirstOrDefault().Equals(0);
|
||||
InStop = !rawData.Skip(2).Take(1).FirstOrDefault().Equals(0);
|
||||
|
||||
//var valore = BitConverter.ToUInt16(rawData, 0);
|
||||
|
||||
//byte b = rawData.Skip(0).Take(1).FirstOrDefault();
|
||||
//InMarcia = (b & (1 << (1 - 1))) != 0;
|
||||
//InEmergenza = (b & (1 << (2 - 1))) != 0;
|
||||
//InStop = (b & (1 << (3 - 1))) != 0; ;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public bool InEmergenza { get; set; } = false;
|
||||
public bool InMarcia { get; set; } = false;
|
||||
public bool InStop { get; set; } = false;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// Object is not a GaugeModel instance
|
||||
if (!(obj is PlantStatus item))
|
||||
return false;
|
||||
|
||||
if (InMarcia != item.InMarcia)
|
||||
return false;
|
||||
if (InEmergenza != item.InEmergenza)
|
||||
return false;
|
||||
if (InStop != item.InStop)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user