Aggiunta BOZZA siemens selezione comur

This commit is contained in:
Samuele E. Locatelli
2019-10-22 17:59:25 +02:00
parent b1f9446667
commit e4a553add5
3 changed files with 491 additions and 0 deletions
+4
View File
@@ -670,6 +670,10 @@ namespace IOB_WIN
iobObj = new IobSiemensAt2001(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS_COMUR:
iobObj = new IobSiemensComur(this, IOBConf);
start.Enabled = true;
break;
case tipoAdapter.SIEMENS_FAPE:
iobObj = new IobSiemensFape(this, IOBConf);
start.Enabled = true;
+78
View File
@@ -0,0 +1,78 @@
;Configurazione IOB-WIN
[IOB]
;Macchina preriscaldo barre per Valvital
CNCTYPE=SIEMENS_COMUR
PING_MS_TIMEOUT=500
[MACHINE]
VENDOR=COMUR
MODEL=DENTATRICE
[CNC]
IP=192.168.214.21
CPUTYPE=S71500
RACK=0
SLOT=0
[SERVER]
MPIP=http://192.168.214.4
MPURL=/MP/IO
CMDBASE=/IOB/input/
CMDFLOG=/IOB/flog/
CMDALIVE=/IOB
CMDENABLED=/IOB/enabled/
CMDADV1=?valore=
CMDREBO=/sendReboot.aspx?idxMacchina=
[MEMORY]
ADDR_READ=DB1275.DBB0
ADDR_WRITE=DB1275.DBB92
SIZE_READ=92
SIZE_WRITE=56
;BIT0=CONN
;BIT1=DB60.DBB1
;BIT2=PZCOUNT.STD.DB700.DBW22
;BIT3=DB60.DBB3
;BIT4=DB60.DBB4
[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.[PAR/MEM].info|BIT.indice
; attenzione memoria sempre base BYTE (1604 DW --> 6416...)
PZCOUNT_MODE=STD.DB1275.DBDW4
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
[BRANCH]
NAME=master
+409
View File
@@ -0,0 +1,409 @@
using IOB_UT;
using System;
using System.Collections.Generic;
using System.Linq;
namespace IOB_WIN
{
/// <summary>
/// Controllo Siemens specifico x impianti COMUR
/// </summary>
public class IobSiemensComur : IobSiemens
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS SAET (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
* -------------------------------------------------------------------------------- */
protected DateTime lastPLCWatchDog;
protected int counterMes2Plc = 0;
protected int counterPlc2Mes = 0;
protected int counterPlc2MesWrote = 0;
protected Dictionary<string, double> LastTSVC = new Dictionary<string, double>();
/// <summary>
/// Classe base con i metodi x Siemens
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public IobSiemensComur(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
lgInfo("NEW IOB SIEMENS versione SAET");
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++;
// se > 9999 --> 0
if (counterMes2Plc > 9999) counterMes2Plc = 0;
// 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>
/// <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>();
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)
{
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.setArt:
case taskType.setComm:
case taskType.setProg:
case taskType.startSetup:
case taskType.stopSetup:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.sendWatchDogMes2Plc:
MemBlock[1] = (byte)counterMes2Plc;
MemBlock[0] = (byte)(counterMes2Plc >> 8);
taskVal = $"VALUE DB1275.92 --> {counterMes2Plc}";
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
}
// scrivo comunque!
bool fatto = 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 true
try
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS SAET (impianti ad induzione in VALVITAL)
*
* 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)
*
* 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)
* -------------------------------------------------------------------------------- */
/* ----------------------------------------------------------
* 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 Power_01 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(24).Take(4).ToArray());
double Power_02 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(28).Take(4).ToArray());
double Power_03 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(32).Take(4).ToArray());
double Power_04 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(36).Take(4).ToArray());
double TempPirom_01 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(40).Take(4).ToArray());
double TempPirom_02 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(44).Take(4).ToArray());
double TempPirom_03 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(48).Take(4).ToArray());
double TempPirom_04 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(52).Take(4).ToArray());
double TempCool_01 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(56).Take(4).ToArray());
double TempCool_02 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(60).Take(4).ToArray());
double TempCool_03 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(64).Take(4).ToArray());
double TempCool_04 = S7.Net.Types.Double.FromByteArray(RawInput.Skip(68).Take(4).ToArray());
int PartStatus_01 = S7.Net.Types.Int.FromByteArray(RawInput.Skip(72).Take(2).ToArray());
int PartStatus_02 = S7.Net.Types.Int.FromByteArray(RawInput.Skip(74).Take(2).ToArray());
int PartStatus_03 = S7.Net.Types.Int.FromByteArray(RawInput.Skip(76).Take(2).ToArray());
int PartStatus_04 = S7.Net.Types.Int.FromByteArray(RawInput.Skip(78).Take(2).ToArray());
if (utils.CRB("enableTSVC"))
{
bool[] scaduti = new bool[16];
// salvo in stack le VC rilevate
scaduti[0] = stackVal_TSVC("Power_01", Power_01);
scaduti[1] = stackVal_TSVC("Power_02", Power_02);
scaduti[2] = stackVal_TSVC("Power_03", Power_03);
scaduti[3] = stackVal_TSVC("Power_04", Power_04);
scaduti[4] = stackVal_TSVC("TempPirom_01", TempPirom_01);
scaduti[5] = stackVal_TSVC("TempPirom_02", TempPirom_02);
scaduti[6] = stackVal_TSVC("TempPirom_03", TempPirom_03);
scaduti[7] = stackVal_TSVC("TempPirom_04", TempPirom_04);
scaduti[8] = stackVal_TSVC("TempCool_01", TempCool_01);
scaduti[9] = stackVal_TSVC("TempCool_02", TempCool_02);
scaduti[10] = stackVal_TSVC("TempCool_03", TempCool_03);
scaduti[11] = stackVal_TSVC("TempCool_04", TempCool_04);
scaduti[12] = stackVal_TSVC("PartStatus_01", PartStatus_01);
scaduti[13] = stackVal_TSVC("PartStatus_02", PartStatus_02);
scaduti[14] = stackVal_TSVC("PartStatus_03", PartStatus_03);
scaduti[15] = stackVal_TSVC("PartStatus_04", PartStatus_04);
// verifico SE devo riportare dati VC
if (baseUtils.CountTrue(scaduti) > 0)
{
Power_01 = getVal_TSVC("Power_01", scaduti[0]);
Power_02 = getVal_TSVC("Power_02", scaduti[1]);
Power_03 = getVal_TSVC("Power_03", scaduti[2]);
Power_04 = getVal_TSVC("Power_04", scaduti[3]);
TempPirom_01 = getVal_TSVC("TempPirom_01", scaduti[4]);
TempPirom_02 = getVal_TSVC("TempPirom_02", scaduti[5]);
TempPirom_03 = getVal_TSVC("TempPirom_03", scaduti[6]);
TempPirom_04 = getVal_TSVC("TempPirom_04", scaduti[7]);
TempCool_01 = getVal_TSVC("TempCool_01", scaduti[8]);
TempCool_02 = getVal_TSVC("TempCool_02", scaduti[9]);
TempCool_03 = getVal_TSVC("TempCool_03", scaduti[10]);
TempCool_04 = getVal_TSVC("TempCool_04", scaduti[11]);
PartStatus_01 = getVal_TSVC_int("PartStatus_01", scaduti[12]);
PartStatus_02 = getVal_TSVC_int("PartStatus_02", scaduti[13]);
PartStatus_03 = getVal_TSVC_int("PartStatus_03", scaduti[14]);
PartStatus_04 = getVal_TSVC_int("PartStatus_04", scaduti[15]);
outVal.Add("DYNDATA", $"Power_01 {Power_01:N2} | TempPirom_01 {TempPirom_01:N2} | TempCool_01 {TempCool_01:N2} | PartStatus_01 {PartStatus_01}");
outVal.Add("Power_01", $"{Power_01:N2}");
outVal.Add("Power_02", $"{Power_02:N2}");
outVal.Add("Power_03", $"{Power_03:N2}");
outVal.Add("Power_04", $"{Power_04:N2}");
outVal.Add("TempPirom_01", $"{TempPirom_01:N2}");
outVal.Add("TempPirom_02", $"{TempPirom_02:N2}");
outVal.Add("TempPirom_03", $"{TempPirom_03:N2}");
outVal.Add("TempPirom_04", $"{TempPirom_04:N2}");
outVal.Add("TempCool_01", $"{TempCool_01:N2}");
outVal.Add("TempCool_02", $"{TempCool_02:N2}");
outVal.Add("TempCool_03", $"{TempCool_03:N2}");
outVal.Add("TempCool_04", $"{TempCool_04:N2}");
outVal.Add("PartStatus_01", $"{PartStatus_01}");
outVal.Add("PartStatus_02", $"{PartStatus_02}");
outVal.Add("PartStatus_03", $"{PartStatus_03}");
outVal.Add("PartStatus_04", $"{PartStatus_04}");
// salvo!
LastTSVC["pressCamFilt"] = Power_01;
LastTSVC["pressLinUt"] = TempPirom_01;
LastTSVC["tempH2O"] = TempCool_01;
}
else
{
outVal.Add("DYNDATA", $"pressCamFilt {LastTSVC["pressCamFilt"]:N6} | pressLinUt {LastTSVC["pressLinUt"]:N6} | tempH2O {LastTSVC["tempH2O"]:N3}");
}
}
else
{
outVal.Add("pressCamFilt", $"{Power_01:N6}");
outVal.Add("pressLinUt", $"{TempPirom_01:N6}");
outVal.Add("tempH2O", $"{TempCool_01:N3}");
outVal.Add("DYNDATA", $"pressCamFilt {Power_01:N3} | pressLinUt {TempPirom_01:N3} | tempH2O {TempCool_01: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>
protected override void decodeToBaseBitmap()
{
// init a zero...
B_input = 0;
/* -----------------------------------------------------
* bitmap MAPO STANDARD
* B0: POWER_ON
* B1: RUN
* B2: pzCount
* B3: allarme
* B4: manuale
* B5: emergenza
*
*
* - BIT di stato
* - DBX2.0: macchina accesa
* - DBX2.1: CICLO AUTO = NON HO ANOMALIE/ALLARMI (0 --> allarme)
* - DBX2.2: contapezzi
* - DBX2.3: MACCHINA IN CICLO AUTO = LAVORA
* - DBX2.4: ERRORE tra part code MES/SAET (blu)
----------------------------------------------------- */
byte mainData = RawInput[2];
int byteSignals = 0;
// bit 0 (poweron) imposto a 1 SE connected...
if (currPLC.IsConnected)
{
byteSignals += (1 << 0);
}
if ((mainData & (1 << 3)) == 1)
{
byteSignals += (1 << 1);
}
// controllo il bit MAIN dello status
if ((mainData & (1 << 1)) == 1)
{
byteSignals += (1 << 3);
}
// considero come MANUALE l'errore part code...
if ((mainData & (1 << 4)) == 0)
{
byteSignals += (1 << 4);
}
// salvo!
B_input = byteSignals;
// processo il watchdog!
counterPlc2Mes = S7.Net.Types.Int.FromByteArray(RawInput.Skip(0).Take(2).ToArray());
// ogni 60 registro...
if (Math.Abs(counterPlc2Mes - counterPlc2MesWrote) > 60)
{
lgInfo($"WatchDog da PLC: {counterPlc2Mes}");
counterPlc2MesWrote = counterPlc2Mes;
}
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[3]} --> B_input: {B_input}"));
}
}
#endregion
}
}