diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 8b141de7..4d80db55 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -18,6 +18,27 @@ namespace IOB_UT_NEXT
OR
}
+ ///
+ /// Modalità di calcolo tra serie di valori
+ ///
+ public enum calcMode
+ {
+ ///
+ /// NEssun processing
+ ///
+ None = 0,
+
+ ///
+ /// somma dei valori
+ ///
+ sum,
+
+ ///
+ /// produttoria
+ ///
+ prod
+ }
+
///
/// Elenco MODI CNC
///
diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs
index e0208cb4..f4984ff4 100644
--- a/IOB-UT-NEXT/ToMapo.cs
+++ b/IOB-UT-NEXT/ToMapo.cs
@@ -166,7 +166,6 @@ namespace IOB_UT_NEXT
///
public void setupData()
{
-
// inizializzo vettore valore allarmi x banco int8 x iniziare
alarmsState = new uint[size];
alarmsMask = new uint[size];
@@ -260,6 +259,11 @@ namespace IOB_UT_NEXT
///
public string keyEStop { get; set; } = "";
+ ///
+ /// Nome variabile x ExeMode
+ ///
+ public string keyExeMode { get; set; } = "";
+
///
/// Nome variabile x pezzi FATTI
///
@@ -286,9 +290,14 @@ namespace IOB_UT_NEXT
public string keyRunMode { get; set; } = "";
///
- /// Nome variabile x ExeMode
+ /// Aree di memoria lettura
///
- public string keyExeMode { get; set; } = "";
+ public Dictionary mMapRead { get; set; } = new Dictionary();
+
+ ///
+ /// Aree di memoria scrittura
+ ///
+ public Dictionary mMapWrite { get; set; } = new Dictionary();
///
/// Dictionary dei nomi da cercare come "endsWith" a cui applicare la soglia indicata
@@ -310,15 +319,18 @@ namespace IOB_UT_NEXT
///
public bool runModeTrad { get; set; } = false;
- ///
- /// Aree di memoria lettura
- ///
- public Dictionary mMapRead { get; set; } = new Dictionary();
+ #endregion Public Properties
+ }
- ///
- /// Aree di memoria scrittura
- ///
- public Dictionary mMapWrite { get; set; } = new Dictionary();
+ ///
+ /// Oggetto x processing valori (elenco valori e modalità)
+ ///
+ public class calcConf
+ {
+ #region Public Properties
+
+ public calcMode calcMode { get; set; } = calcMode.None;
+ public List listVal { get; set; } = new List();
#endregion Public Properties
}
@@ -498,6 +510,22 @@ namespace IOB_UT_NEXT
///
public uint BrowseValue { get; set; } = 5001;
+ ///
+ /// Lista valori calcolati/derivati da processare
+ ///
+ public Dictionary calcValues { get; set; } = new Dictionary();
+
+ ///
+ /// Numero minimo di secondi di durata di uno status
+ ///
+ public int minSecStatusDuration { get; set; } = 1;
+
+ ///
+ /// Numero minimo di secondi di attesa finale (es prima di chiedere chiusura ODL)
+ ///
+ public int minSecFinalWait { get; set; } = 30;
+
+
///
/// Struttura dati x check condizione Contapezzi Abilitato (se vuoto = sempre abilitato)
///
@@ -553,6 +581,12 @@ namespace IOB_UT_NEXT
///
public List filterItemsNodeId { get; set; } = new List();
+ ///
+ /// Elenco item flux da FILTRARE per chiave tradotta/VALORE
+ /// es: Cimolai / Baglietto, RunModeVal NON VOGLIO inviare quando il valore è 0
+ ///
+ public Dictionary> fluxLogKeyValVeto { get; set; } = new Dictionary>();
+
public UserIdent Identity { get; set; } = new UserIdent();
///
@@ -585,13 +619,6 @@ namespace IOB_UT_NEXT
///
public WatchDogConf WatchDog { get; set; } = new WatchDogConf();
-
- ///
- /// Elenco item flux da FILTRARE per chiave tradotta/VALORE
- /// es: Cimolai / Baglietto, RunModeVal NON VOGLIO inviare quando il valore è 0
- ///
- public Dictionary> fluxLogKeyValVeto { get; set; } = new Dictionary>();
-
#endregion Public Properties
}
diff --git a/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.ini b/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.ini
index 1fb48a94..49b8a96f 100644
--- a/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.ini
@@ -71,7 +71,6 @@ CSV_ADD_HEADER=true
VETO_SEND_SNAPSHOT=3
-
;NO_PING=FALSE
; conf aree allarme
ALARM_CONF=BAGLIETTO_CIMOLAI_01_alarm.json
diff --git a/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.json b/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.json
index 4166f851..c5c90e95 100644
--- a/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.json
+++ b/IOB-WIN-NEXT/DATA/CONF/BAGLIETTO_CIMOLAI_01.json
@@ -193,5 +193,18 @@
"-1",
"0"
]
+ },
+ "minSecStatusDuration": 10,
+ "minSecFinalWait": 180,
+ "calcValues": {
+ "PesoTot": {
+ "calcMode": "sum",
+ "listVal": [
+ "PLC/DB231/peso1",
+ "PLC/DB231/peso2",
+ "PLC/DB231/peso3",
+ "PLC/DB231/peso4"
+ ]
+ }
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs
index a08be818..beb86200 100644
--- a/IOB-WIN-NEXT/IobGeneric.cs
+++ b/IOB-WIN-NEXT/IobGeneric.cs
@@ -1173,6 +1173,26 @@ namespace IOB_WIN_NEXT
}
}
+ ///
+ /// URL per richiesta chiusura manuale ad utente x ODL corrente (metodo GET)...
+ ///
+ public string urlODLAskClose
+ {
+ get
+ {
+ string answ = "";
+ try
+ {
+ answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/askCloseODL/{cIobConf.codIOB}?idxOdl=";
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in composizione urlODLClose");
+ }
+ return answ;
+ }
+ }
+
///
/// URL per chiusura ODL corrente (metodo GET)...
///
@@ -5846,14 +5866,37 @@ namespace IOB_WIN_NEXT
protected bool tryCloseODL()
{
bool fatto = false;
+ string fullUrl = $"{urlODLClose}{currIdxODL}";
try
{
- // invio chiamata URL x reset ODL su macchina
- string rawSplit = callUrl($"{urlODLClose}{currIdxODL}", false);
- fatto = (rawSplit != "KO") ? true : false;
+ // invio chiamata URL x chiusura ODL su macchina
+ string callResp = callUrl(fullUrl, false);
+ fatto = (callResp != "KO") ? true : false;
}
catch
{ }
+ lgInfo($"Eseguito tryCloseODL per {currIdxODL} | url: {fullUrl} | esito: {fatto}");
+ return fatto;
+ }
+
+
+ ///
+ /// Effettua chiamata MP-IO per cheidere all'utente se vuole effettuare chiusura ODL corrente della macchina
+ ///
+ ///
+ protected bool tryAskCloseODL()
+ {
+ bool fatto = false;
+ string fullUrl = $"{urlODLAskClose}{currIdxODL}";
+ try
+ {
+ // invio chiamata URL x chiusura ODL su macchina
+ string callResp = callUrl(fullUrl, false);
+ fatto = (callResp != "KO") ? true : false;
+ }
+ catch
+ { }
+ lgInfo($"Eseguito tryAskCloseODL per {currIdxODL} | url: {fullUrl} | esito: {fatto}");
return fatto;
}
diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs
index e471ce4f..45bddd7e 100644
--- a/IOB-WIN-NEXT/IobOpcUa.cs
+++ b/IOB-WIN-NEXT/IobOpcUa.cs
@@ -165,6 +165,22 @@ namespace IOB_WIN_NEXT
return answ;
}
+ ///
+ /// Recupera valore OPC-UA direttamente in formato double
+ ///
+ ///
+ ///
+ public double getDataItemValueDouble(string diKey)
+ {
+ double answ = 0;
+ string rawVal = getDataItemValue(diKey);
+ if (rawVal != null)
+ {
+ double.TryParse(diKey, out answ);
+ }
+ return answ;
+ }
+
///
/// Recupero dati dinamici...
///
@@ -531,7 +547,7 @@ namespace IOB_WIN_NEXT
return changed;
}
- internal virtual void procRunMode(ref string currRun)
+ protected virtual void procRunMode(ref string currRun)
{
// variabili RUN... se richiesto invio runMode
if (opcUaParams.runModeSend)
diff --git a/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs b/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs
index 374a5279..6cb15f3e 100644
--- a/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs
+++ b/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs
@@ -170,14 +170,14 @@ namespace IOB_WIN_NEXT
#region Internal Methods
- internal override void procRunMode(ref string currRun)
+ protected override void procRunMode(ref string currRun)
{
// variabili RUN... se richiesto invio runMode
if (opcUaParams.runModeSend)
{
- currRun = $"{currAct}";
- // effettuo processing SPECIFICO currAct x gestione snapshot...
- if (currAct == 10)
+ currRun = $"{currRunMode}";
+ // effettuo processing SPECIFICO currRunMode x gestione snapshot...
+ if (currRunMode == 10)
{
if (DateTime.Now > vetoSnapshot)
{
@@ -236,6 +236,98 @@ namespace IOB_WIN_NEXT
}
}
}
+
+ // gestione dei macro-stati del travel... SOLO se in esecuzione da travel o con ODL>0...
+ if (currExeMode > 0)
+ {
+ double pesoTot = 0;
+ DateTime adesso = DateTime.Now;
+ // può cambiare stato se per ALMENO minSecStatus è rimasto nello status corrente...
+ bool canChange = adesso.Subtract(currTravelStateStart).TotalSeconds > opcUaParams.minSecStatusDuration;
+ if (canChange)
+ {
+ // STEP 1: verifico se sia iniziato caricamento...
+ if (currTravelState == travelState.Idle)
+ {
+ if (currIdxODL > 0)
+ {
+ currTravelState = travelState.StartOdl;
+ currTravelStateStart = adesso;
+ }
+ }
+ // sono nell'esecuzione ODL, controllo il resto
+ else
+ {
+ // nb: vedere se usare isWorkingCimolai / isManualCimolai
+
+ // verifico il valore della variabile calcolata del PESO totale...
+ if (dataItemMem.ContainsKey("PesoTot"))
+ {
+ pesoTot = getDataItemValueDouble("PesoTot");
+ }
+ // ...oppuresommo direttamente
+ else
+ {
+ pesoTot += getDataItemValueDouble("PLC/DB231/peso1");
+ pesoTot += getDataItemValueDouble("PLC/DB231/peso2");
+ pesoTot += getDataItemValueDouble("PLC/DB231/peso3");
+ pesoTot += getDataItemValueDouble("PLC/DB231/peso4");
+ }
+
+ // STEP 2: verifico se sia iniziato caricamento...
+ if (currTravelState == travelState.StartOdl)
+ {
+ if (pesoTot > 0)
+ {
+ currTravelState = travelState.UpLift;
+ currTravelStateStart = adesso;
+ }
+ }
+ // STEP 3: verifico se sia terminato caricamento...
+ else if (currTravelState == travelState.UpLift)
+ {
+ if (pesoTot == 0)
+ {
+ currTravelState = travelState.Move;
+ currTravelStateStart = adesso;
+ }
+ }
+ // STEP 4: verifico se sia terminato movimento...
+ else if (currTravelState == travelState.Move)
+ {
+ if (pesoTot > 0)
+ {
+ currTravelState = travelState.DownLift;
+ currTravelStateStart = adesso;
+ }
+ }
+ // STEP 5: verifico se sia terminato scaricamento...
+ else if (currTravelState == travelState.DownLift)
+ {
+ if (pesoTot == 0)
+ {
+ currTravelState = travelState.WaitClose;
+ currTravelStateStart = adesso;
+ }
+ }
+ }
+ }
+
+ // ora verifico solo condizione finale x eventuale chiusura...
+ bool sendAskClose = adesso.Subtract(currTravelStateStart).TotalSeconds > opcUaParams.minSecFinalWait;
+ if (currTravelState == travelState.WaitClose && sendAskClose)
+ {
+ // chiama richiesta chiusura x utente
+ tryAskCloseODL();
+ // resetta contatore x nuova richeista finale eventuale...
+ currTravelStateStart = adesso;
+ }
+ }
+ else
+ {
+ // altrimenti forzo a "Idle" state
+ currTravelState = travelState.Idle;
+ }
}
#endregion Internal Methods
@@ -244,7 +336,8 @@ namespace IOB_WIN_NEXT
protected int lastAct = 0;
- protected int lastExe = 0;
+
+ protected int lastExeMode = 0;
protected int VETO_SEND_SNAPSHOT = 10;
@@ -257,14 +350,14 @@ namespace IOB_WIN_NEXT
///
/// Attività corrente (INT) da keyRunMode valore di PLC/DB231/Attivita
///
- protected int currAct
+ protected int currRunMode
{
get
{
int answ = 0;
- if (!string.IsNullOrEmpty(opcUaParams.keyExeMode))
+ if (!string.IsNullOrEmpty(opcUaParams.keyRunMode))
{
- string currRun = getDataItemValue(opcUaParams.keyExeMode);
+ string currRun = getDataItemValue(opcUaParams.keyRunMode);
if (!string.IsNullOrEmpty(currRun))
{
int.TryParse(currRun, out answ);
@@ -277,7 +370,7 @@ namespace IOB_WIN_NEXT
///
/// Attività corrente (INT) da keyExeMode valore di PLC/DB231/InCorso
///
- protected int currExe
+ protected int currExeMode
{
get
{
@@ -413,15 +506,15 @@ namespace IOB_WIN_NEXT
}
// verifico se aggiornare stato LAST ACTION
- if (lastAct != currAct && currAct != 0)
+ if (lastAct != currRunMode && currRunMode != 0)
{
// registro solo azioni > 1 e < 10
- if (currAct > 1 && currAct < 10)
+ if (currRunMode > 1 && currRunMode < 10)
{
// escludo le azioni 4 e 5 (che sono anche in concomitanza con 2-3)
- if (currAct < 4 || currAct > 5)
+ if (currRunMode < 4 || currRunMode > 5)
{
- lastAct = currAct;
+ lastAct = currRunMode;
}
}
}
@@ -431,10 +524,10 @@ namespace IOB_WIN_NEXT
{
// se rilevo variazione exe (curr/last)
// --> registro richiesta attreazzaggio PODL da info commessa
- if (lastExe != currExe)
+ if (lastExeMode != currExeMode)
{
// se 0--> 1 --> registro
- if (currExe == 1)
+ if (currExeMode == 1)
{
lgInfo("--------------------------------------------");
// prendo senza stringa PODL
@@ -455,7 +548,7 @@ namespace IOB_WIN_NEXT
lgInfo("--------------------------------------------");
}
// registro exe mode
- lastExe = currExe;
+ lastExeMode = currExeMode;
}
}
@@ -675,7 +768,7 @@ namespace IOB_WIN_NEXT
WriteValue commWriteVal = new WriteValue();
commWriteVal.NodeId = new NodeId(item.Key);
commWriteVal.AttributeId = Attributes.Value;
- commWriteVal.Value = new DataValue();
+ commWriteVal.Value = new DataValue();\
commWriteVal.Value.Value = item.Value;
nodes2Write.Add(commWriteVal);
@@ -722,5 +815,21 @@ namespace IOB_WIN_NEXT
}
#endregion Private Methods
+
+ protected DateTime currTravelStateStart { get; set; } = DateTime.Today.AddYears(-1);
+ protected travelState currTravelState { get; set; } = travelState.Idle;
+
+ ///
+ /// Definizione stati travel
+ ///
+ protected enum travelState
+ {
+ Idle = 0,
+ StartOdl,
+ UpLift,
+ Move,
+ DownLift,
+ WaitClose
+ }
}
}
\ No newline at end of file