Files
Mapo-IOB-WIN/IOB-WIN-NEXT/IobSiemensComur.cs
T
2021-12-02 11:19:37 +01:00

281 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using MapoSDK;
using System;
using System.Collections.Generic;
namespace IOB_WIN_NEXT
{
/// <summary>
/// Controllo Siemens specifico x impianti COMUR
/// </summary>
public class IobSiemensComur : IobSiemens
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS COMUR
* - basasto su SIEMENS
* - S7 vers 1500
*
* STRUTTURA MEMORIA DB150: 56 byte lettura, di cui 4 byte scrittura (4..7), vedere doc allegato
* G:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\COMUR Dentatrice
*
* Si intende tutto con DB150.DBxx
*
* - parametri processo PLC --> MES
* - DBX0.0 - Macchina On: Segnale pulito di informazione sullo stato della macchina. 0->Aux OFF, 1->Aux ON
* - DBX0.1 Macchina in Allarme: Segnale pulito di macchina in allarme. 0->Nessun Allarme, 1->E presente almeno un allarme/anomalia
* - DBX0.2 Macchina in Ciclo: Segnale pulito sullo stato di funzionamento. 0->La macchina NON sta eseguendo un ciclo automatico, 1->La macchina sta eseguendo un ciclo automatico.
* - DBX0.3 Macchina Non in Produzione: Segnale pulito sullo stato della macchina. 0->Macchina accesa e in lavorazione automatica, 1->Macchina accesa ma NON sta eseguendo un ciclo automatico.
* - DBX0.4 Macchina In Ciclo Continuità: Segnale pulito sullo stato di funzionamento. 1->La macchina sta eseguendo un ciclo automatico con carico/scarico pezzo autonomo, 0->Altrimenti.
* - DBX0.7 Assi In Moto: Segnale pulito sullo stato di movimento Assi. 0->Tutti gli assi della macchina sono fermi, 1->Almeno un asse si sta muovendo.
* - DBX1.0 Impulso Start Ciclo: Impulso a fronte positivo (0->1) della durata di 1’’ che rappresenta levento di Start Ciclo.
* - DBX1.1 Impulso Fine Ciclo: Impulso a fronte positivo (0->1) della durata di 1’’ che rappresenta levento di Fine Ciclo. Attenzione! Questo impulso viene generato solo se il Ciclo Automatico finisce correttamente. Non viene generato nel caso in cui il Ciclo Automatico venga interrotto da allarmi.
* - DBX1.3 Impulso Conta Pezzi: Impulso a fronte positivo (0->1) della durata di 1’’ generato al completamento di ogni programma pezzo.
* - DBX2.0 Preallarmi Pezzi: Segnale pulito di segnalazione Preallarme Pezzi impostabile su CN. 0->Preallarme Disattivo, 1->Preallarme Attivo
* - DBX2.1 Allarme Pezzi: Segnale pulito di segnalazione Allarme Pezzi impostabile su CN. 0->Allarme Disattivo, 1->Allarme Attivo.
* - DBX2.3 Fine Vita Utensile: Segnale pulito di segnalazione Allarme Fine Vita Creatore. 0->Allarme Disattivo, 1->Allarme Attivo.
* - DBX2.7 Ciclo In Attesa: Segnale pulito sullo stato di funzionamento. 1->Ciclo Automatico attivo ma tutti assi fermi, 0->Altrimenti.
*
* - DBD52 - Codice Pezzo In Lavorazione (4byte, REAL)
* - DBD56 - Codice Utensile In Uso (4byte, REAL)
*
*
* - parametri processo MES --> PLC
* - DBX4.0 Reset Contapezzi Parziale: Segnale per resettare il valore del contatore “Contapezzi parziale”. Impostare il bit a 1 per attivare la funzione (il PLC riporterà a 0 il valore quando completa loperazione).
*
* - DB150.DBD8 - Numero di Pezzi da produrre per il lotto (4byte, DInt)
* - DB150.[12.0 .. 31.7] - Codice articolo (stringa da 18 char)
* - DB150.[32.0 .. 51.7] - Codice commessa (stringa da 18 char)
*
*
* - DB111.DBD24: PartCounter INT 2.0 Conteggio Parziale di pezzi prodotti dalla macchina
* -------------------------------------------------------------------------------- */
#region Public Constructors
/// <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 COMUR");
}
#endregion Public Constructors
#region Protected Methods
/// <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: allarme creatore
*
*
* - BIT di stato
* - DBX0.0 - Macchina On: Segnale pulito di informazione sullo stato della macchina. 0->Aux OFF, 1->Aux ON
* - DBX0.1 Macchina in Allarme: Segnale pulito di macchina in allarme. 0->Nessun Allarme, 1->E presente almeno un allarme/anomalia
* - DBX0.2 Macchina in Ciclo: Segnale pulito sullo stato di funzionamento. 0->La macchina NON sta eseguendo un ciclo automatico, 1->La macchina sta eseguendo un ciclo automatico.
* - DBX0.3 Macchina Non in Produzione: Segnale pulito sullo stato della macchina. 0->Macchina accesa e in lavorazione automatica, 1->Macchina accesa ma NON sta eseguendo un ciclo automatico.
* - DBX0.4 Macchina In Ciclo Continuità: Segnale pulito sullo stato di funzionamento. 1->La macchina sta eseguendo un ciclo automatico con carico/scarico pezzo autonomo, 0-> Altrimenti. NON HA SENSO perché NON HANNO il robot...
* - DBX0.7 Assi In Moto: Segnale pulito sullo stato di movimento Assi. 0->Tutti gli assi della macchina sono fermi, 1->Almeno un asse si sta muovendo.
* - DBX1.0 Impulso Start Ciclo: Impulso a fronte positivo (0->1) della durata di 1’’ che rappresenta levento di Start Ciclo.
* - DBX1.1 Impulso Fine Ciclo: Impulso a fronte positivo (0->1) della durata di 1’’ che rappresenta levento di Fine Ciclo. Attenzione! Questo impulso viene generato solo se il Ciclo Automatico finisce correttamente. Non viene generato nel caso in cui il Ciclo Automatico venga interrotto da allarmi.
* - DBX1.3 Impulso Conta Pezzi: Impulso a fronte positivo (0->1) della durata di 1’’ generato al completamento di ogni programma pezzo.
* - DBX2.0 Preallarmi Pezzi: Segnale pulito di segnalazione Preallarme Pezzi impostabile su CN. 0->Preallarme Disattivo, 1->Preallarme Attivo
* - DBX2.1 Allarme Pezzi: Segnale pulito di segnalazione Allarme Pezzi impostabile su CN. 0->Allarme Disattivo, 1->Allarme Attivo.
* - DBX2.3 Fine Vita Utensile: Segnale pulito di segnalazione Allarme Fine Vita Creatore. 0->Allarme Disattivo, 1->Allarme Attivo.
* - DBX2.7 Ciclo In Attesa: Segnale pulito sullo stato di funzionamento. 1->Ciclo Automatico attivo ma tutti assi fermi, 0->Altrimenti.
*
----------------------------------------------------- */
byte mainData = RawInput[0];
int byteSignals = 0;
// bit 0 (poweron) imposto a 1 SE connected...
if (currPLC.IsConnected)
{
byteSignals += (1 << 0);
}
if ((mainData & (1 << 2)) != 0)
{
byteSignals += (1 << 1);
}
// controllo il bit MAIN dello status
if ((mainData & (1 << 1)) != 0)
{
byteSignals += (1 << 3);
}
// considero come MANUALE NON ciclo in continuo...
if ((mainData & (1 << 3)) != 0)
{
byteSignals += (1 << 4);
}
// salvo!
B_input = byteSignals;
// log opzionale!
if (verboseLog)
{
lgInfo($"Trasformazione dati: RawInput:{RawInput[0]} --> B_input: {B_input}");
}
}
#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)
{
// 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 di default
byte[] MemBlock = new byte[1];
string memAddrWrite = "";
if (task2exe != null)
{
// cerco task specifici
foreach (var item in task2exe)
{
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
// init valori
int byteSize = 0;
int valDInt = 0;
short valShort = 0;
// controllo sulla KEY
switch (tName)
{
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setProg:
case taskType.sendWatchDogMes2Plc:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.setArt:
case taskType.setComm:
case taskType.setPzComm:
saveProdData(item);
// 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);
}
else if (currMem.tipoMem == plcDataType.DInt)
{
int.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
}
else if (currMem.tipoMem == plcDataType.Int)
{
short.TryParse(item.Value, out valShort);
MemBlock = S7.Net.Types.Int.ToByteArray(valShort);
}
}
taskVal = item.Value;
break;
case taskType.startSetup:
// resetto IN PRIMIS il contapezzi...
valDInt = 0;
int.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
memAddrWrite = "DB150.DBB24";
S7WriteBB(ref MemBlock, memAddrWrite);
// processo scrittura BIT su DB150.DBX4.0
MemBlock = new byte[1];
MemBlock[0] = (byte)1;
memAddrWrite = "DB150.DBB4";
break;
case taskType.stopSetup:
// resetto IN PRIMIS il contapezzi...
valDInt = 0;
int.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
memAddrWrite = "DB150.DBB24";
S7WriteBB(ref MemBlock, memAddrWrite);
// processo scrittura BIT su DB150.DBX4.0
MemBlock = new byte[1];
MemBlock[0] = (byte)0;
memAddrWrite = "DB150.DBB4";
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;
default:
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
if (!string.IsNullOrEmpty(memAddrWrite))
{
// scrivo!
taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
}
if (!taskOk)
{
lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
}
}
}
return taskDone;
}
#endregion Public Methods
}
}