1084 lines
35 KiB
C#
1084 lines
35 KiB
C#
using IOB_UT;
|
|
using S7.Net;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Net.NetworkInformation;
|
|
|
|
namespace IOB_WIN
|
|
{
|
|
public class IobSiemensTorri : IobSiemens
|
|
{
|
|
/* --------------------------------------------------------------------------------
|
|
* Controlli SIEMENS TORRI
|
|
* - basasto su SIEMENS
|
|
* - S7 vers 1200
|
|
*
|
|
* -------------------------------------------------------------------------------- */
|
|
|
|
#region area componenti base
|
|
|
|
/// <summary>
|
|
/// Configurazione valori da LEGGERE dal PLC
|
|
/// </summary>
|
|
public otherData[] memMapR;
|
|
/// <summary>
|
|
/// Configurazione valori da SCRIVERE nel PLC
|
|
/// </summary>
|
|
public otherData[] memMapW;
|
|
/// <summary>
|
|
/// Byte dimensione buffer dati memoria (da file map)
|
|
/// </summary>
|
|
public int numByte = 0;
|
|
/// <summary>
|
|
/// Lungh massima stringhe
|
|
/// </summary>
|
|
protected int maxStrChar = 20;
|
|
/// <summary>
|
|
/// Oggetto PLC da ri-utilizzare...
|
|
/// </summary>
|
|
protected Plc currPLC;
|
|
/// <summary>
|
|
/// Oggetto cronometro x test vari...
|
|
/// </summary>
|
|
protected Stopwatch sw = new Stopwatch();
|
|
/// <summary>
|
|
/// parametri di connessione
|
|
/// </summary>
|
|
protected connParamS7 parametri;
|
|
/// <summary>
|
|
/// Variabile x salvataggio iobConf locale
|
|
/// </summary>
|
|
protected IobConfiguration _IOBConf;
|
|
|
|
#endregion
|
|
|
|
#region area metodi lettura/Scrittura
|
|
|
|
|
|
/// <summary>
|
|
/// wrapper chiamata LETTURA in blocco MULTI BYTE...
|
|
/// </summary>
|
|
/// <param name="MATRICE valori letti"></param>
|
|
/// <returns></returns>
|
|
public bool S7ReadBB(ref byte[] Value)
|
|
{
|
|
bool answ = false;
|
|
sw.Restart();
|
|
parentForm.commPlcActive = true;
|
|
if (testCncConn())
|
|
{
|
|
// decodifico memoria...
|
|
memAreaSiemens memoria = new memAreaSiemens(parametri.memAddrRead);
|
|
int numByte = parametri.memSizeRead;
|
|
Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
|
|
// copio in value, sennò do errore...
|
|
if (memByteRead.Length == Value.Length)
|
|
{
|
|
Value = memByteRead;
|
|
}
|
|
else
|
|
{
|
|
lgError(string.Format("Mismatch dimensione array memoria: passato array di {0} byte, letti da S7 {1} byte", Value.Length, memByteRead.Length));
|
|
}
|
|
string titolo = string.Format("READ BLOCK MEM BYTE: {0} --> {1} byte", parametri.memAddrRead, numByte);
|
|
if (verboseLog)
|
|
{
|
|
lgInfo(titolo);
|
|
}
|
|
|
|
string contenuto = string.Format("Contenuto area memoria aquisita{0}", Environment.NewLine);
|
|
string byteVal = "";
|
|
for (int i = 0; i < memByteRead.Length; i++)
|
|
{
|
|
byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0');
|
|
contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine);
|
|
}
|
|
// loggo lettura...
|
|
if (verboseLog)
|
|
{
|
|
lgInfo(contenuto);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
connectionOk = false;
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
sw.Stop();
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(cIobConf.codIOB, string.Format("{0}|{1}", parametri.memAddrRead, numByte), sw.ElapsedTicks);
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata SCRITTURA in blocco MULTI BYTE...
|
|
/// </summary>
|
|
/// <param name="MATRICE valori scritti"></param>
|
|
/// <returns></returns>
|
|
public bool S7WriteBB(ref byte[] Value)
|
|
{
|
|
bool answ = false;
|
|
|
|
#if false
|
|
sw.Restart();
|
|
if (testCncConn())
|
|
{
|
|
// decodifico memoria...
|
|
memAddress memoria = new memAddress(txtMemArea.Text);
|
|
int numByte = 1;
|
|
int.TryParse(txtMemSize.Text, out numByte);
|
|
Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
|
|
titolo = string.Format("READ BLOCK MEM BYTE: {0} --> {1} byte", txtMemArea.Text, numByte);
|
|
contenuto = "";
|
|
string byteVal = "";
|
|
for (int i = 0; i < memByteRead.Length; i++)
|
|
{
|
|
byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0');
|
|
contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine);
|
|
}
|
|
showOut(titolo, contenuto);
|
|
}
|
|
sw.Stop();
|
|
tslRTime.Text = string.Format("{0}", sw.Elapsed);
|
|
#endif
|
|
|
|
|
|
#if false
|
|
if (FANUC_ref.Connected)
|
|
{
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
#endif
|
|
return answ;
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// estende l'init della classe base con i metodi x Siemens specifici x Torri
|
|
/// </summary>
|
|
/// <param name="caller"></param>
|
|
/// <param name="adpConf"></param>
|
|
public IobSiemensTorri(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
|
{
|
|
// gestione invio ritardato contapezzi
|
|
pzCountDelay = utils.CRI("pzCountDelay");
|
|
lastPzCountSend = DateTime.Now;
|
|
lastWarnODL = DateTime.Now;
|
|
// init conf
|
|
_IOBConf = IOBConf;
|
|
// inizializzo parametri...
|
|
parametri = new connParamS7()
|
|
{
|
|
ipAdrr = "127.0.0.1",
|
|
tipoCpu = CpuType.S7200,
|
|
slot = 0,
|
|
rack = 0,
|
|
pingMsTimeout = IOBConf.pingMsTimeout,
|
|
memAddrRead = "DB700.DBB0",
|
|
memAddrWrite = "DB701.DBB0",
|
|
memSizeRead = 0,
|
|
memSizeWrite = 0
|
|
};
|
|
setParamPlc();
|
|
}
|
|
/// <summary>
|
|
/// Test connessione CNC
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool testCncConn()
|
|
{
|
|
bool answ = false;
|
|
IPStatus pingStatus = testPing();
|
|
// se passa il ping faccio il resto...
|
|
if (pingStatus != IPStatus.Success)
|
|
{
|
|
lgError(string.Format("Errore in testCncConn: reply Status per {0}: {1}", parametri.ipAdrr, pingStatus));
|
|
}
|
|
else
|
|
{
|
|
if (!currPLC.IsConnected)
|
|
{
|
|
currPLC.Open();
|
|
}
|
|
|
|
if (!currPLC.IsAvailable)
|
|
{
|
|
lgError(string.Format("PLC Siemens NON disponibile:{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString));
|
|
currPLC.ClearLastError();
|
|
}
|
|
else
|
|
{
|
|
if (!currPLC.IsConnected)
|
|
{
|
|
lgError(string.Format("PLC Siemens NON connesso:{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString));
|
|
currPLC.ClearLastError();
|
|
parentForm.updateComStats("NO connection");
|
|
}
|
|
else
|
|
{
|
|
parentForm.updateComStats("Connection OK");
|
|
answ = true;
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Imposto parametri PLC
|
|
/// </summary>
|
|
private void setParamPlc()
|
|
{
|
|
// Creo oggetto connessione NC
|
|
parentForm.commPlcActive = true;
|
|
lgInfo("Start init Adapter SIEMENS TORRI all'IP {0} | CPU: {1} | R/S: {2}/{3} | --> IOB {4}", _IOBConf.cncIpAddr, _IOBConf.cpuType, _IOBConf.rack, _IOBConf.slot, _IOBConf.codIOB);
|
|
// SE è necessario refresh...
|
|
if (needRefresh)
|
|
{
|
|
lgInfo("Refreshing connection...");
|
|
try
|
|
{
|
|
parametri.slot = _IOBConf.slot;
|
|
parametri.rack = _IOBConf.rack;
|
|
parametri.tipoCpu = (CpuType)Enum.Parse(typeof(CpuType), _IOBConf.cpuType);
|
|
parametri.ipAdrr = _IOBConf.cncIpAddr;
|
|
// leggo file init...
|
|
IniFile fIni = new IniFile(_IOBConf.iniFileName);
|
|
// ora leggo valori speciali
|
|
parametri.memAddrRead = fIni.ReadString("MEMORY", "ADDR_READ", "");
|
|
parametri.memAddrWrite = fIni.ReadString("MEMORY", "ADDR_WRITE", "");
|
|
parametri.memSizeRead = fIni.ReadInteger("MEMORY", "SIZE_READ", 0);
|
|
parametri.memSizeWrite = fIni.ReadInteger("MEMORY", "SIZE_WRITE", 0);
|
|
// salvo vettori memoria...
|
|
RawInput = new byte[parametri.memSizeRead];
|
|
RawOutput = new byte[parametri.memSizeWrite];
|
|
// salvo parametri conn!
|
|
lgInfo(string.Format("Parametri memoria: memAddrRead: {0} | memAddrWrite: {1} | memSizeRead: {2} | memSizeWrite: {3}", parametri.memAddrRead, parametri.memAddrWrite, parametri.memSizeRead, parametri.memSizeWrite));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in parse parametri da IOBConf");
|
|
}
|
|
// ora tento avvio PLC... SE PING OK...
|
|
if (testPing() == IPStatus.Success)
|
|
{
|
|
try
|
|
{
|
|
currPLC = new Plc(parametri.tipoCpu, parametri.ipAdrr, parametri.rack, parametri.slot);
|
|
// disconnetto e connetto...
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("SIEMENS-TORRI: tryDisconnect");
|
|
}
|
|
|
|
tryDisconnect();
|
|
lgInfo("SIEMENS-TORRI: tryConnect");
|
|
tryConnect();
|
|
lgInfo("End init Adapter SIEMENS-TORRI");
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("S7+ CONNESSIONE AVVENUTA");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in INIT PLC S7+");
|
|
}
|
|
needRefresh = false;
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
// carico conf vettore memoria...
|
|
loadMemConf();
|
|
if (utils.CRB("enableContapezzi"))
|
|
{
|
|
lgInfo("TORRI-SIEMENS: inizio gestione contapezzi");
|
|
try
|
|
{
|
|
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
|
|
if (cIobConf.optPar.Count > 0 && cIobConf.optPar["PZCOUNT_MODE"] != "")
|
|
{
|
|
if (cIobConf.optPar["PZCOUNT_MODE"].StartsWith("STD"))
|
|
{
|
|
pzCntReload(true);
|
|
// refresh associazione Macchina - IOB
|
|
sendM2IOB();
|
|
// per adesso imposto lettura fanuc == contapezzi (poi farà vera lettura...)
|
|
lastCountCNC = contapezzi;
|
|
}
|
|
else
|
|
{
|
|
contapezzi = 0;
|
|
lgInfo("Contapezzi STD disabilitato: modalità {0}", cIobConf.optPar["PZCOUNT_MODE"]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
contapezzi = 0;
|
|
lgInfo("Parametro mancante PZCOUNT_MODE");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in contapezzi TORRI-SIEMENS");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Override disconnessione
|
|
/// </summary>
|
|
public override void tryDisconnect()
|
|
{
|
|
if (connectionOk)
|
|
{
|
|
string szStatusConnection = "";
|
|
try
|
|
{
|
|
currPLC.Close();
|
|
connectionOk = false;
|
|
lgInfo(szStatusConnection);
|
|
lgInfo("Effettuata disconnessione adapter SIEMENS-TORRI!");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgFatal(exc, "Errore nella disconnessione dall'adapter SIEMENS-TORRI");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgError("IMPOSSIBILE effettuare disconnessione SIEMENS-TORRI: Connessione non disponibile...");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Override connessione
|
|
/// </summary>
|
|
public override void tryConnect()
|
|
{
|
|
bool doLog = (verboseLog || periodicLog);
|
|
if (!connectionOk)
|
|
{
|
|
// reimporto parametri PLC se necessario...
|
|
setParamPlc();
|
|
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
|
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
|
{
|
|
if (doLog)
|
|
{
|
|
lgInfo("SIEMENS-TORRI: ConnKO - tryConnect");
|
|
}
|
|
// in primis salvo data ping...
|
|
lastPING = DateTime.Now;
|
|
// se passa il ping faccio il resto...
|
|
if (testPing() == IPStatus.Success)
|
|
{
|
|
string szStatusConnection = "";
|
|
try
|
|
{
|
|
// ora provo connessione...
|
|
parentForm.commPlcActive = true;
|
|
currPLC.Open();
|
|
parentForm.commPlcActive = false;
|
|
lgInfo("szStatusConnection: " + szStatusConnection);
|
|
connectionOk = true;
|
|
// refresh stato allarmi!!!
|
|
if (connectionOk)
|
|
{
|
|
if (adpRunning)
|
|
{
|
|
// carico status allarmi (completo)
|
|
lgInfo("Inizio refresh completo stato allarmi...");
|
|
forceAlarmCheck();
|
|
lgInfo("Completato refresh completo stato allarmi!");
|
|
}
|
|
else
|
|
{
|
|
lgInfo("Connessione OK");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgError("Impossibile procedere, connessione mancante...");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgFatal(string.Format("Errore nella connessione all'adapter SIEMENS-TORRI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
lgInfo(string.Format("Eccezione in TryConnect, Adapter SIEMENS-TORRI NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// loggo no risposta ping ...
|
|
connectionOk = false;
|
|
if (doLog)
|
|
{
|
|
lgInfo(string.Format("Attenzione: SIEMENS-TORRI controllo PING fallito per IP {0}", cIobConf.cncIpAddr));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// se non è ancora connesso faccio procesisng memoria caso disconnesso...
|
|
if (!connectionOk)
|
|
{
|
|
// processo semafori ed invio...
|
|
processMemoryDiscon();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Caricamento conf memoria DB del SIEMENS
|
|
/// </summary>
|
|
private void loadMemConf()
|
|
{
|
|
// carico conf memoria
|
|
loadConfFile(ref memMapR, filePath("MMapR"), 1, ref numByte);
|
|
loadConfFile(ref memMapW, filePath("MMapW"), 1, ref numByte);
|
|
}
|
|
/// <summary>
|
|
/// Restituisce path completo file da chaive configurazione
|
|
/// </summary>
|
|
/// <param name="keyFile">chaive conf x file richiesto</param>
|
|
/// <returns></returns>
|
|
protected string filePath(string keyFile)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Eccezione in recupero filePath");
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua vero processing contapezzi
|
|
/// </summary>
|
|
public override void processContapezzi()
|
|
{
|
|
if (utils.CRB("enableContapezzi"))
|
|
{
|
|
try
|
|
{
|
|
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
|
|
if (cIobConf.optPar.Count > 0 && cIobConf.optPar["PZCOUNT_MODE"] != "")
|
|
{
|
|
string memAddr = cIobConf.optPar["PZCOUNT_MODE"];
|
|
if (memAddr.StartsWith("STD"))
|
|
{
|
|
// inizio verifica area memoria/parametro levando prima parte codice
|
|
memAddr = memAddr.Replace("STD.", "");
|
|
object outputVal = new object();
|
|
// verifico se si tratta di lettura area DB... formato tipo STD.DB700.DBB22.W
|
|
if (memAddr.StartsWith("DB"))
|
|
{
|
|
memAreaSiemens areaCounter = new memAreaSiemens(memAddr);
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("[0] area memoria: {1}.{2}.{3}", memAddr, areaCounter.DbNum, areaCounter.indiceMem, areaCounter.tipoMem);
|
|
}
|
|
// copio da blocco già letto... con switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
|
|
switch (areaCounter.tipoMem)
|
|
{
|
|
case "B":
|
|
byte valB = RawInput[areaCounter.indiceMem];
|
|
outputVal = valB;
|
|
break;
|
|
case "W":
|
|
ushort valW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(2).ToArray());
|
|
outputVal = valW;
|
|
break;
|
|
case "DW":
|
|
uint valDW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(4).ToArray());
|
|
outputVal = valDW;
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("[2] outputVal contapezzi: {0}", outputVal);
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// salvo...
|
|
Int32.TryParse(outputVal.ToString(), out lastCountCNC);
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("[3] lastCountCNC contapezzi: {0}", lastCountCNC);
|
|
}
|
|
}
|
|
stopwatch.Stop();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in contapezzi SIEMENS-TORRI");
|
|
}
|
|
}
|
|
}
|
|
|
|
#region da completare
|
|
|
|
/// <summary>
|
|
/// Recupero dati override in formato dictionary
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override Dictionary<string, string> getOverrides()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
uint valDW = 0;
|
|
// !!!FARE!!! recuperare da conf memoria, ora HARD CODED
|
|
outVal.Add("FEED_OVER", RawInput[19].ToString());
|
|
outVal.Add("RAPID_OVER", RawInput[20].ToString());
|
|
outVal.Add("CURR_MODE", decodeCurrMode(RawInput[21]));
|
|
// recupero RPM pezzo/mola !!!FARE!!! cambio nome da config, qui sono 01:conduttrice e 02:operatrice (3013), mentre sono pezzo/mola nella V100
|
|
valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(24).Take(4).ToArray());
|
|
outVal.Add("RPM_01", valDW.ToString());
|
|
valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(28).Take(4).ToArray());
|
|
outVal.Add("RPM_02", valDW.ToString());
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// lettura bit semafori
|
|
/// </summary>
|
|
public override void readSemafori()
|
|
{
|
|
base.readSemafori();
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("inizio read semafori");
|
|
}
|
|
|
|
parentForm.sIN = Semaforo.SV;
|
|
// leggo TUTTI i byte configurati...
|
|
byte[] MemBlock = new byte[parametri.memSizeRead];
|
|
bool fatto = S7ReadBB(ref MemBlock);
|
|
Buffer.BlockCopy(MemBlock, 0, RawInput, 0, parametri.memSizeRead);
|
|
if (verboseLog)
|
|
{
|
|
lgInfo(string.Format("RawInput[0]: {0}", utils.binaryForm(RawInput[0])));
|
|
}
|
|
// salvo il solo BYTE dell'input decifrando il semaforo...
|
|
decodeToBaseBitmap();
|
|
decodeOtherData();
|
|
}
|
|
|
|
/// <summary>
|
|
/// decodifica da bitmap il CURRENT MODE del controllo
|
|
/// </summary>
|
|
/// <param name="currModeBitmap"></param>
|
|
/// <returns></returns>
|
|
protected string decodeCurrMode(byte currModeBitmap)
|
|
{
|
|
string answ = "";
|
|
if (verboseLog)
|
|
{
|
|
lgInfo(string.Format("CURR_MODE raw data: {0}", utils.binaryForm(currModeBitmap)));
|
|
}
|
|
// decodifica del MODO... B21
|
|
/*
|
|
* CURR MODE diviso in BIT:
|
|
* B0 (01) = AUTO
|
|
* B1 (02) = MDI
|
|
* B2 (04) = JOG
|
|
* B3 (08) = TeachIN (associato a MDI --> 10)
|
|
* B4 (16) = Repos (associato a JOG --> 20)
|
|
* B5 (32) = RefPoint (associato a Jog --> 36)
|
|
* B6 (64) = Incr1 (associato a Jog --> 68)
|
|
* B7 (128) = Incr10 (associato a Jog --> -124 / 132 se UInt)
|
|
* */
|
|
|
|
// modi principali
|
|
if (currModeBitmap.SelectBit(0))
|
|
{
|
|
answ = "AUTO";
|
|
}
|
|
else if (currModeBitmap.SelectBit(1))
|
|
{
|
|
answ = "MDI";
|
|
}
|
|
else if (currModeBitmap.SelectBit(2))
|
|
{
|
|
answ = "JOG";
|
|
}
|
|
// modi accessori
|
|
if (currModeBitmap.SelectBit(3))
|
|
{
|
|
answ += " | TEACH-IN";
|
|
}
|
|
if (currModeBitmap.SelectBit(4))
|
|
{
|
|
answ += " | REPOS";
|
|
}
|
|
if (currModeBitmap.SelectBit(5))
|
|
{
|
|
answ += " | REF-POINT";
|
|
}
|
|
if (currModeBitmap.SelectBit(6))
|
|
{
|
|
answ += " | INCR-1";
|
|
}
|
|
if (currModeBitmap.SelectBit(7))
|
|
{
|
|
answ += " | INCR-10";
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Decodifica il resto dell'area TORRI x i dati accessori (allarmi, ...)
|
|
/// </summary>
|
|
private void decodeOtherData()
|
|
{
|
|
if (verboseLog)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
|
/// </summary>
|
|
private void decodeToBaseBitmap()
|
|
{
|
|
// init a zero...
|
|
B_input = 0;
|
|
// TORRI: leggo i primi 8 bit hard coded...
|
|
int byteSem = RawInput[0];
|
|
// azzero i bit NON gestiti (2-5-6-7)
|
|
byteSem &= ~(1 << 2);
|
|
byteSem &= ~(1 << 5);
|
|
byteSem &= ~(1 << 6);
|
|
byteSem &= ~(1 << 7);
|
|
// salvo infine variabile bit x invio
|
|
B_input = byteSem;
|
|
|
|
|
|
string currODL = "";
|
|
try
|
|
{
|
|
currODL = utils.callUrl(urlGetCurrODL);
|
|
// solo SE HO un ODL...
|
|
if (currODL == "" || currODL == "0")
|
|
{
|
|
if (periodicLog)
|
|
{
|
|
lgInfo(string.Format("SiemensTorri | Lettura ODL andata a vuoto: currODL: {0}", currODL));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// se variato o scaduto timeout log...
|
|
if (periodicLog || (currIdxODL.ToString() != currODL))
|
|
{
|
|
lgInfo(string.Format("SiemensTorri | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL));
|
|
}
|
|
// provo a salvare nuovo ODL
|
|
int.TryParse(currODL, out currIdxODL);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15)
|
|
{
|
|
lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL);
|
|
lastWarnODL = DateTime.Now;
|
|
}
|
|
}
|
|
if (currODL != null && currODL != "" && currODL != "0")
|
|
{
|
|
// ora processo il contapezzi...
|
|
// controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture
|
|
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
|
|
{
|
|
|
|
// se sono differenti MOSTRO...
|
|
if (lastCountCNC != contapezzi)
|
|
{
|
|
// registro contapezzi
|
|
lgInfo(string.Format("Differenza Contapezzi: READ: {0} | Interno {1}", lastCountCNC, contapezzi));
|
|
}
|
|
// verifico se variato contapezzi... e se passato ritardo minimo...
|
|
if (lastCountCNC > contapezzi)
|
|
{
|
|
// salvo nuovo contapezzi (incremento di 1...)
|
|
contapezzi++;
|
|
// salvo in semaforo!
|
|
B_input += 1 << 2;
|
|
// registro contapezzi
|
|
lgInfo(string.Format("Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
|
|
}
|
|
|
|
// invio a server contapezzi (aggiornato)
|
|
string retVal = utils.callUrl(urlSetPzCount + contapezzi.ToString());
|
|
// verifica se tutto OK
|
|
if (retVal != "OK")
|
|
{
|
|
// errore salvataggio contapezzi
|
|
lgInfo(string.Format("Errore salvataggio Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1} | Errore salvataggio: {2}", lastCountCNC, contapezzi, retVal));
|
|
}
|
|
// resetto timer...
|
|
lastPzCountSend = DateTime.Now;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
|
|
{
|
|
lgInfo(string.Format("Attenzione: mancanza ODL non procedo con gestione contapezzi. Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
|
|
// resetto timer...
|
|
lastPzCountSend = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
// log opzionale!
|
|
if (verboseLog)
|
|
{
|
|
lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Recupero programma in lavorazione
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string getPrgName()
|
|
{
|
|
string prgName = "";
|
|
#if false
|
|
// recupero NUOVO prgName...
|
|
try
|
|
{
|
|
// recupero nome programma MAIN
|
|
prgName = utils.purgedChar2String(FANUC_ref.getPrgNameMain());
|
|
// trimmo path del programma, ovvero "CNCMEMUSERPATH1"
|
|
prgName = prgName.Replace(utils.CRS("basePrgMemPath"), "");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
#endif
|
|
return prgName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero programma in lavorazione come Dictionary FANUC...
|
|
/// - SYSINFO: (prima KEY globale) TUTTI i valori separati da # (x fare check modifica)
|
|
/// - altre stringhe: ogni singolo parametro / valore
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override Dictionary<string, string> getSysInfo()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
#if false
|
|
inizio = DateTime.Now;
|
|
EgwProxy.MultiCncLib.Focas1.ODBSYS answ = FANUC_ref.getSysInfo();
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("SYS-INFO"), DateTime.Now.Subtract(inizio).Ticks);
|
|
try
|
|
{
|
|
string cnc_type = new string(answ.cnc_type);
|
|
string mt_type = new string(answ.mt_type);
|
|
string series = new string(answ.series);
|
|
string version = new string(answ.version);
|
|
string axes = new string(answ.axes);
|
|
//short addInfo = answ.addinfo;
|
|
short max_axis = answ.max_axis;
|
|
// preparo i singoli valori dell'array...
|
|
outVal.Add("SYSINFO", string.Format("{0}#{1}#{2}#{3}#{4}#{5}", cnc_type, mt_type, series, version, axes, max_axis));
|
|
outVal.Add("CNC", cnc_type);
|
|
outVal.Add("MTT", mt_type);
|
|
outVal.Add("SER", series);
|
|
outVal.Add("VER", version);
|
|
outVal.Add("AXS", string.Format("{0}|{1}", axes, max_axis));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in getSysInfo");
|
|
}
|
|
#endif
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Esegue processing MODE (e nel contempo recupera altri dati dell'area G)
|
|
/// </summary>
|
|
public override void processMode()
|
|
{
|
|
if (utils.CRB("enableMode"))
|
|
{
|
|
#if false
|
|
try
|
|
{
|
|
inizio = DateTime.Now;
|
|
// leggo tutto da 0 a 43...
|
|
int memIndex = 0;
|
|
FanucMemRW(R, FANUC.MemType.G, memIndex, ref MemBlockG);
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-G-AREA", MemBlockG.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
// verifico modo con valore corrente, se cambia aggiorno...
|
|
CNC_MODE newMode = decodeG43(MemBlockG[43]);
|
|
if (newMode != currMode)
|
|
{
|
|
// aggiorno!
|
|
currMode = newMode;
|
|
// conversione NUM MODE in descrizione da ENUM
|
|
string descrMode = Enum.GetName(typeof(CNC_MODE), currMode);
|
|
// accodo x invio
|
|
string sVal = string.Format("[CNC_MODE]{0}", descrMode);
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog("CNC_MODE", descrMode));
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in process Mode G43");
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#if false
|
|
/// <summary>
|
|
/// decodifica il modo dai valori del byte G43
|
|
/// </summary>
|
|
/// <param name="currVal"></param>
|
|
/// <returns></returns>
|
|
protected CNC_MODE decodeG43(byte currVal)
|
|
{
|
|
// hard coded da valori tabellari a MODI definiti in CNC_MODE...
|
|
CNC_MODE answ = CNC_MODE.ND;
|
|
switch (currVal)
|
|
{
|
|
case 0:
|
|
answ = CNC_MODE.MDI;
|
|
break;
|
|
case 1:
|
|
answ = CNC_MODE.MEN;
|
|
break;
|
|
case 3:
|
|
answ = CNC_MODE.EDIT;
|
|
break;
|
|
case 4:
|
|
answ = CNC_MODE.HANDLE_INC;
|
|
break;
|
|
case 5:
|
|
answ = CNC_MODE.JOG;
|
|
break;
|
|
case 6:
|
|
answ = CNC_MODE.TJOG;
|
|
break;
|
|
case 7:
|
|
answ = CNC_MODE.THND;
|
|
break;
|
|
case 33:
|
|
answ = CNC_MODE.RMT;
|
|
break;
|
|
case 133:
|
|
answ = CNC_MODE.REF;
|
|
break;
|
|
default:
|
|
answ = CNC_MODE.ND;
|
|
break;
|
|
}
|
|
return answ;
|
|
}
|
|
#endif
|
|
/// <summary>
|
|
/// Recupero dati dinamici...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getDynData()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
#if false
|
|
inizio = DateTime.Now;
|
|
EgwProxy.MultiCncLib.Focas1.ODBDY2_1 answ = FANUC_ref.getAllDynData();
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("PROC-DYN-DATA"), DateTime.Now.Subtract(inizio).Ticks);
|
|
try
|
|
{
|
|
string actf = answ.actf.ToString();
|
|
string acts = answ.acts.ToString();
|
|
//string numAlarm = answ.alarm.ToString();
|
|
// preparo i singoli valori dell'array...
|
|
//outVal.Add("DYNDATA", string.Format("{0}#{1}#{2}", actf, acts, numAlarm));
|
|
outVal.Add("DYNDATA", string.Format("FEED {0}#SPEED_RPM {1}", actf, acts));
|
|
if (utils.CRB("SendFeedSpeed"))
|
|
{
|
|
outVal.Add("FEED", actf);
|
|
outVal.Add("SPEED_RPM", acts);
|
|
//outVal.Add("NUM_ALARM", numAlarm);
|
|
}
|
|
if (utils.CRB("SendAxPos"))
|
|
{
|
|
// salvo le posizioni...
|
|
EgwProxy.MultiCncLib.Focas1.FAXIS posAx = answ.pos;
|
|
int[] currPosAbs = posAx.absolute;
|
|
int i = 0;
|
|
foreach (var item in currPosAbs)
|
|
{
|
|
i++;
|
|
outVal.Add(string.Format("POS_{0:00}", i), item.ToString());
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in getDynData");
|
|
}
|
|
#endif
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override salvataggio valori in memoria...
|
|
/// </summary>
|
|
/// <param name="tipo">tipo di DUMP</param>
|
|
public override void saveMemDump(dumpType tipo)
|
|
{
|
|
#if false
|
|
dump_MemAreaD();
|
|
dump_MemAreaY();
|
|
#endif
|
|
}
|
|
/// <summary>
|
|
/// Dump PERIODICO area D della memoria
|
|
/// </summary>
|
|
/// <param name="memIndex">area memoria di partenza</param>
|
|
/// <param name="memSyzeByte"></param>
|
|
private void dump_MemAreaD(int memIndex, int memSyzeByte)
|
|
{
|
|
// leggo TUTTI i 9999 byte della memoria D...
|
|
byte[] MemBlockD = new byte[memSyzeByte];
|
|
stopwatch.Restart();
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("START MemDump AreaD");
|
|
}
|
|
#if false
|
|
FanucMemRW(R, FANUC.MemType.D, memIndex, ref MemBlockD);
|
|
if (verboseLog) lgInfo("END MemDump AreaD");
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpD", MemBlockD.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
// file out!
|
|
string nomeFile = "";
|
|
Dictionary<string, string> mappaValori = new Dictionary<string, string>();
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
nomeFile = string.Format(@"{0}\SAMPLES\MemDump_D_DW_{1:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, DateTime.Now);
|
|
for (int i = 0; i < MemBlockD.Length / 4; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockD, i * 4).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
#endif
|
|
}
|
|
/// <summary>
|
|
/// Dump area D della memoria
|
|
/// </summary>
|
|
private void dump_MemAreaD()
|
|
{
|
|
// faccio chaimate e salvo in file dump...
|
|
int memIndex = 0;
|
|
// leggo TUTTI i 9999 byte della memoria D...
|
|
byte[] MemBlockD = new byte[9999];
|
|
stopwatch.Restart();
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("START MemDump AreaD");
|
|
}
|
|
#if false
|
|
FanucMemRW(R, FANUC.MemType.D, memIndex, ref MemBlockD);
|
|
if (verboseLog) lgInfo("END MemDump AreaD");
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpD", MemBlockD.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
//
|
|
string nomeFile = "";
|
|
// salvo in file i dati letti come BYTE
|
|
nomeFile = string.Format(@"{0}\MemDump_D_Byte.dat", utils.dataDatDir);
|
|
Dictionary<string, string> mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockD.Length; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), MemBlockD[i].ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
nomeFile = string.Format(@"{0}\MemDump_D_DW.dat", utils.dataDatDir);
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockD.Length / 4; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockD, i * 4).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
nomeFile = string.Format(@"{0}\MemDump_D_W.dat", utils.dataDatDir);
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockD.Length / 2; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt16(MemBlockD, i * 2).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
#endif
|
|
}
|
|
/// <summary>
|
|
/// Dump area Y della memoria
|
|
/// </summary>
|
|
private void dump_MemAreaY()
|
|
{
|
|
// faccio chaimate e salvo in file dump...
|
|
int memIndex = 0;
|
|
// leggo TUTTI i 9999 byte della memoria Y...
|
|
byte[] MemBlockY = new byte[10];
|
|
stopwatch.Restart();
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("START MemDump AreaY");
|
|
}
|
|
#if false
|
|
FanucMemRW(R, FANUC.MemType.Y, memIndex, ref MemBlockY);
|
|
if (verboseLog) lgInfo("END MemDump AreaY");
|
|
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpY", MemBlockY.Length), DateTime.Now.Subtract(inizio).Ticks);
|
|
//
|
|
string nomeFile = "";
|
|
// salvo in file i dati letti come BYTE
|
|
nomeFile = string.Format(@"{0}\MemDump_Y_Byte.dat", utils.dataDatDir);
|
|
Dictionary<string, string> mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockY.Length; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), MemBlockY[i].ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
nomeFile = string.Format(@"{0}\MemDump_Y_DW.dat", utils.dataDatDir);
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockY.Length / 4; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockY, i * 4).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
nomeFile = string.Format(@"{0}\MemDump_Y_W.dat", utils.dataDatDir);
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockY.Length / 2; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt16(MemBlockY, i * 2).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
#endif
|
|
}
|
|
#endregion
|
|
}
|
|
}
|