Update PRESSOIL-CEI

This commit is contained in:
Samuele E. Locatelli
2019-11-08 18:47:47 +01:00
parent fb5d5d5bb1
commit bdfd0787c4
7 changed files with 266 additions and 254 deletions
+7 -20
View File
@@ -27,8 +27,8 @@ CMDREBO=/sendReboot.aspx?idxMacchina=
[MEMORY]
ADDR_READ=DB64.DBB0
ADDR_WRITE=DB67.DBB0
SIZE_READ=24
SIZE_WRITE=4
SIZE_READ=30
SIZE_WRITE=770
;BIT0=CONN
;BIT1=DB60.DBB1
;BIT2=PZCOUNT.STD.DB700.DBW22
@@ -51,29 +51,16 @@ BLINK_FILT=0
;BLINK_FILT=28
[OPTPAR]
NO_PING=true
;NO_PING=true
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
; attenzione memoria sempre base BYTE (1604 DW --> 6416...)
PZCOUNT_MODE=STD.DB1001.DBDW2
PZCOUNT_MODE=STD.DB64.DBDW2
DISABLE_PZCOUNT=TRUE
ENABLE_DYN_DATA=TRUE
FORCE_DYN_DATA=TRUE
TSVC_Power_01=MAX:5
TSVC_Power_02=MAX:5
TSVC_Power_03=MAX:5
TSVC_Power_04=MAX:5
TSVC_TempPirom_01=MAX:5
TSVC_TempPirom_02=MAX:5
TSVC_TempPirom_03=MAX:5
TSVC_TempPirom_04=MAX:5
TSVC_TempCool_01=MAX:5
TSVC_TempCool_02=MAX:5
TSVC_TempCool_03=MAX:5
TSVC_TempCool_04=MAX:5
TSVC_PartStatus_01=MAX:5
TSVC_PartStatus_02=MAX:5
TSVC_PartStatus_03=MAX:5
TSVC_PartStatus_04=MAX:5
NEW_DYN_DATA=TRUE
; conf parametri memoria READ/WRITE
PARAM_CONF=VL23.json
[BRANCH]
NAME=master
+126
View File
@@ -0,0 +1,126 @@
{
"mMapWrite": {
"setArt": {
"name": "setArt",
"description": "Articolo",
"memAddr": "DB67.DBB2",
"tipoMem": "String",
"index": 2,
"size": 256
},
"setComm": {
"name": "setComm",
"description": "Commessa",
"memAddr": "DB67.DBB258",
"tipoMem": "String",
"index": 258,
"size": 256
},
"setPzComm": {
"name": "setPzComm",
"description": "Qty",
"memAddr": "DB67.DBB514",
"tipoMem": "String",
"index": 514,
"size": 256
}
},
"mMapRead": {
"Temp_Olio": {
"name": "Temp_Olio",
"description": "Temperatura Olio",
"memAddr": "DB64.DBB6",
"tipoMem": "Real",
"index": 6,
"size": 4,
"func": "MAX",
"period": 60,
"factor": 1
},
"Power": {
"name": "Power",
"description": "Forza",
"memAddr": "DB64.DBB10",
"tipoMem": "Real",
"index": 10,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
},
"VelAsseSup": {
"name": "VelAsseSup",
"description": "Vel Asse Superiore",
"memAddr": "DB64.DBB12",
"tipoMem": "Real",
"index": 12,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
},
"VelAsseInf": {
"name": "VelAsseInf",
"description": "Vel Asse Inferiore",
"memAddr": "DB64.DBB14",
"tipoMem": "Real",
"index": 14,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
},
"Pressione": {
"name": "Pressione",
"description": "Pressione",
"memAddr": "DB64.DBB16",
"tipoMem": "Real",
"index": 16,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
},
"Tensione": {
"name": "Tensione",
"description": "Tensione",
"memAddr": "DB64.DBB18",
"tipoMem": "Real",
"index": 18,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
},
"Corrente": {
"name": "Corrente",
"description": "Corrente",
"memAddr": "DB64.DBB20",
"tipoMem": "DInt",
"index": 20,
"size": 4,
"func": "MAX",
"period": 60
},
"Potenza": {
"name": "Potenza",
"description": "Potenza",
"memAddr": "DB64.DBB24",
"tipoMem": "DInt",
"index": 24,
"size": 4,
"func": "MAX",
"period": 60
},
"CosPhi": {
"name": "CosPhi",
"description": "CosPhi",
"memAddr": "DB64.DBB88",
"tipoMem": "Real",
"index": 28,
"size": 2,
"func": "MAX",
"period": 60,
"factor": 1
}
} }
+1
View File
@@ -248,6 +248,7 @@
<None Include="DATA\CONF\SIMUL_06.json" />
<None Include="DATA\CONF\SIMUL_07.json" />
<None Include="DATA\CONF\SIMUL_08.json" />
<None Include="DATA\CONF\VL23.json" />
<None Include="DATA\CONF\VL22.json" />
<None Include="DATA\CONF\VL21.json" />
<None Include="DATA\CONF\VL20.json" />
+6 -1
View File
@@ -92,7 +92,6 @@ namespace IOB_WIN
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setProg:
case taskType.stopSetup:
case taskType.sendWatchDogMes2Plc:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
@@ -133,6 +132,12 @@ namespace IOB_WIN
MemBlock[0] = (byte)1;
memAddrWrite = "DB150.DBB4";
break;
case taskType.stopSetup:
// processo scrittura BIT su DB150.DBX4.0
MemBlock = new byte[1];
MemBlock[0] = (byte)0;
memAddrWrite = "DB150.DBB4";
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
+9 -3
View File
@@ -176,8 +176,6 @@ namespace IOB_WIN
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setProg:
case taskType.startSetup:
case taskType.stopSetup:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.setArt:
@@ -219,7 +217,15 @@ namespace IOB_WIN
int valore = inSetup ? 1 : 0;
valore += (byte)(counterMes2Plc << 7);
MemBlock[0] = (byte)valore;
taskVal = $"VALUE DB1002.92 --> {counterMes2Plc}";
taskVal = $"VALUE DB1002.92 --> {valore} | counter interno {counterMes2Plc}";
break;
case taskType.startSetup:
// salvo che SONO IN SETUP!
inSetup = true;
break;
case taskType.stopSetup:
// salvo che SONO FUORI DAL SETUP!
inSetup = false;
break;
default:
taskVal = "SKIPPED | NO EXEC";
+116 -229
View File
@@ -1,5 +1,4 @@
using IOB_UT;
using MapoSDK;
using MapoSDK;
using System;
using System.Collections.Generic;
@@ -11,51 +10,11 @@ namespace IOB_WIN
public class IobSiemensPressoilCei : IobSiemens
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS SAET (impianti ad induzione in VALVITAL)
* Controlli SIEMENS CEI PRESSOIL (impianti ad induzione in VALVITAL)
* - basasto su SIEMENS
* - S7 vers 1500
*
* STRUTTURA MEMORIA DB1275: primi 92 byte lettura, poi 56 byte scrittura, vedere doc allegato
* G:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\SAET (forno e tempra)
*
* Si intende tutto con DB1275.DBxx
*
* - parametri processo
* - DBD00: Watchdog INT SAET Alive ( 1-9999 )
*
* - DB60.DBD6: pressione camera filtrante (salvataggio del MAX ogni minuto) | var testVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(0).Take(4).ToArray());
* - DB60.DBD10: pressione linea utenze (salvataggio del MAX ogni minuto)
* - DB60.DBD14: temperatura acqua pulita (salvataggio del MAX ogni minuto)
*
* - BIT di stato
* - DBX2.1: READY TO RUN in AUTOMATICO
* - DBX2.3: Macchina in LAVORAZIONE
* - DBX2.4: WARNING Differenza tra Part Code MES - Saet (blu)
* - DBX2.5: se 1 --> LAMPADA ROSSA (allarmi almeno 1 attivo)
*
* PartCounter DINT 4.0 Conteggio Parziale di pezzi "OK" prodotti dalla macchina
* NumberCode String [12] 8.0 Valore numerico associato alla ricetta di produzione attualmente utilizzata dalla macchina
* NewCode INT 22.0 "1= Avvenuta ricezione del segnale ""richiesta nuovo ordine di produzione (NEW CODE)""
* ricevuto dal server,impostabile su 1 solo quando la macchina NON è in produzione attiva"
* Potenza utilizzata ST.1 REAL 24 Potenza utilizzata dalla stazione di riscaldo 1 [kW]
* Potenza utilizzata ST.2 REAL 28 Potenza utilizzata dalla stazione di riscaldo 2 [kW]
* Potenza utilizzata ST.3 REAL 32 Potenza utilizzata dalla stazione di riscaldo 3 [kW]
* Potenza utilizzata ST.4 REAL 36 Potenza utilizzata dalla stazione di riscaldo 4 [kW]
* Lettura Pirometro ST.1 REAL 40 Lettura Pirometro della stazione di riscaldo 1 [°C]
* Lettura Pirometro ST.2 REAL 44 Lettura Pirometro della stazione di riscaldo 2 [°C]
* Lettura Pirometro ST.3 REAL 48 Lettura Pirometro della stazione di riscaldo 3 [°C]
* Lettura Pirometro ST.4 REAL 52 Lettura Pirometro della stazione di riscaldo 4 [°C]
* Temperatura Acqua Raff Conv. ST.1 REAL 56 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 1 [°C]
* Temperatura Acqua Raff Conv. ST.2 REAL 60 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 2 [°C]
* Temperatura Acqua Raff Conv. ST.3 REAL 64 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 3 [°C]
* Temperatura Acqua Raff Conv. ST.4 REAL 68 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 4 [°C]
* Part_Status ST.1 INT 72 Stato Pezzo Stazione di Riscaldo 1 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.2 INT 74 Stato Pezzo Stazione di Riscaldo 2 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.3 INT 76 Stato Pezzo Stazione di Riscaldo 3 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.4 INT 78 Stato Pezzo Stazione di Riscaldo 4 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Reserve_12 REAL 80 Riserva
* Reserve_13 REAL 84 Riserva
* Reserve_14 REAL 88 Riserva
* STRUTTURA MEMORIA DB64 READ e DB67 WRITE, vedere file conf json
* -------------------------------------------------------------------------------- */
@@ -71,68 +30,10 @@ namespace IOB_WIN
public IobSiemensPressoilCei(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
lgInfo("NEW IOB SIEMENS versione PRESSOIL - CEI");
lastPLCWatchDog = DateTime.Now.AddMinutes(-1);
// imposto i parametri speciali x calcolo...
var chiaviTSVC = findOptPar("TSVC");
if (chiaviTSVC.Count > 0)
{
lgInfo($"Trovate {chiaviTSVC.Count} chiavi TSVC");
string[] codVal;
VCData currConf;
int periodo = 0;
VC_func funz = VC_func.POINT;
// accodo nella conf...
foreach (var item in chiaviTSVC)
{
codVal = item.Value.Split(':');
Enum.TryParse(codVal[0], out funz);
int.TryParse(codVal[1], out periodo);
currConf = new VCData()
{
Funzione = funz,
Period = periodo,
DTStart = DateTime.Now.AddHours(-1),
dataArray = new List<double>()
};
TSVC_Data.Add(item.Key.Replace("TSVC_", ""), currConf);
}
// documento...
foreach (var item in TSVC_Data)
{
lgInfo($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
// salvo i valori PREC...
LastTSVC.Add(item.Key, 0);
}
}
}
#region Metodi specifici (da verificare/completare in implementazione)
/// <summary>
/// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
/// </summary>
public override void processOverride()
{
}
public override void processWhatchDog()
{
// scrivo 1 volta al secondo il contatore incrementale su area apposita
DateTime adesso = DateTime.Now;
if (adesso.Subtract(lastPLCWatchDog).TotalSeconds > 1)
{
// incremento
counterMes2Plc++;
// salvo su DB
Dictionary<string, string> task2exe = new Dictionary<string, string>();
Dictionary<string, string> taskDone = new Dictionary<string, string>();
task2exe.Add("SendWatchDogMes2Plc", counterMes2Plc.ToString());
taskDone = executeTasks(task2exe);
// salvo watchdog PLC
lastPLCWatchDog = adesso;
}
}
/// <summary>
/// Processo i task richiesti e li elimino dalla coda 1:1
/// </summary>
@@ -143,109 +44,95 @@ namespace IOB_WIN
Dictionary<string, string> taskDone = new Dictionary<string, string>();
bool taskOk = false;
string taskVal = "";
// inizio con 1 byte VUOTO
byte[] MemBlock = new byte[2];
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
foreach (var item in task2exe)
// inizio con 1 byte di default
byte[] MemBlock = new byte[1];
string memAddrWrite = "";
if (task2exe != null)
{
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
// controllo sulla KEY
//!!!FIXME!!! totalmente da rivedere
switch (tName)
// cerco task specifici
foreach (var item in task2exe)
{
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setArt:
case taskType.setComm:
case taskType.setProg:
case taskType.startSetup:
case taskType.stopSetup:
case taskType.sendWatchDogMes2Plc:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
// controllo sulla KEY
switch (tName)
{
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setProg:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.setArt:
case taskType.setComm:
case taskType.setPzComm:
saveProdData(item);
int byteSize = 0;
// recupero dati da memMap... altrimenti NULLA
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
byteSize = currMem.size;
memAddrWrite = currMem.memAddr;
MemBlock = new byte[byteSize];
if (currMem.tipoMem == plcDataType.String)
{
saveStringOnMemBlock(ref MemBlock, item.Key, 0, byteSize, true);
}
else if (currMem.tipoMem == plcDataType.DInt)
{
int valDInt = 0;
int.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
}
else if (currMem.tipoMem == plcDataType.Int)
{
short valDInt = 0;
short.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.Int.ToByteArray(valDInt);
}
}
taskVal = item.Value;
break;
case taskType.sendWatchDogMes2Plc:
// processo scrittura BIT su DB67.DBX0.0
MemBlock = new byte[1];
memAddrWrite = "DB67.DBB0";
// compogo in byte... primo bit è setup/run, ultimo è watchdog
int valore = inSetup ? 1 : 0;
valore += (byte)(counterMes2Plc << 7);
MemBlock[0] = (byte)valore;
taskVal = $"VALUE DB67.0 --> {valore} | counter interno {counterMes2Plc}";
break;
case taskType.startSetup:
// salvo che SONO IN SETUP!
inSetup = true;
break;
case taskType.stopSetup:
// salvo che SONO FUORI DAL SETUP!
inSetup = false;
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
// scrivo comunque!
taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
if (!taskOk)
{
lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
}
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
}
// scrivo comunque!
taskOk = S7WriteBB(ref MemBlock);
return taskDone;
}
/// <summary>
/// Recupero dati dinamici in formato dictionary
/// </summary>
/// <returns></returns>
public override Dictionary<string, string> getDynData()
{
Dictionary<string, string> outVal = new Dictionary<string, string>();
#if false
try
{
/* ----------------------------------------------------------
* DB60.DBD6: pressione camera filtrante (salvataggio del MAX ogni minuto) | var testVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(0).Take(4).ToArray());
* DB60.DBD10: pressione linea utenze (salvataggio del MAX ogni minuto)
* DB60.DBD14: temperatura acqua pulita (salvataggio del MAX ogni minuto)
* */
double pressCamFilt = S7.Net.Types.Double.FromByteArray(RawInput.Skip(6).Take(4).ToArray());
double pressLinUt = S7.Net.Types.Double.FromByteArray(RawInput.Skip(10).Take(4).ToArray());
double tempH2O = S7.Net.Types.Double.FromByteArray(RawInput.Skip(14).Take(4).ToArray());
if (utils.CRB("enableTSVC"))
{
// salvo in stack le VC rilevate
bool scad01 = stackVal_TSVC("pressCamFilt", pressCamFilt);
bool scad02 = stackVal_TSVC("pressLinUt", pressLinUt);
bool scad03 = stackVal_TSVC("tempH2O", tempH2O);
// verifico SE devo riportare dati VC
if (scad01 || scad02 || scad03)
{
pressCamFilt = getVal_TSVC("pressCamFilt", scad01);
pressLinUt = getVal_TSVC("pressLinUt", scad02);
tempH2O = getVal_TSVC("tempH2O", scad03);
outVal.Add("DYNDATA", $"pressCamFilt {pressCamFilt:N6} | pressLinUt {pressLinUt:N6} | tempH2O {tempH2O:N3}");
outVal.Add("pressCamFilt", $"{pressCamFilt:N6}");
outVal.Add("pressLinUt", $"{pressLinUt:N6}");
outVal.Add("tempH2O", $"{tempH2O:N3}");
// salvo!
LastTSVC["pressCamFilt"] = pressCamFilt;
LastTSVC["pressLinUt"] = pressLinUt;
LastTSVC["tempH2O"] = tempH2O;
}
else
{
outVal.Add("DYNDATA", $"pressCamFilt {LastTSVC["pressCamFilt"]:N6} | pressLinUt {LastTSVC["pressLinUt"]:N6} | tempH2O {LastTSVC["tempH2O"]:N3}");
}
}
else
{
outVal.Add("pressCamFilt", $"{pressCamFilt:N6}");
outVal.Add("pressLinUt", $"{pressLinUt:N6}");
outVal.Add("tempH2O", $"{tempH2O:N3}");
outVal.Add("DYNDATA", $"pressCamFilt {pressCamFilt:N3} | pressLinUt {pressLinUt:N3} | tempH2O {tempH2O:N3}");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in getDynData x Siemens Aprochim");
}
#endif
return outVal;
}
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
@@ -265,51 +152,51 @@ namespace IOB_WIN
*
*
* - BIT di stato
* - DB60.DBX3.0: AUSILIARI INSERITI = NO EMERGENZA
* - DB60.DBX3.1: Filtro (macchina) in LAVORAZIONE
* - DB60.DBX3.2: Selettore in AUTOMATICO (sennò GIALLO)
* - DB60.DBX3.3: WARNING MIN LIV VASCA (arancio)
* - DB60.DBX3.4: WARNING MIN LIV CELLULOSA (blu)
* - DB60.DBX3.5: LAMPADA ROSSA (allarmi almeno 1 attivo)
* - DBX0.0 - Life bit
* - DBX0.1 Macchina lavora
* - DBX0.2 Macchina in ciclo
* - DBX0.3 Macchina in manuale
* - DBX0.4 Macchina in allarme
* - DBX0.5 Macchina in emergenza
*
----------------------------------------------------- */
byte mainData = RawInput[0];
/* -----------------------------------------------------
* bitmap MAPO FILTRO Aprochim
* B0: POWER_ON
* B1: RUN
* B2: AUTOMATICO
* B3: WARN_MIN_VASCA
* B4: WARN_MIN_CELL
* B5: ALARM
* B6: EMERGENZA
----------------------------------------------------- */
// bit 0 (poweron) imposto a 1 SE connected...
B_input = currPLC.IsConnected ? 1 : 0;
// recupero byte segnali...
int byteSignals = RawInput[3];
// aggiungo "in coda" primo bit emergenza...essendo un bit negato (NON emergenza) lo cambio di segno
if ((byteSignals & (1 << 0)) == 0)
{
byteSignals += (1 << 6);
}
// cancello primo bit (faccio uno shift a dx e poi a sx di 1...)
byteSignals = ((byteSignals >> 1) << 1);
int byteSignals = 0;
// bit 0 (poweron) imposto a 1 SE connected...
if (currPLC.IsConnected)
{
byteSignals += (1 << 0);
}
// RUN se lavora ed in ciclo
if ((mainData & (1 << 1)) == 1 && (mainData & (1 << 2)) == 1)
{
byteSignals += (1 << 1);
}
// manuale
if ((mainData & (1 << 3)) == 1)
{
byteSignals += (1 << 4);
}
// allarme
if ((mainData & (1 << 4)) == 1)
{
byteSignals += (1 << 3);
}
// emergenza
if ((mainData & (1 << 5)) == 1)
{
byteSignals += (1 << 5);
}
// salvo!
B_input = byteSignals;
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[3]} --> B_input: {B_input}"));
lgInfo($"Trasformazione dati: RawInput:{RawInput[0]} --> B_input: {B_input}");
}
}
Vendored
+1 -1
View File
@@ -16,7 +16,7 @@ pipeline {
/* calcolo numero versione... diverso x branch MASTER/DEVELOP */
script {
withEnv(['NEXT_BUILD_NUMBER=505']) {
withEnv(['NEXT_BUILD_NUMBER=506']) {
// env.versionNumber = VersionNumber(versionNumberString : '2.4.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true)
env.versionNumber = VersionNumber(versionNumberString : '2.4.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}')
env.APP_NAME = 'MAPO-IOB-WIN'