Merge remote-tracking branch 'origin/develop' into RemoteDebug
This commit is contained in:
+18
-14
@@ -424,6 +424,24 @@ namespace IOB_UT_NEXT
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di resettare contatore lotto e
|
||||
/// quindi riavviare produzione (es: impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actResetCounter { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di effettuare impostazione nuovo
|
||||
/// programma/ricetta (es: impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actSetRecipe { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di fermare la produzione (es:
|
||||
/// impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actStopProd { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Identificativo nodo iniziale
|
||||
/// </summary>
|
||||
@@ -526,20 +544,6 @@ namespace IOB_UT_NEXT
|
||||
/// </summary>
|
||||
public WatchDogConf WatchDog { get; set; } = new WatchDogConf();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di fermare la produzione (es: impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actStopProd { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di effettuare impostazione nuovo programma/ricetta (es: impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actSetRecipe { get; set; } = new Dictionary<string, string>();
|
||||
/// <summary>
|
||||
/// Elenco Variabili (e valori da impostare) x indicare di resettare contatore lotto e quindi riavviare produzione (es: impostando valore a 1...)
|
||||
/// </summary>
|
||||
public Dictionary<string, string> actResetCounter { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
;Configurazione IOB-WIN
|
||||
[IOB]
|
||||
CNCTYPE=FANUC
|
||||
|
||||
[MACHINE]
|
||||
VENDOR=COLCOM
|
||||
MODEL=DMG-MORI
|
||||
|
||||
[CNC]
|
||||
; TEST FANUC!
|
||||
IP=192.168.100.78
|
||||
PORT=8193
|
||||
GETPRGNAME=true
|
||||
|
||||
[SERVER]
|
||||
MPIP=192.168.111.104
|
||||
MPURL=/MP/IO
|
||||
CMDBASE=/IOB/input/
|
||||
CMDFLOG=/IOB/flog/
|
||||
CMDALIVE=/IOB
|
||||
CMDENABLED=/IOB/enabled/
|
||||
CMDADV1=?valore=
|
||||
CMDREBO=/sendReboot.aspx?idxMacchina=
|
||||
|
||||
[MEMORY]
|
||||
; Red: Y12.4 | Yellow: Y51.1 (porta chiusa, da NEGARE) | Green Y12.6 | Alarm Y 51.4 | Blu Y12.7
|
||||
;BIT0=CONN
|
||||
BIT1=Y12.6
|
||||
BIT2=PZCOUNT.PAR.6711
|
||||
BIT3=Y12.4
|
||||
BIT4=Y12.7
|
||||
;BIT5=Y11.2
|
||||
BIT5=X18.3
|
||||
BIT6=X11.3
|
||||
AREAD_START=0
|
||||
AREAD_SIZE=9999
|
||||
AREAG_SIZE=48
|
||||
AREAR_START=0
|
||||
AREAR_SIZE=64
|
||||
AREAX_START=0
|
||||
AREAX_SIZE=64
|
||||
AREAY_START=0
|
||||
AREAY_SIZE=64
|
||||
PAR_START=6711
|
||||
PAR_SIZE=3
|
||||
|
||||
[BLINK]
|
||||
;MAX_COUNTER_BLINK = 30
|
||||
MAX_COUNTER_BLINK = 15
|
||||
;bit0 = 0
|
||||
;bit1 = 0
|
||||
;bit2 = 1
|
||||
;bit3 = 1
|
||||
;bit4 = 1
|
||||
;bit5 = 0
|
||||
;bit6 = 0
|
||||
;bit7 = 0
|
||||
BLINK_FILT=0
|
||||
;BLINK_FILT=28
|
||||
|
||||
[OPTPAR]
|
||||
;PZCOUNT_MODE=STD|BIT
|
||||
PZCOUNT_MODE=STD.PAR.6711
|
||||
PZGTOT_MODE=STD.PAR.6712
|
||||
;PZREQ_MODE=STD.PAR.6713
|
||||
ENABLE_PZ_RESET=TRUE
|
||||
ENABLE_PZ_RESET_stopSetup=TRUE
|
||||
;gestione invio pezzi in blocco
|
||||
ENABLE_SEND_PZC_BLOCK=TRUE
|
||||
MIN_SEND_PZC_BLOCK=0
|
||||
MAX_SEND_PZC_BLOCK=100
|
||||
|
||||
|
||||
[BRANCH]
|
||||
NAME=master
|
||||
@@ -15,7 +15,7 @@ namespace IOB_WIN_NEXT
|
||||
/// <summary>
|
||||
/// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
|
||||
/// </summary>
|
||||
private Dictionary<string, string> signLUT = new Dictionary<string, string>();
|
||||
internal Dictionary<string, string> signLUT = new Dictionary<string, string>();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
|
||||
+110
-111
@@ -3,31 +3,17 @@ 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
|
||||
{
|
||||
public class IobOpcUaSiemens : IobOpcUa
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Modalità cambio ODL
|
||||
/// </summary>
|
||||
protected string CHANGE_ODL_MODE = "";
|
||||
|
||||
protected bool testDone = false;
|
||||
|
||||
#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 Siemens OPC-UA (es OPC, Cereria Finassi)
|
||||
/// https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la
|
||||
/// gestione specifica per Siemens OPC-UA (es OPC, Cereria Finassi) https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// </summary>
|
||||
/// <param name="caller"></param>
|
||||
/// <param name="IOBConf"></param>
|
||||
@@ -44,6 +30,113 @@ namespace IOB_WIN_NEXT
|
||||
|
||||
#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 (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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Modalità cambio ODL
|
||||
/// </summary>
|
||||
protected string CHANGE_ODL_MODE = "";
|
||||
|
||||
protected bool testDone = false;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
@@ -138,7 +231,7 @@ namespace IOB_WIN_NEXT
|
||||
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
nodes2Write.Add(commWriteVal);
|
||||
|
||||
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -272,99 +365,5 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#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 (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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,17 @@
|
||||
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
|
||||
{
|
||||
public class IobOpcUaSiemensOMP : IobOpcUaSiemens
|
||||
{
|
||||
#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 EWON (es Monti, Tenditalia)
|
||||
/// https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la
|
||||
/// gestione specifica per EWON (es Monti, Tenditalia) https://github.com/OPCFoundation/UA-.NETStandard
|
||||
/// </summary>
|
||||
/// <param name="caller"></param>
|
||||
/// <param name="IOBConf"></param>
|
||||
@@ -37,89 +27,9 @@ namespace IOB_WIN_NEXT
|
||||
sendKeyRichiesta = true;
|
||||
}
|
||||
|
||||
public override bool resetcontapezziPLC()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actResetCounter)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Azioni specifiche x indicare fine lotto di produzione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool setFineLotto()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actStopProd)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Azioni specifiche x iniziare produzione (impostazione ricetta)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool setInizioProd()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actSetRecipe)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Processo i task richiesti e li elimino dalla coda 1:1
|
||||
@@ -130,9 +40,8 @@ namespace IOB_WIN_NEXT
|
||||
// uso metodo base x salvare esito scrittura
|
||||
var writeResult = base.executeTasks(task2exe);
|
||||
|
||||
// aggiungo comportamento custom:
|
||||
// se ho impostato nome ricetta (programma) --> imposto richiesta caricamento
|
||||
// se ho richiesto reset o fine lavoro --> imposto azzeramento
|
||||
// aggiungo comportamento custom: se ho impostato nome ricetta (programma) --> imposto
|
||||
// richiesta caricamento se ho richiesto reset o fine lavoro --> imposto azzeramento
|
||||
// esco restituendo risutlato scrittura iniziali
|
||||
if (task2exe != null)
|
||||
{
|
||||
@@ -202,7 +111,93 @@ namespace IOB_WIN_NEXT
|
||||
return writeResult;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
public override bool resetcontapezziPLC()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actResetCounter)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Azioni specifiche x indicare fine lotto di produzione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool setFineLotto()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actStopProd)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Azioni specifiche x iniziare produzione (impostazione ricetta)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool setInizioProd()
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
List<WriteValue> nodes2Write = new List<WriteValue>();
|
||||
foreach (var item in opcUaParams.actSetRecipe)
|
||||
{
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId(item.Key);
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = item.Value;
|
||||
|
||||
nodes2Write.Add(commWriteVal);
|
||||
}
|
||||
// vera scrittura
|
||||
UA_ref.WriteNodes(nodes2Write);
|
||||
answ = true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
+470
-458
@@ -8,112 +8,6 @@ namespace IOB_WIN_NEXT
|
||||
{
|
||||
public class IobSimula : IobGeneric
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 2
|
||||
/// </summary>
|
||||
protected simPar bit2;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 3
|
||||
/// </summary>
|
||||
protected simPar bit3;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 4
|
||||
/// </summary>
|
||||
protected simPar bit4;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 5
|
||||
/// </summary>
|
||||
protected simPar bit5;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 6
|
||||
/// </summary>
|
||||
protected simPar bit6;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 7
|
||||
/// </summary>
|
||||
protected simPar bit7;
|
||||
|
||||
/// <summary>
|
||||
/// pallet corrente
|
||||
/// </summary>
|
||||
protected int cP = 1;
|
||||
|
||||
protected bool disableSimStatus = false;
|
||||
|
||||
/// <summary>
|
||||
/// ultimo controllo decremento eventi
|
||||
/// </summary>
|
||||
protected DateTime lastEvCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo istante in cui sono stati generati dati di simulazione
|
||||
/// </summary>
|
||||
protected DateTime lastSimData;
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo istante in cui sono stati ridotti dati simulazione duration
|
||||
/// </summary>
|
||||
protected DateTime lastRedDuration;
|
||||
|
||||
/// <summary>
|
||||
/// Matricola OPR simulato
|
||||
/// </summary>
|
||||
protected int matrOpr = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Durata minima ODL x reset quando pezzi iob > pezzi macchina...
|
||||
/// </summary>
|
||||
protected int minDurataODL = 480;
|
||||
|
||||
/// <summary>
|
||||
/// pallet successivo (next)
|
||||
/// </summary>
|
||||
protected int nP = 1;
|
||||
|
||||
/// <summary>
|
||||
/// periodo base del simulatore (in millisecondi)
|
||||
/// </summary>
|
||||
protected int periodoMSec = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// variabile di appoggio x stato segnale contapezzo
|
||||
/// </summary>
|
||||
protected bool sigPzCount = false;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione registrazione dichiarazioni utente
|
||||
/// </summary>
|
||||
protected simPar simDich;
|
||||
|
||||
/// <summary>
|
||||
/// BOOL: indica se simulare powerOn/Off (bit 0 e 1) compresi WarmUp e CoolDown
|
||||
/// </summary>
|
||||
protected bool simPowerOnOff;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione effettuazione controlli utente
|
||||
/// </summary>
|
||||
protected simPar simRC;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione registro scarti utente
|
||||
/// </summary>
|
||||
protected simPar simRS;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo di MINIMO attesa x simulazione parametri
|
||||
/// </summary>
|
||||
protected int waitSimPar = utils.CRI("waitSimPar");
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>
|
||||
@@ -200,18 +94,454 @@ namespace IOB_WIN_NEXT
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Private Methods
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica il resto dell'area x i dati accessori (allarmi, ...)
|
||||
/// Processo i task richiesti e li elimino dalla coda 1:1 (in realtà SOLO forceSetPzCount x ora)
|
||||
/// </summary>
|
||||
private void decodeOtherData()
|
||||
/// <param name="task2exe"></param>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
// controlo SE sia disabilitata simulazione principale
|
||||
if (!disableSimStatus)
|
||||
{
|
||||
string taskVal = "";
|
||||
// verifico non sia null
|
||||
if (task2exe != null)
|
||||
{
|
||||
// cerco task specifici
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setArt:
|
||||
case taskType.setComm:
|
||||
case taskType.setProg:
|
||||
case taskType.setPzComm:
|
||||
memMap.mMapWrite[item.Key].value = item.Value;
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | UPDATED memMap.mMapWrite";
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case taskType.nihil:
|
||||
case taskType.fixStopSetup:
|
||||
case taskType.forceResetPzCount:
|
||||
case taskType.sendWatchDogMes2Plc:
|
||||
case taskType.startSetup:
|
||||
case taskType.stopSetup:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
break;
|
||||
|
||||
case taskType.forceSetPzCount:
|
||||
// forzo sul SIM il valore pzCount dell'IOB...
|
||||
int newPzCount = contapezziPLC;
|
||||
bool fatto = int.TryParse(item.Value, out newPzCount);
|
||||
if (fatto)
|
||||
{
|
||||
// verifico SE sia ammesso il cambio ...
|
||||
int deltaPzCount = newPzCount - contapezziPLC;
|
||||
double maxDelta = DateTime.Now.Subtract(plcLastPzRead).TotalMinutes / (plcAvgTc / 60);
|
||||
// se incremento superiore del doppio atteso --> segnalo errore
|
||||
// e NON accetto
|
||||
if (deltaPzCount > (maxDelta * maxPzDeltaPerc) / 100)
|
||||
{
|
||||
lgError($"[DELTA CHECK]: intremento contapezziPLC troppo elevato: lettura {newPzCount} | contapezzi attuale: {contapezziPLC} | ultima lettura PLC: {plcLastPzRead} | TCiclo medio: {plcAvgTc}s | incremento accettato ");
|
||||
}
|
||||
else
|
||||
{
|
||||
contapezziPLC = newPzCount;
|
||||
taskVal = $"Set new contapezziPLC: {contapezziPLC}";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = "SKIPPED | NO EXEC";
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera e processa allarmi CNC...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getCncAlarms()
|
||||
{
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec
|
||||
if (lastSimData.AddSeconds(waitSimPar) < DateTime.Now)
|
||||
{
|
||||
Random rnd = new Random();
|
||||
// controllo conf memorie json (se ci sono...)
|
||||
try
|
||||
{
|
||||
if (memMap.mMapWrite.Count > 0)
|
||||
{
|
||||
foreach (var item in memMap.mMapWrite)
|
||||
{
|
||||
outVal.Add(item.Key, item.Value.value);
|
||||
}
|
||||
}
|
||||
if (memMap.mMapRead.Count > 0)
|
||||
{
|
||||
foreach (var item in memMap.mMapRead)
|
||||
{
|
||||
// se il TIPO di valore è livello --> simulo variazione da MAX --> min,
|
||||
// con un delta in CALO pari a factor * (80-120)%
|
||||
if (item.Value.name == "SIM_LEVEL")
|
||||
{
|
||||
// verifico last value
|
||||
float lastVal = 0;
|
||||
float.TryParse(item.Value.value, out lastVal);
|
||||
if (lastVal == 0)
|
||||
{
|
||||
lastVal = item.Value.maxVal - (float)item.Value.factor;
|
||||
}
|
||||
// decremento casuale...
|
||||
float newVal = lastVal - ((float)item.Value.factor * rnd.Next(40, 120) / 100);
|
||||
// se inferiore a minimo --> massimo!
|
||||
if (newVal < item.Value.minVal)
|
||||
{
|
||||
newVal = item.Value.maxVal;
|
||||
}
|
||||
// salvo il suo VALUE...
|
||||
item.Value.value = $"{newVal}";
|
||||
outVal.Add(item.Key, $"{newVal}");
|
||||
}
|
||||
// altrimenti siulazione random walk...
|
||||
else
|
||||
{
|
||||
if (item.Value.factor == 1)
|
||||
{
|
||||
// uso factor come valore MAX ammesso
|
||||
int randVal = rnd.Next(item.Value.minVal, item.Value.maxVal);
|
||||
outVal.Add(item.Key, randVal.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// uso factor come fattore di divisione x simulare decimali
|
||||
float randVal = ((float)rnd.Next(item.Value.minVal, item.Value.maxVal)) / (float)item.Value.factor;
|
||||
outVal.Add(item.Key, randVal.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
lastSimData = DateTime.Now;
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero programma in lavorazione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string getPrgName()
|
||||
{
|
||||
// NOME DEL SIM!
|
||||
string prgName = $"PROG_{cIobConf.codIOB}";
|
||||
return prgName;
|
||||
}
|
||||
|
||||
/// <summary> Recupero info sistema generiche <returns></returns>
|
||||
public override Dictionary<string, string> getSysInfo()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
outVal.Add("MACHINE", "IOB_SIM");
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua vero processing contapezzi
|
||||
/// </summary>
|
||||
public override void processContapezzi()
|
||||
{
|
||||
}
|
||||
|
||||
private Random rnd = new Random();
|
||||
private int currSimAlarmCode = 0;
|
||||
private List<string> alarmMessages = new List<string>();
|
||||
/// <summary>
|
||||
/// Processo contatori eventi...
|
||||
/// </summary>
|
||||
public override void processVHF()
|
||||
{
|
||||
if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now)
|
||||
{
|
||||
// decremento contatore ultimo evento
|
||||
try
|
||||
{
|
||||
if (bit2 != null)
|
||||
bit2.wait--;
|
||||
|
||||
if (bit3 != null)
|
||||
bit3.wait--;
|
||||
|
||||
if (bit4 != null)
|
||||
bit4.wait--;
|
||||
|
||||
if (bit5 != null)
|
||||
bit5.wait--;
|
||||
|
||||
if (simDich != null)
|
||||
simDich.wait--;
|
||||
|
||||
if (simRC != null)
|
||||
simRC.wait--;
|
||||
|
||||
if (simRS != null)
|
||||
simRS.wait--;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
lastEvCheck = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
base.readSemafori(ref currDispData);
|
||||
|
||||
// controlo SE sia disabilitata simulazione principale
|
||||
if (!disableSimStatus)
|
||||
{
|
||||
// decodifica e gestione
|
||||
decodeToBaseBitmap();
|
||||
decodeOtherData();
|
||||
reportRawInput(ref currDispData);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua reset del contapezzi
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool resetcontapezziPLC()
|
||||
{
|
||||
bool answ = false;
|
||||
// ...SE abilitato da conf IOB
|
||||
if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
|
||||
{
|
||||
// fingo di aver fatto...
|
||||
answ = true;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
public override void tryConnect()
|
||||
{
|
||||
base.tryConnect();
|
||||
connectionOk = true;
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
base.tryDisconnect();
|
||||
connectionOk = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 2
|
||||
/// </summary>
|
||||
protected simPar bit2;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 3
|
||||
/// </summary>
|
||||
protected simPar bit3;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 4
|
||||
/// </summary>
|
||||
protected simPar bit4;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 5
|
||||
/// </summary>
|
||||
protected simPar bit5;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 6
|
||||
/// </summary>
|
||||
protected simPar bit6;
|
||||
|
||||
/// <summary>
|
||||
/// Parametri simulazione oscillazione bit 7
|
||||
/// </summary>
|
||||
protected simPar bit7;
|
||||
|
||||
/// <summary>
|
||||
/// pallet corrente
|
||||
/// </summary>
|
||||
protected int cP = 1;
|
||||
|
||||
protected bool disableSimStatus = false;
|
||||
|
||||
/// <summary>
|
||||
/// ultimo controllo decremento eventi
|
||||
/// </summary>
|
||||
protected DateTime lastEvCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo istante in cui sono stati ridotti dati simulazione duration
|
||||
/// </summary>
|
||||
protected DateTime lastRedDuration;
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo istante in cui sono stati generati dati di simulazione
|
||||
/// </summary>
|
||||
protected DateTime lastSimData;
|
||||
|
||||
/// <summary>
|
||||
/// Matricola OPR simulato
|
||||
/// </summary>
|
||||
protected int matrOpr = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Durata minima ODL x reset quando pezzi iob > pezzi macchina...
|
||||
/// </summary>
|
||||
protected int minDurataODL = 480;
|
||||
|
||||
/// <summary>
|
||||
/// pallet successivo (next)
|
||||
/// </summary>
|
||||
protected int nP = 1;
|
||||
|
||||
/// <summary>
|
||||
/// periodo base del simulatore (in millisecondi)
|
||||
/// </summary>
|
||||
protected int periodoMSec = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// variabile di appoggio x stato segnale contapezzo
|
||||
/// </summary>
|
||||
protected bool sigPzCount = false;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione registrazione dichiarazioni utente
|
||||
/// </summary>
|
||||
protected simPar simDich;
|
||||
|
||||
/// <summary>
|
||||
/// BOOL: indica se simulare powerOn/Off (bit 0 e 1) compresi WarmUp e CoolDown
|
||||
/// </summary>
|
||||
protected bool simPowerOnOff;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione effettuazione controlli utente
|
||||
/// </summary>
|
||||
protected simPar simRC;
|
||||
|
||||
/// <summary>
|
||||
/// Simulazione registro scarti utente
|
||||
/// </summary>
|
||||
protected simPar simRS;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo di MINIMO attesa x simulazione parametri
|
||||
/// </summary>
|
||||
protected int waitSimPar = utils.CRI("waitSimPar");
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Salvo valori PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
dataConf currMem = null;
|
||||
int byteSize = 0;
|
||||
byte[] MemBlock = new byte[1];
|
||||
string memAddrWrite = "";
|
||||
string serObj = "";
|
||||
if (updatedPar != null)
|
||||
{
|
||||
// controllo i parametri... ne gestisco 4...
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
try
|
||||
{
|
||||
memAddrWrite = "";
|
||||
// cerco in area memMapWrite...
|
||||
if (memMap.mMapWrite.ContainsKey(item.uid))
|
||||
{
|
||||
// recupero!
|
||||
currMem = memMap.mMapWrite[item.uid];
|
||||
byteSize = currMem.size;
|
||||
memAddrWrite = currMem.memAddr;
|
||||
MemBlock = new byte[byteSize];
|
||||
// faccio preliminarmente upsertKey...
|
||||
upsertKey(currMem.name, currMem.value);
|
||||
serObj = JsonConvert.SerializeObject(item, Formatting.Indented);
|
||||
lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}{Environment.NewLine}---------------UPDATED PARAM---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
|
||||
serObj = JsonConvert.SerializeObject(currMem, Formatting.Indented);
|
||||
lgInfo($"---------------MEMORY CONTENT---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
|
||||
lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgInfo($"Errore uid non trovato in area write memory: {item.uid}, ci sono {memMap.mMapWrite.Count} in area write");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in fase di plcWriteParams per item {item.uid} con valore {item.value}{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decremento duration del bit indicato secondo stesse regole di ritardo dei bit di wait
|
||||
@@ -226,21 +556,27 @@ namespace IOB_WIN_NEXT
|
||||
case 2:
|
||||
bit2.duration--;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
bit3.duration--;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
bit4.duration--;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
bit5.duration--;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
bit6.duration--;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
bit7.duration--;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -248,6 +584,27 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private List<string> alarmMessages = new List<string>();
|
||||
|
||||
private int currSimAlarmCode = 0;
|
||||
|
||||
private Random rnd = new Random();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica il resto dell'area x i dati accessori (allarmi, ...)
|
||||
/// </summary>
|
||||
private void decodeOtherData()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
||||
/// </summary>
|
||||
@@ -655,7 +1012,7 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// provo a chiamare split ODL
|
||||
/// provo a chiamare split ODL
|
||||
/// </summary>
|
||||
private void trySplitOdl()
|
||||
{
|
||||
@@ -674,351 +1031,6 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Salvo valori PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
dataConf currMem = null;
|
||||
int byteSize = 0;
|
||||
byte[] MemBlock = new byte[1];
|
||||
string memAddrWrite = "";
|
||||
string serObj = "";
|
||||
if (updatedPar != null)
|
||||
{
|
||||
// controllo i parametri... ne gestisco 4...
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
try
|
||||
{
|
||||
memAddrWrite = "";
|
||||
// cerco in area memMapWrite...
|
||||
if (memMap.mMapWrite.ContainsKey(item.uid))
|
||||
{
|
||||
// recupero!
|
||||
currMem = memMap.mMapWrite[item.uid];
|
||||
byteSize = currMem.size;
|
||||
memAddrWrite = currMem.memAddr;
|
||||
MemBlock = new byte[byteSize];
|
||||
// faccio preliminarmente upsertKey...
|
||||
upsertKey(currMem.name, currMem.value);
|
||||
serObj = JsonConvert.SerializeObject(item, Formatting.Indented);
|
||||
lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}{Environment.NewLine}---------------UPDATED PARAM---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
|
||||
serObj = JsonConvert.SerializeObject(currMem, Formatting.Indented);
|
||||
lgInfo($"---------------MEMORY CONTENT---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
|
||||
lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgInfo($"Errore uid non trovato in area write memory: {item.uid}, ci sono {memMap.mMapWrite.Count} in area write");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in fase di plcWriteParams per item {item.uid} con valore {item.value}{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Processo i task richiesti e li elimino dalla coda 1:1 (in realtà SOLO forceSetPzCount x ora)
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
// controlo SE sia disabilitata simulazione principale
|
||||
if (!disableSimStatus)
|
||||
{
|
||||
string taskVal = "";
|
||||
// verifico non sia null
|
||||
if (task2exe != null)
|
||||
{
|
||||
// cerco task specifici
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setArt:
|
||||
case taskType.setComm:
|
||||
case taskType.setProg:
|
||||
case taskType.setPzComm:
|
||||
memMap.mMapWrite[item.Key].value = item.Value;
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | UPDATED memMap.mMapWrite";
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case taskType.nihil:
|
||||
case taskType.fixStopSetup:
|
||||
case taskType.forceResetPzCount:
|
||||
case taskType.sendWatchDogMes2Plc:
|
||||
case taskType.startSetup:
|
||||
case taskType.stopSetup:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
break;
|
||||
|
||||
case taskType.forceSetPzCount:
|
||||
// forzo sul SIM il valore pzCount dell'IOB...
|
||||
int newPzCount = contapezziPLC;
|
||||
bool fatto = int.TryParse(item.Value, out newPzCount);
|
||||
if (fatto)
|
||||
{
|
||||
// verifico SE sia ammesso il cambio ...
|
||||
int deltaPzCount = newPzCount - contapezziPLC;
|
||||
double maxDelta = DateTime.Now.Subtract(plcLastPzRead).TotalMinutes / (plcAvgTc / 60);
|
||||
// se incremento superiore del doppio atteso --> segnalo errore e NON accetto
|
||||
if (deltaPzCount > (maxDelta * maxPzDeltaPerc) / 100)
|
||||
{
|
||||
lgError($"[DELTA CHECK]: intremento contapezziPLC troppo elevato: lettura {newPzCount} | contapezzi attuale: {contapezziPLC} | ultima lettura PLC: {plcLastPzRead} | TCiclo medio: {plcAvgTc}s | incremento accettato ");
|
||||
}
|
||||
else
|
||||
{
|
||||
contapezziPLC = newPzCount;
|
||||
taskVal = $"Set new contapezziPLC: {contapezziPLC}";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = "SKIPPED | NO EXEC";
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera e processa allarmi CNC...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getCncAlarms()
|
||||
{
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec
|
||||
if (lastSimData.AddSeconds(waitSimPar) < DateTime.Now)
|
||||
{
|
||||
Random rnd = new Random();
|
||||
// controllo conf memorie json (se ci sono...)
|
||||
try
|
||||
{
|
||||
if (memMap.mMapWrite.Count > 0)
|
||||
{
|
||||
foreach (var item in memMap.mMapWrite)
|
||||
{
|
||||
outVal.Add(item.Key, item.Value.value);
|
||||
}
|
||||
}
|
||||
if (memMap.mMapRead.Count > 0)
|
||||
{
|
||||
foreach (var item in memMap.mMapRead)
|
||||
{
|
||||
// se il TIPO di valore è livello --> simulo variazione da MAX --> min, con un delta in CALO pari a factor * (80-120)%
|
||||
if (item.Value.name == "SIM_LEVEL")
|
||||
{
|
||||
// verifico last value
|
||||
float lastVal = 0;
|
||||
float.TryParse(item.Value.value, out lastVal);
|
||||
if (lastVal == 0)
|
||||
{
|
||||
lastVal = item.Value.maxVal - (float)item.Value.factor;
|
||||
}
|
||||
// decremento casuale...
|
||||
float newVal = lastVal - ((float)item.Value.factor * rnd.Next(40, 120) / 100);
|
||||
// se inferiore a minimo --> massimo!
|
||||
if (newVal < item.Value.minVal)
|
||||
{
|
||||
newVal = item.Value.maxVal;
|
||||
}
|
||||
// salvo il suo VALUE...
|
||||
item.Value.value = $"{newVal}";
|
||||
outVal.Add(item.Key, $"{newVal}");
|
||||
}
|
||||
// altrimenti siulazione random walk...
|
||||
else
|
||||
{
|
||||
if (item.Value.factor == 1)
|
||||
{
|
||||
// uso factor come valore MAX ammesso
|
||||
int randVal = rnd.Next(item.Value.minVal, item.Value.maxVal);
|
||||
outVal.Add(item.Key, randVal.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// uso factor come fattore di divisione x simulare decimali
|
||||
float randVal = ((float)rnd.Next(item.Value.minVal, item.Value.maxVal)) / (float)item.Value.factor;
|
||||
outVal.Add(item.Key, randVal.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
lastSimData = DateTime.Now;
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero programma in lavorazione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string getPrgName()
|
||||
{
|
||||
// NOME DEL SIM!
|
||||
string prgName = $"PROG_{cIobConf.codIOB}";
|
||||
return prgName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero info sistema generiche
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> getSysInfo()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
outVal.Add("MACHINE", "IOB_SIM");
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua vero processing contapezzi
|
||||
/// </summary>
|
||||
public override void processContapezzi()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processo contatori eventi...
|
||||
/// </summary>
|
||||
public override void processVHF()
|
||||
{
|
||||
if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now)
|
||||
{
|
||||
// decremento contatore ultimo evento
|
||||
try
|
||||
{
|
||||
if (bit2 != null)
|
||||
bit2.wait--;
|
||||
|
||||
if (bit3 != null)
|
||||
bit3.wait--;
|
||||
|
||||
if (bit4 != null)
|
||||
bit4.wait--;
|
||||
|
||||
if (bit5 != null)
|
||||
bit5.wait--;
|
||||
|
||||
if (simDich != null)
|
||||
simDich.wait--;
|
||||
|
||||
if (simRC != null)
|
||||
simRC.wait--;
|
||||
|
||||
if (simRS != null)
|
||||
simRS.wait--;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
lastEvCheck = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale
|
||||
/// <paramref name="currDispData">Parametri da aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
base.readSemafori(ref currDispData);
|
||||
|
||||
// controlo SE sia disabilitata simulazione principale
|
||||
if (!disableSimStatus)
|
||||
{
|
||||
// decodifica e gestione
|
||||
decodeToBaseBitmap();
|
||||
decodeOtherData();
|
||||
reportRawInput(ref currDispData);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua reset del contapezzi
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool resetcontapezziPLC()
|
||||
{
|
||||
bool answ = false;
|
||||
// ...SE abilitato da conf IOB
|
||||
if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
|
||||
{
|
||||
// fingo di aver fatto...
|
||||
answ = true;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
public override void tryConnect()
|
||||
{
|
||||
base.tryConnect();
|
||||
connectionOk = true;
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
base.tryDisconnect();
|
||||
connectionOk = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user