1132 lines
45 KiB
C#
1132 lines
45 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using SCMCncLib;
|
||
using System.Windows.Forms;
|
||
using System.Threading;
|
||
using System.IO;
|
||
using System.Collections.Generic;
|
||
|
||
namespace MTC_Adapter
|
||
{
|
||
public class AdapterESA : AdapterGeneric
|
||
{
|
||
#if false
|
||
// vettore valori in file interscambio
|
||
public Dictionary<string, string> generalStatus;
|
||
#endif
|
||
/// <summary>
|
||
/// Configurazione valori da leggere IOT_Byte
|
||
/// </summary>
|
||
public otherData[] mapIOT_Byte;
|
||
/// <summary>
|
||
/// Configurazione valori da leggere IOT_Word
|
||
/// </summary>
|
||
public otherData[] mapIOT_Word;
|
||
/// <summary>
|
||
/// Configurazione valori da leggere IOT_DWord
|
||
/// </summary>
|
||
public otherData[] mapIOT_DWord;
|
||
/// <summary>
|
||
/// Configurazione valori da leggere IOT_String
|
||
/// </summary>
|
||
public otherData[] mapIOT_String;
|
||
/// <summary>
|
||
/// variabile globale x usare IOT MEMORY (!!! da eliminare alla fine dei test)
|
||
/// </summary>
|
||
protected bool useIotMem = true;
|
||
|
||
/// <summary>
|
||
/// Carico file conf dati IOT
|
||
/// </summary>
|
||
protected override void loadOtherFile()
|
||
{
|
||
base.loadOtherFile();
|
||
loadByteListMap();
|
||
loadWordListMap();
|
||
loadDWordListMap();
|
||
loadStringListMap();
|
||
}
|
||
/// <summary>
|
||
/// Carico conf vettore dati STRING
|
||
/// </summary>
|
||
private void loadStringListMap()
|
||
{
|
||
loadConfFile(ref mapIOT_String, filePath("IOTStringFilePath"), 1);
|
||
}
|
||
/// <summary>
|
||
/// Carico conf vettore dati DWORD
|
||
/// </summary>
|
||
private void loadDWordListMap()
|
||
{
|
||
loadConfFile(ref mapIOT_DWord, filePath("IOTDWordFilePath"), 1);
|
||
}
|
||
/// <summary>
|
||
/// Carico conf vettore dati WORD
|
||
/// </summary>
|
||
private void loadWordListMap()
|
||
{
|
||
loadConfFile(ref mapIOT_Word, filePath("IOTWordFilePath"), 1);
|
||
}
|
||
/// <summary>
|
||
/// Carico conf vettore dati BYTE
|
||
/// </summary>
|
||
private void loadByteListMap()
|
||
{
|
||
loadConfFile(ref mapIOT_Byte, filePath("IOTByteFilePath"), 1);
|
||
}
|
||
/// <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)
|
||
{
|
||
return string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile));
|
||
}
|
||
/// <summary>
|
||
/// Legge il file di conf di una MAP di informazioni da gestire con lettura set memoria
|
||
/// </summary>
|
||
/// <param name="vettoreConf">nome vettore memoria</param>
|
||
/// <param name="nomeFile">file origine</param>
|
||
/// <param name="memSize">dimensione (in byte) della memoria</param>
|
||
protected void loadConfFile(ref otherData[] vettoreConf, string nomeFile, int memSize)
|
||
{
|
||
//// carico dati x Maintenance
|
||
//if (utils.CRB("verbose")) lg.Info("Inizio caricamento vettore mappa " + nomeFile);
|
||
int totRighe = 0;
|
||
string linea;
|
||
totRighe = File.ReadLines(nomeFile).Count();
|
||
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
||
vettoreConf = new otherData[File.ReadLines(nomeFile).Count()];
|
||
// carica da file...
|
||
System.IO.StreamReader file = new System.IO.StreamReader(nomeFile);
|
||
// leggo 1 linea alla volta...
|
||
int numRiga = 0;
|
||
int bitNum = 0;
|
||
int byteNum = 0;
|
||
while ((linea = file.ReadLine()) != null)
|
||
{
|
||
// SE non è un commento...
|
||
if (linea.Substring(0, 1) != "#")
|
||
{
|
||
// se finisce per BIT allora processo bit-a-bit...
|
||
if (linea.EndsWith("BIT"))
|
||
{
|
||
try
|
||
{
|
||
string[] memIdx = linea.Split(utils.CRC("testCharSep"))[0].Split('.');
|
||
// calcolo bit e byte number...
|
||
int.TryParse(memIdx[0], out byteNum);
|
||
if (memIdx.Length > 1)
|
||
{
|
||
int.TryParse(memIdx[1], out bitNum);
|
||
}
|
||
else
|
||
{
|
||
bitNum = 0;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
byteNum = 0;
|
||
bitNum = 0;
|
||
}
|
||
vettoreConf[numRiga] = decodeBitData(linea, utils.CRC("testCharSep"), "", byteNum, 1, bitNum);
|
||
}
|
||
else
|
||
{
|
||
//int.TryParse(linea.Split(utils.CRC("testCharSep"))[0], out byteNum);
|
||
vettoreConf[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), "", 1, memSize);
|
||
}
|
||
numRiga++;
|
||
}
|
||
}
|
||
// chiudo file
|
||
file.Close();
|
||
// ora trimmo vettore al solo numero VERO dei valori caricati...
|
||
Array.Resize<otherData>(ref vettoreConf, numRiga);
|
||
|
||
if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili per file {1}", numRiga, nomeFile));
|
||
}
|
||
|
||
/// <summary>
|
||
/// oggetto onnessione ESA
|
||
/// </summary>
|
||
protected thdNcEsaGvKvara ncDevice;
|
||
/// <summary>
|
||
/// thread del processo comunicazione esa
|
||
/// </summary>
|
||
protected Thread thdDevice;
|
||
|
||
/// <summary>
|
||
/// estende l'init della classe base...
|
||
/// </summary>
|
||
/// <param name="caller"></param>
|
||
/// <param name="adpConf"></param>
|
||
public AdapterESA(MainForm caller, AdapterConf adpConf) : base(caller, adpConf)
|
||
{
|
||
string iniPath = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("defaultEsaFile"));
|
||
|
||
lg.Info("Start init Adapter ESA dal file {0}", iniPath);
|
||
|
||
IniFiles.IniFile EsaIni = new IniFiles.IniFile(iniPath);
|
||
|
||
if (utils.CRB("verbose")) lg.Info("step 01: impostato INI File {0}", iniPath);
|
||
|
||
loadOtherFile();
|
||
|
||
ncDevice = new thdNcEsaGvKvara(EsaIni, mapIOT_Byte.Length, mapIOT_Word.Length, mapIOT_DWord.Length, mapIOT_String.Length);
|
||
|
||
if (utils.CRB("verbose")) lg.Info("step 02: avviato thdNcEsaGvKvara da INI File {0}", iniPath);
|
||
|
||
// inizializzo posizioni assi...
|
||
prevPosAxis = new double[adpConf.nAxis];
|
||
prevDirAxis = new int[adpConf.nAxis];
|
||
|
||
// verifica avvio...
|
||
lg.Info("ESA: tryConnect");
|
||
tryConnect();
|
||
lg.Info("End init Adapter ESA");
|
||
}
|
||
|
||
public override void tryDisconnect()
|
||
{
|
||
base.tryDisconnect();
|
||
// disconnetto
|
||
ncDevice.Disconnect();
|
||
connectionOk = false;
|
||
}
|
||
|
||
public override void tryConnect()
|
||
{
|
||
base.tryConnect();
|
||
|
||
// se non già connesso provo a connettermi...
|
||
if (!ncDevice.Connected)
|
||
{
|
||
// provo a collegarmi
|
||
if (!ncDevice.Connect())
|
||
{
|
||
//altrimenti disconnette...
|
||
ncDevice.Disconnect();
|
||
connectionOk = false;
|
||
}
|
||
else
|
||
{
|
||
connectionOk = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifico connessione ESA...
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override bool connectionOk
|
||
{
|
||
get
|
||
{
|
||
return ncDevice.Connected;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Carica ed acquisisce dati del buffer Byte (8 bit) di memoria
|
||
/// </summary>
|
||
protected void getIotMem_Byte()
|
||
{
|
||
// HARD CODE: forzo path 1 (indice 0...)
|
||
int idxPath = 0;
|
||
// accodo dati path in DataMonitor......
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
if (connectionOk)
|
||
{
|
||
// leggo TUTTO il blocco di memoria
|
||
inizio = DateTime.Now;
|
||
ncDevice.ReadBufferByte();
|
||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-PLC_IOT-Byte", ncDevice.PLC_MemoryAreaIOT_Byte.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Errore connessione mancante in getIotMem_Byte");
|
||
}
|
||
// Processing area BYTE
|
||
int numero = 0;
|
||
string status = "";
|
||
int bitNum = 0;
|
||
int byteNum = 0;
|
||
byte currByte;
|
||
for (int i = 0; i < mapIOT_Byte.Length; i++)
|
||
{
|
||
// gestisco in primis le variabili BIT
|
||
if (mapIOT_Byte[i].dataType == "BIT")
|
||
{
|
||
string[] memIdx = mapIOT_Byte[i].memAddr.Split('.');
|
||
// calcolo bit e byte number...
|
||
int.TryParse(memIdx[0], out byteNum);
|
||
if (memIdx.Length > 1)
|
||
{
|
||
int.TryParse(memIdx[1], out bitNum);
|
||
}
|
||
// leggo byte...
|
||
currByte = ncDevice.PLC_MemoryAreaIOT_Byte[byteNum];
|
||
if (mapIOT_Byte[i].varName == "IOT_EXEC")
|
||
{
|
||
if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum)))
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "RUN";
|
||
// !!!FARE per ora prendo ANCHE poweron...
|
||
mPower.Value = "ON";
|
||
}
|
||
else
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "READY";
|
||
// !!!FARE per ora prendo ANCHE poweron...
|
||
mPower.Value = "OFF";
|
||
}
|
||
}
|
||
else if (mapIOT_Byte[i].varName == "IOT_HOLD")
|
||
{
|
||
if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) //(ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] != 0)
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "FEED_HOLD"; //"FEEDHOLD";
|
||
}
|
||
}
|
||
else if (mapIOT_Byte[i].varName == "IOT_EMG")
|
||
{
|
||
// 2017.03.07 controllo bit emergenza...
|
||
if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) //(ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] != 0)
|
||
{
|
||
mEStop.Value = "TRIGGERED";
|
||
}
|
||
else
|
||
{
|
||
mEStop.Value = "ARMED";
|
||
}
|
||
}
|
||
else if (mapIOT_Byte[i].varName == "IOT_ALRM")
|
||
{
|
||
if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) //(ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] != 0)
|
||
{
|
||
// carico IN BLOCCO memoria allarmi...
|
||
// FARE!!!
|
||
}
|
||
}
|
||
}
|
||
// vado poi a gestire le variabili BYTE
|
||
else if (mapIOT_Byte[i].dataType == "BYTE")
|
||
{
|
||
int.TryParse(mapIOT_Byte[i].memAddr, out byteNum);
|
||
if (mapIOT_Byte[i].varName == "IOT_OVRF")
|
||
{
|
||
// -------------------------------------------
|
||
// recupero dati FeedOverride
|
||
// FeedOver: 100% = 213 (il pannello è 0-120 --> 0-255, quindi 100% è 100/120*255=213)
|
||
FeedRateOver = Convert.ToInt16((decimal)(ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] * 100) / 213);
|
||
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
|
||
}
|
||
else if (mapIOT_Byte[i].varName == "IOT_OVRS")
|
||
{
|
||
// -------------------------------------------
|
||
// recupero dati SpeedOverride
|
||
// SpeedOver: 50% = 128
|
||
SpeedRateOver = Convert.ToInt16((decimal)(ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] * 100) / 255);
|
||
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
|
||
}
|
||
else if (mapIOT_Byte[i].varName.StartsWith("IOT_LUB_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_LUB_", "").Replace("_Status", ""));
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
if (mapIOT_Byte[i].varName.EndsWith("_STA"))
|
||
{
|
||
if (ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] != 0)
|
||
{
|
||
status = "EMPTY";
|
||
}
|
||
else
|
||
{
|
||
status = "OK";
|
||
}
|
||
vettLubro[numero - 1].mLubroStatus.Value = status;
|
||
}
|
||
else if (mapIOT_Byte[i].varName.EndsWith("_CNT"))
|
||
{
|
||
vettLubro[numero - 1].mLubroNum.Value = ncDevice.PLC_MemoryAreaIOT_Byte[i];
|
||
}
|
||
}
|
||
else if (mapIOT_Byte[i].varName.StartsWith("IOT_I_MD_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_I_MD_", ""));
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
// salvo in vettore carico mandrini
|
||
try
|
||
{
|
||
vettUnOp[numero - 1].mUnOpLoad.Value = ncDevice.PLC_MemoryAreaIOT_Byte[i];
|
||
}
|
||
catch
|
||
{ }
|
||
}
|
||
else if (mapIOT_Byte[i].varName.StartsWith("IOT_PGMR_A_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_I_MD_", ""));
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
//// salvo in vettore carico mandrini
|
||
//try
|
||
//{
|
||
// vettUnOp[numero - 1].mUnOpLoad.Value = ncDevice.PLC_MemoryAreaIOT_Byte[i];
|
||
//}
|
||
//catch
|
||
//{ }
|
||
}
|
||
}
|
||
}
|
||
parentForm.dataMonitor += sb.ToString();
|
||
}
|
||
/// <summary>
|
||
/// Carica ed acquisisce dati del buffer WORD (16 bit) di memoria
|
||
/// </summary>
|
||
protected void getIotMem_Word()
|
||
{
|
||
if (connectionOk)
|
||
{
|
||
// leggo TUTTO il blocco di memoria
|
||
inizio = DateTime.Now;
|
||
ncDevice.ReadBufferWord();
|
||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-PLC_IOT-Word", ncDevice.PLC_MemoryAreaIOT_Word.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Errore connessione mancante in getIotMem_Word");
|
||
}
|
||
|
||
int numero = 0;
|
||
int byteNum = 0;
|
||
// Processing area WORD
|
||
for (int i = 0; i < mapIOT_Word.Length; i++)
|
||
{
|
||
int.TryParse(mapIOT_Word[i].memAddr, out byteNum);
|
||
if (mapIOT_Word[i].varName.StartsWith("IOT_S_MD_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_S_MD_", ""));
|
||
vettUnOp[numero - 1].mUnOpSpeed.Value = ncDevice.PLC_MemoryAreaIOT_Word[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_Word[i].varName.StartsWith("IOT_T_MD_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_T_MD_", ""));
|
||
vettUnOp[numero - 1].mUnOpToolId.Value = ncDevice.PLC_MemoryAreaIOT_Word[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_Word[i].varName.StartsWith("IOT_C_H_VAC_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_H_VAC_", ""));
|
||
vettVacAct[numero - 1].mVacActCount.Value = ncDevice.PLC_MemoryAreaIOT_Word[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_Word[i].varName.StartsWith("IOT_C_TC_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_TC_", ""));
|
||
vettUnOp[numero - 1].mUnOpNumCU.Value = ncDevice.PLC_MemoryAreaIOT_Word[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_Word[i].varName.StartsWith("IOT_C_H_MD_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_H_MD_", ""));
|
||
vettUnOp[numero - 1].mUnOpAccTime.Value = ncDevice.PLC_MemoryAreaIOT_Word[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Carica ed acquisisce dati del buffer DWORD (32 bit) di memoria
|
||
/// </summary>
|
||
protected void getIotMem_DWord()
|
||
{
|
||
if (connectionOk)
|
||
{
|
||
// leggo TUTTO il blocco di memoria
|
||
inizio = DateTime.Now;
|
||
ncDevice.ReadBufferDWord();
|
||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-PLC_IOT-DWord", ncDevice.PLC_MemoryAreaIOT_DWord.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Errore connessione mancante in getIotMem_DWord");
|
||
}
|
||
|
||
int numero = 0;
|
||
int byteNum = 0;
|
||
double valDouble = 0;
|
||
// Processing area WORD
|
||
for (int i = 0; i < mapIOT_DWord.Length; i++)
|
||
{
|
||
int.TryParse(mapIOT_DWord[i].memAddr, out byteNum);
|
||
if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KU_AX_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KU_AX_", ""));
|
||
vettAxis[numero - 1].mAxDistDone.Value = ncDevice.PLC_MemoryAreaIOT_DWord[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KINV_AX_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KINV_AX_", ""));
|
||
vettAxis[numero - 1].mAxInvDDone.Value = ncDevice.PLC_MemoryAreaIOT_DWord[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_DWord[i].varName.StartsWith("IOT_POS_AX_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_POS_AX_", ""));
|
||
// recupero valore pos assi (in micron)
|
||
valDouble = (double)BitConverter.ToInt32(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0);
|
||
// riporto il dato in mm (divido x 1000)
|
||
vettAxis[numero - 1].mAxPosAct.Value = valDouble / utils.CRI("fattdecimale");
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KREV_MD_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KREV_MD_", ""));
|
||
vettUnOp[numero - 1].mUnOpKRev.Value = ncDevice.PLC_MemoryAreaIOT_DWord[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_DWord[i].varName.StartsWith("IOT_PLC_MSG_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_PLC_MSG_", ""));
|
||
// copio allarmi in vettore generale AlarmFlags (dove lo gestisce) 4 byte alla volta
|
||
Buffer.BlockCopy(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0, AlarmFlags, numero * 4, 4);
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_EXEC_A_"))
|
||
{
|
||
// recupero NUMERO
|
||
try
|
||
{
|
||
numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_EXEC_A_", ""));
|
||
//vettAxis[numero - 1].mAxInvDDone.Value = ncDevice.PLC_MemoryAreaIOT_DWord[byteNum];
|
||
// FARE!!!! nuovo oggetto ed area x programmi caricati in area...
|
||
//mMessage.Code = mapIOT_DWord[i].varName;
|
||
//mMessage.Value = ncDevice.PLC_MemoryAreaIOT_DWord[byteNum];
|
||
}
|
||
catch
|
||
{
|
||
// se non trovo --> 1!
|
||
numero = 1;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
public override void getGlobalData()
|
||
{
|
||
base.getGlobalData();
|
||
|
||
// 2017.03.07 IN BLOCCO processo TUTTI i valori della memoria WORD/DWORD...
|
||
if (useIotMem)
|
||
{
|
||
processAllMemory();
|
||
}
|
||
else
|
||
{
|
||
// accodo dati path in DataMonitor......
|
||
StringBuilder sb = new StringBuilder();
|
||
if (connectionOk)
|
||
{
|
||
// leggo TUTTO il blocco di memoria
|
||
inizio = DateTime.Now;
|
||
ncDevice.ReadBuffer();
|
||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R-PLC_FullMemoryRead", ncDevice.PLC_MemoryRead.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Errore connessione mancante in getGlobalData");
|
||
}
|
||
|
||
// dati override feed/speed...
|
||
Byte v82 = ncDevice.PLC_MemoryAreaV[14];
|
||
Byte v83 = ncDevice.PLC_MemoryAreaV[15];
|
||
// 2 byte x speed da copiare...
|
||
byte[] tmpByte = new byte[2];
|
||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaV, 16, tmpByte, 0, 2);
|
||
short v84 = BitConverter.ToInt16(tmpByte, 0);
|
||
// lista allarmi PLC/CNC
|
||
Byte v87 = ncDevice.PLC_MemoryAreaV[19]; // Allarme CN (almeno 1?!?)
|
||
|
||
// -------------------------------------------
|
||
// recupero dati Feed/Speed/override
|
||
// FeedOver: 100% = 213 (il pannello è 0-120 --> 0-255, quindi 100% è 100/120*255=213)
|
||
FeedRateOver = Convert.ToInt16((decimal)(v82 * 100) / 213);
|
||
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
|
||
// SpeedOver: 50% = 128
|
||
SpeedRateOver = Convert.ToInt16((decimal)(v83 * 100) / 255);
|
||
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
|
||
// Speed S5000 OK!!!
|
||
SpeedRate = v84;
|
||
sb.AppendLine(string.Format("SpeedRate: {0} rpm", SpeedRate));
|
||
// -------------------------------------------
|
||
|
||
// da recuperare da qualche parte?!?
|
||
UnOpLoad = 0;
|
||
sb.AppendLine(string.Format("Load: {0}", UnOpLoad));
|
||
|
||
// -------------------------------------------
|
||
// recupero dati dai contatori EOK
|
||
bool needSave = false;
|
||
|
||
// ore totali accensione
|
||
int MinMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[0];
|
||
int OreMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[1];
|
||
istOreMaccOn = OreMaccOn + (double)MinMaccOn / 60;
|
||
needSave = procOreMaccOn(needSave);
|
||
|
||
// ore totali lavoro
|
||
int MinMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[2];
|
||
int OreMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[3];
|
||
istOreMaccLav = OreMaccLav + (double)MinMaccLav / 60;
|
||
needSave = procOreMaccLav(needSave);
|
||
|
||
// giri totali degli elettromandrini!
|
||
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
||
{
|
||
istGiriElettrom[i] = (uint)ncDevice.PLC_MemoryAreaEOK[4 + i];
|
||
}
|
||
needSave = procGiriTotUnOp(needSave);
|
||
needSave = procNumCU(needSave);
|
||
|
||
// per ESA calcolo a mano se ci sia stato impiego assi... salvo le istantanee mov precedenti...
|
||
double precVal = 0;
|
||
DateTime adesso = DateTime.Now;
|
||
TimeSpan accumTime = adesso.Subtract(lastChekAccumTimeAxis);
|
||
|
||
// spostamento totale assi!
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
precVal = istDistMovAssi[i];
|
||
// primo è metri, secondo km (moltiplico x 1000)
|
||
istDistMovAssi[i] = ncDevice.PLC_MemoryAreaEOK[8 + 2 * i] + ncDevice.PLC_MemoryAreaEOK[9 + 2 * i] * 1000;
|
||
// verifico SE devo aggiungere tempo lavoro sui singoli assi (se si sono spostati...) -- è a maglie LARGHE poiché leggiamo lo "scatto ogni metro" x cui se campiono velocemente ma assi muovono lenti prendo MENO tempo di movimento del reale...
|
||
if (precVal != istDistMovAssi[i])
|
||
{
|
||
istAccTimeAssi[i] += accumTime.TotalHours;
|
||
}
|
||
}
|
||
// salvo valore lastChekAccumTimeAxis
|
||
lastChekAccumTimeAxis = adesso;
|
||
|
||
needSave = procMovTotAssi(needSave);
|
||
needSave = procAccTimeAssi(needSave);
|
||
needSave = procProgrName(needSave);
|
||
needSave = procPartId(needSave);
|
||
needSave = procPzProd(needSave);
|
||
needSave = procNumInvAssi(needSave);
|
||
needSave = procVacPump(needSave);
|
||
needSave = procVacAct(needSave);
|
||
needSave = procLubro(needSave);
|
||
|
||
|
||
|
||
// salvo se necessario!
|
||
if (needSave) parentForm.persistData();
|
||
// -------------------------------------------
|
||
|
||
|
||
// copio allarmi in vettore generale AlarFlags (dove lo gestisce)...
|
||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaAllarmi, 0, AlarmFlags, 0, ncDevice.PLC_MemoryAreaAllarmi.Length);
|
||
parentForm.dataMonitor = sb.ToString();
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// Path percorso file prod
|
||
/// </summary>
|
||
protected string ScmProdFileName
|
||
{
|
||
get
|
||
{
|
||
return string.Format(@"{0}\{1}", utils.confDir, utils.CRS("ScmProdFile"));
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Oggetto elenco dati produzione
|
||
/// </summary>
|
||
public datiProdSCM[] elencoDatiProd;
|
||
|
||
/// <summary>
|
||
/// leggo altri file:
|
||
/// - dati produzione
|
||
/// </summary>
|
||
public override void getSlowChangingData()
|
||
{
|
||
base.getSlowChangingData();
|
||
|
||
// carico dati x Maintenance
|
||
if (utils.CRB("verbose")) lg.Info(string.Format("Inizio caricamento file dati produzione ({0})", ScmProdFileName));
|
||
int totRighe = 0;
|
||
string linea;
|
||
// controllo se file esista, altrimenti loggo errore!
|
||
if (!File.Exists(ScmProdFileName))
|
||
{
|
||
lg.Error(string.Format("ATTENZIONE! file dati produzione ({0}) non trovato!", ScmProdFileName));
|
||
}
|
||
else
|
||
{
|
||
totRighe = File.ReadLines(ScmProdFileName).Count();
|
||
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
|
||
datiProdSCM[] elencoDatiProdNew = new datiProdSCM[File.ReadLines(ScmProdFileName).Count()];
|
||
// carica da file...
|
||
System.IO.StreamReader file = new System.IO.StreamReader(ScmProdFileName);
|
||
// leggo 1 linea alla volta...
|
||
int rumRiga = 0;
|
||
while ((linea = file.ReadLine()) != null)
|
||
{
|
||
// SE non è un valore totale... lungh > 50 e 22 virgole (23 valori)
|
||
if (linea.Length > 50)
|
||
{
|
||
// comma separated!
|
||
elencoDatiProdNew[rumRiga] = decodeScmProdLine(linea, ',');
|
||
// se !=null conto!
|
||
if (elencoDatiProdNew != null) rumRiga++;
|
||
}
|
||
}
|
||
// chiudo file
|
||
file.Close();
|
||
// ora trimmo vettore al solo numero VERO degli allarmi caricati...
|
||
Array.Resize<datiProdSCM>(ref elencoDatiProdNew, rumRiga);
|
||
|
||
/*--------------------------------------------------
|
||
* Gestione verifica dati prod (naive)
|
||
* - se file curr vuoto --> inizio a popolare
|
||
* - se i 2 file hanno stessa lunghezza --> verifico + update last row
|
||
* - se nNew > nCurr --> accodo
|
||
* - se nCurr > nNew e nNew ==0 --> aggiorno last row giorno prec
|
||
* - se nCurr > nNew e nNew > 0 --> svuoto file curr e riparto
|
||
*--------------------------------------------------*/
|
||
|
||
|
||
// verifica preliminare dati da lung vettori
|
||
int nRecCur = 0;
|
||
int nRecIst = 0;
|
||
if (elencoDatiProd != null)
|
||
{
|
||
try
|
||
{
|
||
nRecCur = elencoDatiProd.Length;
|
||
}
|
||
catch
|
||
{ }
|
||
}
|
||
if (elencoDatiProdNew != null)
|
||
{
|
||
try
|
||
{
|
||
nRecIst = elencoDatiProdNew.Length;
|
||
}
|
||
catch
|
||
{ }
|
||
}
|
||
|
||
// uso un INT x delta qta da sommare...
|
||
int deltaQta = 0;
|
||
// in primis devo verificare che sia > 0 num oggetti su entrambi i vettori
|
||
if (nRecCur + nRecIst > 0)
|
||
{
|
||
// verifico se ho meno valori CURR e quindi devo accodare
|
||
if (nRecCur < nRecIst)
|
||
{
|
||
// resize vettore!
|
||
Array.Resize<datiProdSCM>(ref elencoDatiProd, nRecCur + 1);
|
||
// carico nuovo record
|
||
elencoDatiProd[nRecCur] = elencoDatiProdNew[nRecCur];
|
||
deltaQta = elencoDatiProd[nRecCur].qta;
|
||
nRecCur++;
|
||
}
|
||
else if (nRecCur == nRecIst)
|
||
{
|
||
// devo confrontare ULTIMO record Curr con equivalente record NEW x verificare se sia variato.. verifico PRG + start
|
||
bool checkName = elencoDatiProd[nRecCur - 1].fileName == elencoDatiProdNew[nRecCur - 1].fileName;
|
||
bool checkStart = elencoDatiProd[nRecCur - 1].start == elencoDatiProdNew[nRecCur - 1].start;
|
||
if (checkName && checkStart)
|
||
{
|
||
// salvo se variata quantità...
|
||
deltaQta = elencoDatiProdNew[nRecCur - 1].qta - elencoDatiProd[nRecCur - 1].qta;
|
||
elencoDatiProd[nRecCur - 1] = elencoDatiProdNew[nRecCur - 1];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// inizio svuotando elenco eventi CURR (migliorabile leggendo da data prec?!?)
|
||
elencoDatiProd = null;
|
||
nRecCur = 0;
|
||
}
|
||
|
||
// riporto comunque ultima riga del vettore CURR (sia perché variato sia perché aggiunto)
|
||
if (nRecCur > 0)
|
||
{
|
||
string prgName = elencoDatiProd[nRecCur - 1].fileName;
|
||
prgName = prgName.Substring(prgName.LastIndexOf(@"\") + 1);
|
||
// se il mio articolo NON cambia...
|
||
if (istPathPartId[0] == prgName)
|
||
{
|
||
istPathPartCount[0] += (uint)deltaQta;
|
||
}
|
||
else
|
||
{
|
||
istPathPartId[0] = prgName;
|
||
// 2016.07.27 riporto puntualmente qta nuovo record...
|
||
istPathPartCount[0] = (uint)deltaQta;
|
||
// old sostituito
|
||
//istPathPartCount[0] = Convert.ToUInt32(elencoDatiProd[nRecCur - 1].qta);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Processing di TUTTA l'area di memoria configurata e delle variabili derivate...
|
||
/// </summary>
|
||
public override void processAllMemory()
|
||
{
|
||
//!!!FARE!!! completare e validare parti commentate...
|
||
// inizializzo data monitor su FORM
|
||
parentForm.dataMonitor = "";
|
||
|
||
// recupero le varie memorie
|
||
getIotMem_Byte();
|
||
getIotMem_Word();
|
||
getIotMem_DWord();
|
||
//getIotMem_String();
|
||
|
||
// processo componenti specifici x info...
|
||
//getUnOp();
|
||
//getPath();
|
||
getAxis();
|
||
|
||
// !!!FARE verifica...
|
||
//getConfigParam();
|
||
////acquisisco dati su programma in esecuzione e dati generali (stato, orologio, power...)
|
||
//getSlowChangingData();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Processo stti macchina...
|
||
/// </summary>
|
||
public override void processStatus()
|
||
{
|
||
|
||
// HARD CODE: forzo path 1 (indice 0...)
|
||
int idxPath = 0;
|
||
// accodo dati path in DataMonitor......
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
// 2017.03.07 IN BLOCCO processo TUTTI i valori della memoria BYTE...
|
||
if (useIotMem)
|
||
{
|
||
processAllMemory();
|
||
}
|
||
else
|
||
{
|
||
// verifica macchina accesa...
|
||
Byte V73 = ncDevice.PLC_MemoryAreaV[5];
|
||
|
||
if (((StFlag8)V73).HasFlag(StFlag8.B2))
|
||
{
|
||
mPower.Value = "ON";
|
||
}
|
||
else
|
||
{
|
||
mPower.Value = "OFF";
|
||
}
|
||
|
||
// switch su EXE mode...
|
||
/*
|
||
* MODO_X V[70/71] --> byte (2-3)
|
||
* V70.2 = Modo RUN
|
||
* V70.3 = Modo FeedHold
|
||
* V71.5 = Ready
|
||
* */
|
||
Byte V70 = ncDevice.PLC_MemoryAreaV[2];
|
||
Byte V71 = ncDevice.PLC_MemoryAreaV[3];
|
||
|
||
if (((StFlag8)V70).HasFlag(StFlag8.B3))
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "FEED_HOLD"; //"FEEDHOLD";
|
||
}
|
||
else if (((StFlag8)V70).HasFlag(StFlag8.B2))
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "ACTIVE";
|
||
}
|
||
else if (((StFlag8)V71).HasFlag(StFlag8.B5))
|
||
{
|
||
vettPath[idxPath].mPathExeMode.Value = "READY";
|
||
}
|
||
//// appunto: modi da creare
|
||
//STOPPED/HOLD(da creare)
|
||
//INTERRUPTED(da creare)
|
||
//OPTIONAL_STOP(da creare)
|
||
//PROGRAM_STOPPED(da creare)
|
||
//PROGRAM_COMPLETED(da creare)
|
||
|
||
|
||
// switch su run mode...
|
||
/*
|
||
* MODO_X V[74].W --> byte (6)
|
||
* 0 = Modo NESSUNO
|
||
* 1 = Modo MANUALE
|
||
* 2 = Modo AUTOMATICO
|
||
* 3 = Modo POM
|
||
* 4 = Modo MDI
|
||
* 5 = Modo SEMIAUTOMATICO
|
||
* 6 = Modo RAP
|
||
* 7 = Modo TES
|
||
* */
|
||
uint V74 = ncDevice.PLC_MemoryAreaV[6];
|
||
switch (V74)
|
||
{
|
||
case 1:
|
||
vettPath[idxPath].mPathRunMode.Value = "EDIT";
|
||
break;
|
||
case 2:
|
||
vettPath[idxPath].mPathRunMode.Value = "AUTOMATIC";
|
||
break;
|
||
case 3:
|
||
vettPath[idxPath].mPathRunMode.Value = "MANUAL";
|
||
break;
|
||
case 4:
|
||
vettPath[idxPath].mPathRunMode.Value = "MANUAL_DATA_INPUT";
|
||
break;
|
||
case 5:
|
||
vettPath[idxPath].mPathRunMode.Value = "SEMI_AUTOMATIC"; //"SEMIAUTO";
|
||
break;
|
||
case 6:
|
||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"RAP";
|
||
break;
|
||
case 7:
|
||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"TES";
|
||
break;
|
||
case 0:
|
||
default:
|
||
vettPath[idxPath].mPathRunMode.Value = "NA";
|
||
break;
|
||
}
|
||
}
|
||
//parentForm.dataMonitor = sb.ToString();
|
||
}
|
||
/// <summary>
|
||
/// Recupera la speed override x i mandrini (UnOp)
|
||
/// </summary>
|
||
public override void getUnOp()
|
||
{
|
||
// cicl su UnOp
|
||
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
||
{
|
||
vettUnOp[i].mUnOpSpeedOverr.Value = SpeedRateOver;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Carica info accessorie assi (direzione, feed, ...)
|
||
/// </summary>
|
||
public override void getAxis()
|
||
{
|
||
// mostro assi in DataMonitor......
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
// nuova posizione (per calcoli)
|
||
double newPos = 0;
|
||
double distPerc = 0;
|
||
int newDir = 0;
|
||
string tipoAsse = "";
|
||
string direzione = "";
|
||
|
||
// leggo in modo "cablato" i dati dei vari assi...
|
||
for (int i = 0; i < currAdpConf.nAxis; i++)
|
||
{
|
||
vettAxis[i].mAxFeedAct.Value = FeedRate;
|
||
|
||
// calcolo distanza e salvo valore...
|
||
newPos = Convert.ToDouble(vettAxis[i].mAxPosAct.Value);
|
||
distPerc = newPos - prevPosAxis[i];
|
||
|
||
// sistemo direzione +/- (POS/NEG se lineari, CCW/CW se rotativi)
|
||
if (distPerc != 0)
|
||
{
|
||
newDir = Convert.ToInt32(distPerc / Math.Abs(distPerc));
|
||
}
|
||
else
|
||
{
|
||
newDir = prevDirAxis[i];
|
||
}
|
||
|
||
|
||
// verifico tipo direzione da tipo asse...
|
||
tipoAsse = vettAxis[i].mAxType.Value.ToString();
|
||
if (tipoAsse == "LINEAR")
|
||
{
|
||
// ?: conditional operator.
|
||
direzione = (newDir > 0) ? "POSITIVE" : "NEGATIVE";
|
||
}
|
||
else if (tipoAsse == "ROTARY")
|
||
{
|
||
direzione = (newDir > 0) ? "CLOCKWISE" : "COUNTER_CLOCKWISE";
|
||
}
|
||
|
||
vettAxis[i].mAxDir.Value = direzione;
|
||
|
||
// se la direzione è variata salvo il cambio direzione...
|
||
if (newDir != prevDirAxis[i])
|
||
{
|
||
// salvo "+1" come cambi direzione
|
||
istNumInvAssi[i]++;
|
||
}
|
||
|
||
if (utils.CRB("verbose"))
|
||
{
|
||
sb.AppendLine(string.Format("Asse {0}: PosAct:{1:N3}, | {2}", i, (double)(newPos), direzione));
|
||
}
|
||
|
||
// salvo valori vettore prec...
|
||
prevPosAxis[i] = newPos;
|
||
prevDirAxis[i] = newDir;
|
||
}
|
||
|
||
parentForm.dataMonitor += sb.ToString();
|
||
}
|
||
|
||
#if false
|
||
public override void processAlarm()
|
||
{
|
||
base.processAlarm();
|
||
if (!useIotMem)
|
||
{
|
||
// ora controllo "allarmi speciali" se si sono...
|
||
if (AlarmFlags != null)
|
||
{
|
||
// variabili helper
|
||
StFlag32 AlarmBlock = 0;
|
||
int eStopCode = utils.CRI("eStopCode") - 1; // è base zero memoria, ma allarmi base 1...
|
||
|
||
int memStart = (int)Math.Floor((double)eStopCode / 8);
|
||
// leggo 32bit alla volta...
|
||
AlarmBlock = (StFlag32)BitConverter.ToUInt32(AlarmFlags, memStart);
|
||
int eStopIndex = eStopCode - memStart * 8;
|
||
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
|
||
if (AlarmBlock.HasFlag((StFlag32)Math.Pow(2, eStopIndex)))
|
||
{
|
||
mEStop.Value = "TRIGGERED";
|
||
}
|
||
else
|
||
{
|
||
mEStop.Value = "ARMED";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|