Files
Mapo-IOB-WIN/IOB-WIN/IobSiemensComur.cs
T
2019-12-04 14:48:13 +01:00

244 lines
11 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
{
/// <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.DBD2: PartCounter INT 2.0 Conteggio Parziale di pezzi prodotti dalla macchina
* -------------------------------------------------------------------------------- */
/// <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");
}
#region Metodi specifici (da verificare/completare in implementazione)
/// <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);
// 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);
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);
}
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.startSetup:
// processo scrittura BIT su DB150.DBX4.0
MemBlock = new byte[1];
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;
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 comunque!
taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
}
if (!taskOk)
{
lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
}
}
}
return taskDone;
}
/// <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
*
*
* - 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.
*
----------------------------------------------------- */
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)) == 1)
{
byteSignals += (1 << 1);
}
// controllo il bit MAIN dello status
if ((mainData & (1 << 1)) == 1)
{
byteSignals += (1 << 3);
}
// considero come MANUALE NON ciclo in continuo...
if ((mainData & (1 << 4)) == 0 || (mainData & (1 << 3)) == 1)
{
byteSignals += (1 << 4);
}
// salvo!
B_input = byteSignals;
// log opzionale!
if (verboseLog)
{
lgInfo($"Trasformazione dati: RawInput:{RawInput[0]} --> B_input: {B_input}");
}
}
#endregion
}
}