1114 lines
35 KiB
C#
1114 lines
35 KiB
C#
using CndexLinkDotNet;
|
|
using IOB_UT;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using testSam;
|
|
|
|
namespace IOB_WIN
|
|
{
|
|
public class IobOSAI : IobGeneric
|
|
{
|
|
|
|
/// <summary>
|
|
/// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
|
|
/// </summary>
|
|
Dictionary<string, string> signLUT = new Dictionary<string, string>();
|
|
/// <summary>
|
|
/// Struttura dati principale in continuo update...
|
|
/// </summary>
|
|
protected Cndex.GETINFO1DATA oData;
|
|
/// <summary>
|
|
/// Vettore degli allarmi CNC attivi
|
|
/// </summary>
|
|
public Dictionary<string, string> allarmiCNC = new Dictionary<string, string>();
|
|
/// <summary>
|
|
/// Stato corrente (da classe ENUM)
|
|
/// </summary>
|
|
public CNC_STATUS_OSAI currStatus;
|
|
|
|
#if false
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura OSAI x BYTE...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="memOrderStart">0/1 orimo o secondo byte della word...</param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_Byte(bool bWrite, OSAI.MemTypeWord MemType, Int32 memIndex, Int32 memOrderStart, ref byte[] Value)
|
|
{
|
|
bool answ = false;
|
|
#if false
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_Byte(bWrite, MemType, memIndex, memOrderStart, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_Byte");
|
|
}
|
|
}
|
|
#endif
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura x WORD...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_Word(bool bWrite, OSAI.MemTypeWord MemType, Int32 memIndex, ref ushort[] Value)
|
|
{
|
|
bool answ = false;
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
#if false
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_Word(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_Word");
|
|
}
|
|
#endif
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura x DOUBLE-WORD...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_DWord(bool bWrite, OSAI.MemTypeWord MemType, Int32 memIndex, ref uint[] Value)
|
|
{
|
|
bool answ = false;
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
#if false
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_DWord(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_DWord");
|
|
}
|
|
#endif
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura x Short...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_Short(bool bWrite, OSAI.MemTypeWord MemType, Int32 memIndex, ref short[] Value)
|
|
{
|
|
bool answ = false;
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
#if false
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_Short(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_Short");
|
|
}
|
|
#endif
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura x INT...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_Integer(bool bWrite, OSAI.MemTypeWord MemType, Int32 memIndex, ref int[] Value)
|
|
{
|
|
bool answ = false;
|
|
#if false
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_Integer(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_Integer");
|
|
}
|
|
}
|
|
#endif
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// wrapper chiamata lettura/scrittura x Double...
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="memIndex"></param>
|
|
/// <param name="MATRICE Value"></param>
|
|
/// <returns></returns>
|
|
public bool OsaiMemRW_Double(bool bWrite, OSAI.MemTypeDouble MemType, Int32 memIndex, ref double[] Value)
|
|
{
|
|
bool answ = false;
|
|
#if false
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
try
|
|
{
|
|
parentForm.commPlcActive = true;
|
|
answ = OSAI_ref.O_RW_Double(bWrite, MemType, memIndex, ref Value);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in OsaiMemRW_Double");
|
|
}
|
|
}
|
|
#endif
|
|
parentForm.commPlcActive = false;
|
|
return answ;
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Oggetto MAIN x connessione OSAI
|
|
/// </summary>
|
|
protected ComCNOsai OSAI_ref;
|
|
|
|
/// <summary>
|
|
/// estende l'init della classe base...
|
|
/// </summary>
|
|
/// <param name="caller"></param>
|
|
/// <param name="adpConf"></param>
|
|
public IobOSAI(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
|
{
|
|
// i dati RAW principali sono 6 byte...
|
|
RawInput = new byte[6];
|
|
|
|
// gestione invio ritardato contapezzi
|
|
pzCountDelay = utils.CRI("pzCountDelay");
|
|
lastPzCountSend = DateTime.Now;
|
|
lastWarnODL = DateTime.Now;
|
|
|
|
// inizializzo correttamente aree memoria secondo CONF - iniFileName
|
|
IniFile fIni = new IniFile(IOBConf.iniFileName);
|
|
|
|
// inizializzo aree di memoria correnti...
|
|
|
|
// fix enable prgName
|
|
enablePrgName = fIni.ReadBoolean("CNC", "GETPRGNAME", true);
|
|
|
|
// effettuo lettura della conf sigLUT... cercando 1:1 i bit...
|
|
string currBit = "";
|
|
string memArea = "";
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
currBit = string.Format("BIT{0}", i);
|
|
memArea = fIni.ReadString("MEMORY", currBit, "");
|
|
// se trovo un valore...
|
|
if (memArea != "")
|
|
{
|
|
signLUT.Add(currBit, memArea);
|
|
}
|
|
}
|
|
|
|
// è little endian (NON serve conversione)
|
|
hasBigEndian = false;
|
|
lgInfo("Start init Adapter OSAI all'IP {0}:{1} per IOB {2}", IOBConf.cncIpAddr, IOBConf.cncPort, IOBConf.codIOB);
|
|
|
|
// Creo oggetto x gestione connessione/comunicazione NC: secondo il tipo creo CNDEX o OPEN
|
|
parentForm.commPlcActive = true;
|
|
if (IOBConf.tipoIob == tipoAdapter.OSAI_OPEN)
|
|
{
|
|
OSAI_ref = new Open_Series(IOBConf.cncIpAddr, false);
|
|
}
|
|
else
|
|
{
|
|
OSAI_ref = new ComCNOsai(IOBConf.cncIpAddr, false);
|
|
}
|
|
parentForm.commPlcActive = false;
|
|
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo(string.Format("INIT OSAI_ref da CncLib come {0}", IOBConf.tipoIob));
|
|
}
|
|
|
|
// disconnetto e connetto...
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo("OSAI: tryDisconnect");
|
|
}
|
|
|
|
tryDisconnect();
|
|
lgInfo("OSAI: tryConnect");
|
|
tryConnect();
|
|
|
|
|
|
// recupero machine status e mode da cui decodificare info sul PLC...
|
|
byte machineStatus = OSAI_ref.GetMachineStatus();
|
|
byte modeSelected = OSAI_ref.GetModeSelected();
|
|
lgInfo(string.Format("Lettura preliminare: machineStatus={0} | modeSelected={1}", machineStatus, modeSelected));
|
|
|
|
// possiamo leggere tutto da qui che contiene status, mode e last_nc_error
|
|
oData = new Cndex.GETINFO1DATA();
|
|
var ncInfo = OSAI_ref.NcInfo1(ref oData);
|
|
|
|
lgInfo(string.Format("Lettura START completa NCINFO1DATA{0} lastNcError={1}{0}status={2}{0}substatus={9}{0}mode_select={3}{0}main_progr_name={4}{0}speed_ov={5}{0}progr_speed={6}{0}real_speed={7}{0}real_feed={8}{0}", Environment.NewLine, oData.last_nc_error, oData.status, oData.mode_select, oData.main_progr_name, oData.speed_ov, oData.progr_speed, oData.real_speed, oData.real_feed, oData.substatus));
|
|
|
|
// inizio il calcolo dello status semaforico
|
|
short bitStatus = 0;
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
bitStatus += 1;
|
|
}
|
|
|
|
// lettura variabili (es contapezzi)
|
|
ComCNOsai.stVAR temp;
|
|
temp.nAddress = 29; // impostare da conf
|
|
temp.nBit = 0;
|
|
temp.nNumCn = 1;
|
|
temp.szVarName = "";
|
|
|
|
short risultato;
|
|
risultato = OSAI_ref.ReadShortVar(temp);
|
|
|
|
|
|
// area vb di riferimento x decodifica...
|
|
#if false
|
|
' valore bitmap dello statup IOB
|
|
Dim status As Short = 0
|
|
|
|
' power on
|
|
If CnOsai.Connected Then
|
|
status += 1
|
|
End If
|
|
|
|
' RUN mode
|
|
If (machineStatus = ComCNOsai.CYCLE_ And modeSelected = ComCNOsai.AUTO) Then
|
|
status += 2
|
|
End If
|
|
|
|
' Allarme
|
|
If (machineStatus = ComCNOsai.ERRO_) Then
|
|
status += 8
|
|
End If
|
|
|
|
' Manuale
|
|
If (modeSelected <> ComCNOsai.AUTO) Then
|
|
status += 16
|
|
End If
|
|
|
|
' Allarme
|
|
If (machineStatus = ComCNOsai.EMERG_) Then
|
|
status += 32
|
|
End If
|
|
|
|
|
|
' compongo i bit di status...
|
|
Dim IobBitmap As String
|
|
IobBitmap = "--------------" + vbCrLf
|
|
IobBitmap += "Bitmap IOB:" + vbCrLf
|
|
IobBitmap += status.ToString() + vbCrLf
|
|
IobBitmap += "--------------" + vbCrLf + vbCrLf
|
|
|
|
' per leggere variabili dichiaro la struttura
|
|
Dim temp As ComCNOsai.stVAR
|
|
temp.nAddress = nVar_NC_state ' da conf che vale 352 da
|
|
temp.nBit = 0
|
|
temp.nNumCn = 1
|
|
temp.szVarName = ""
|
|
|
|
Dim risultato As Short
|
|
risultato = CnOsai.ReadShortVar(temp)
|
|
|
|
IobBitmap += vbCrLf
|
|
IobBitmap += "Variabile " + nVar_NC_state.ToString() + ": " + risultato.ToString()
|
|
#endif
|
|
|
|
|
|
|
|
if (utils.CRB("enableContapezzi"))
|
|
{
|
|
lgInfo("OSAI: inizio gestione contapezzi");
|
|
try
|
|
{
|
|
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
|
|
if (currIobConf.optPar.Count > 0 && currIobConf.optPar["PZCOUNT_MODE"] != "")
|
|
{
|
|
if (currIobConf.optPar["PZCOUNT_MODE"].StartsWith("OVAR"))
|
|
{
|
|
pzCntReload();
|
|
// refresh associazione Macchina - IOB
|
|
sendM2IOB();
|
|
// per adesso imposto lettura dal CNC == contapezzi (poi farà vera lettura...)
|
|
lastCountCNC = contapezzi;
|
|
}
|
|
else
|
|
{
|
|
contapezzi = 0;
|
|
lgInfo("Contapezzi STD disabilitato: modalità {0}", currIobConf.optPar["PZCOUNT_MODE"]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
contapezzi = 0;
|
|
lgInfo("Parametro mancante PZCOUNT_MODE");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in contapezzi OSAI");
|
|
}
|
|
}
|
|
// finisco INIT ADAPTER
|
|
lgInfo("End init Adapter OSAI");
|
|
}
|
|
/// <summary>
|
|
/// Override disconnessione
|
|
/// </summary>
|
|
public override void tryDisconnect()
|
|
{
|
|
if (connectionOk)
|
|
{
|
|
string szStatusConnection = "";
|
|
try
|
|
{
|
|
OSAI_ref.CloseSession();
|
|
connectionOk = false;
|
|
// resetto timing!
|
|
TimingData.resetData();
|
|
lgInfo(szStatusConnection);
|
|
lgInfo("Effettuata disconnessione adapter OSAI!");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgFatal(exc, "Errore nella disconnessione dall'adapter OSAI");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgError("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile...");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Override connessione
|
|
/// </summary>
|
|
public override void tryConnect()
|
|
{
|
|
if (!connectionOk)
|
|
{
|
|
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
|
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
|
{
|
|
if (verboseLog || periodicLog)
|
|
{
|
|
lgInfo("ConnKO - tryConnect");
|
|
}
|
|
// in primis salvo data ping...
|
|
lastPING = DateTime.Now;
|
|
// ora PING!!!
|
|
Ping pingSender = new Ping();
|
|
IPAddress address = IPAddress.Loopback;
|
|
IPAddress.TryParse(currIobConf.cncIpAddr, out address);
|
|
PingReply reply = pingSender.Send(address, 100);
|
|
// se passa il ping faccio il resto...
|
|
if (reply.Status == IPStatus.Success)
|
|
{
|
|
string szStatusConnection = "";
|
|
try
|
|
{
|
|
// ora provo connessione...
|
|
parentForm.commPlcActive = true;
|
|
OSAI_ref.OpenSession();
|
|
|
|
parentForm.commPlcActive = false;
|
|
lgInfo("szStatusConnection: " + szStatusConnection);
|
|
connectionOk = true;
|
|
// refresh stato allarmi!!!
|
|
if (connectionOk)
|
|
{
|
|
dtAvvioAdp = DateTime.Now;
|
|
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 OSAI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
lgInfo(string.Format("Eccezione in TryConnect, Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// loggo no risposta ping ...
|
|
connectionOk = false;
|
|
if (verboseLog || periodicLog)
|
|
{
|
|
lgInfo(string.Format("Attenzione: controllo PING fallito per IP {0} - {1}", currIobConf.cncIpAddr, reply.Status));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// se non è ancora connesso faccio procesisng memoria caso disconnesso...
|
|
if (!connectionOk)
|
|
{
|
|
// processo semafori ed invio...
|
|
processMemoryDiscon();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// lettura principale (bit semafori)
|
|
/// </summary>
|
|
public override void readSemafori()
|
|
{
|
|
base.readSemafori();
|
|
try
|
|
{
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("inizio read semafori");
|
|
}
|
|
|
|
parentForm.sIN = Semaforo.SV;
|
|
|
|
stopwatch.Restart();
|
|
// possiamo leggere tutto da qui che contiene tutto: status, mode, last_nc_error
|
|
var ncInfo = OSAI_ref.NcInfo1(ref oData);
|
|
// time rec
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(currIobConf.codIOB, "GETINFO1DATA", stopwatch.ElapsedTicks);
|
|
}
|
|
stopwatch.Stop();
|
|
|
|
// salvo il solo BYTE dell'input decifrando il semaforo...
|
|
decodeToBitmap();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(string.Format("Eccezione in readSemafori:{0}{1}", Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
|
/// </summary>
|
|
private void decodeToBitmap()
|
|
{
|
|
// init a zero...
|
|
B_input = 0;
|
|
// SE SI E' CONNESSO al CNC allora è 1=powerON...
|
|
if (OSAI_ref.Connected)
|
|
{
|
|
B_input += 1 << 0;
|
|
}
|
|
|
|
// decodifico impiegando dictionary... cercando il TIPO di memoria & co...
|
|
string bKey = "";
|
|
string bVal = "";
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
bKey = string.Format("BIT{0}", i);
|
|
// cerco se ci sia in LUT
|
|
if (signLUT.ContainsKey(bKey))
|
|
{
|
|
// recupero nome variabile...
|
|
bVal = signLUT[bKey];
|
|
// se l'area è PZCOUNT... processo PUNTUALMENTE il CONTAPEZZI...
|
|
if (bVal.StartsWith("PZCOUNT"))
|
|
{
|
|
string currODL = "";
|
|
try
|
|
{
|
|
currODL = utils.callUrl(urlGetCurrODL);
|
|
if (utils.CRB("verbose"))
|
|
{
|
|
lgInfo(string.Format("Lettura ODL, {0} --> {1}", currIdxODL, currODL));
|
|
}
|
|
// 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")
|
|
{
|
|
// controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture
|
|
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
|
|
{
|
|
// verifico se variato contapezzi in area STD PAR6711... 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 OSAI: {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 OSAI: {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 OSAI: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
|
|
// resetto timer...
|
|
lastPzCountSend = DateTime.Now;
|
|
}
|
|
}
|
|
}
|
|
// controllo le condizioni x costruire il bit1 RUN!
|
|
if (oData.mode_select == 2 && oData.status == 2)
|
|
{
|
|
B_input += 1 << 1;
|
|
}
|
|
// errore su bit3
|
|
if (oData.mode_select == 6)
|
|
{
|
|
B_input += 1 << 3;
|
|
}
|
|
// auto su bit4
|
|
if (oData.mode_select != 2)
|
|
{
|
|
B_input += 1 << 4;
|
|
}
|
|
// emergenza su bit5
|
|
if (oData.mode_select == 9)
|
|
{
|
|
B_input += 1 << 5;
|
|
}
|
|
}
|
|
}
|
|
// 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 = "";
|
|
// recupero NUOVO prgName...
|
|
try
|
|
{
|
|
// recupero nome programma MAIN
|
|
prgName = System.Text.Encoding.Default.GetString(oData.main_progr_name);
|
|
// trimmo path del programma, ovvero "CNCMEMUSERPATH1"
|
|
prgName = prgName.Replace(utils.CRS("basePrgMemPath"), "");
|
|
lgInfo("Current PROG: {0}", prgName);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
}
|
|
return prgName;
|
|
}
|
|
/// <summary>
|
|
/// Recupero programma in lavorazione come Dictionary CNC...
|
|
/// - 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>();
|
|
stopwatch.Restart();
|
|
#if false
|
|
CncLib.Focas1.ODBSYS answ = OSAI_ref.getSysInfo();
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(currIobConf.codIOB, string.Format("SYS-INFO"), stopwatch.ElapsedTicks);
|
|
}
|
|
|
|
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");
|
|
connectionOk = false;
|
|
}
|
|
#endif
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Effettua vero processing contapezzi appoggiato ad area specifica da CONF
|
|
/// </summary>
|
|
public override void processContapezzi()
|
|
{
|
|
if (utils.CRB("enableContapezzi"))
|
|
{
|
|
try
|
|
{
|
|
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
|
|
if (currIobConf.optPar.Count > 0 && currIobConf.optPar["PZCOUNT_MODE"] != "")
|
|
{
|
|
string memAddr = currIobConf.optPar["PZCOUNT_MODE"];
|
|
if (memAddr.StartsWith("STD"))
|
|
{
|
|
// inizio verifica area memoria/parametro levando prima parte codice
|
|
memAddr = memAddr.Replace("STD.", "");
|
|
// var di appoggio
|
|
int cntAddr = 0;
|
|
// verifico se si tratta di lettura MEMORIA... formato tipo STD.MEM.6711
|
|
if (memAddr.StartsWith("MEM."))
|
|
{
|
|
// recupero parametro...
|
|
int.TryParse(memAddr.Replace("MEM.", ""), out cntAddr);
|
|
if (cntAddr == 0)
|
|
{
|
|
cntAddr = 29;
|
|
}
|
|
// processo parametro contapezzi (lavorati)
|
|
stopwatch.Restart();
|
|
// vera lettura area memoria...
|
|
short resVal = 0;
|
|
// lettura variabili (es contapezzi)
|
|
ComCNOsai.stVAR tmpVar;
|
|
tmpVar.nAddress = cntAddr;
|
|
tmpVar.nBit = 0;
|
|
tmpVar.nNumCn = 1;
|
|
tmpVar.szVarName = "";
|
|
// vera lettura
|
|
resVal = OSAI_ref.ReadShortVar(tmpVar);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(currIobConf.codIOB, string.Format("R{0}-MEM", 2), stopwatch.ElapsedTicks);
|
|
}
|
|
// aggiungo in visualizzazione SE variata...
|
|
if (resVal != lastCountCNC)
|
|
{
|
|
string mCount = string.Format("MEM{0}", cntAddr);
|
|
string sVal = string.Format("[PZCOUNT]{0}|{1}", mCount, resVal);
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog(mCount, resVal.ToString()));
|
|
}
|
|
// salvo ultimo conteggio rilevato
|
|
lastCountCNC = resVal;
|
|
}
|
|
stopwatch.Stop();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in contapezzi CNC");
|
|
connectionOk = false;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Esegue processing MODE (e nel contempo recupera altri dati dell'area G)
|
|
/// </summary>
|
|
public override void processMode()
|
|
{
|
|
if (utils.CRB("enableMode"))
|
|
{
|
|
try
|
|
{
|
|
// verifico modo con valore corrente, se cambia aggiorno...
|
|
CNC_MODE newMode = decodeModeOsai(oData.mode_select);
|
|
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, string.Format("Errore in process Mode OSAI: {0}{1}", Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
stopwatch.Stop();
|
|
}
|
|
}
|
|
// lo status lo processo SEMPRE
|
|
try
|
|
{
|
|
// verifico modo con valore corrente, se cambia aggiorno...
|
|
CNC_STATUS_OSAI newStatus = (CNC_STATUS_OSAI)(oData.status);
|
|
if (newStatus != currStatus)
|
|
{
|
|
// aggiorno!
|
|
currStatus = newStatus;
|
|
// accodo x invio
|
|
string sVal = string.Format("[CNC_STATUS]{0}", currStatus.ToString());
|
|
// chiamo accodamento...
|
|
accodaFLog(sVal, qEncodeFLog("CNC_STATUS", currStatus.ToString()));
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, string.Format("Errore in process Mode OSAI: {0}{1}", Environment.NewLine, exc));
|
|
connectionOk = false;
|
|
stopwatch.Stop();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Decodifica del MODE selezionato
|
|
/// </summary>
|
|
/// <param name="mode"></param>
|
|
/// <returns></returns>
|
|
protected CNC_MODE decodeModeOsai(int mode)
|
|
{
|
|
CNC_MODE answ = CNC_MODE.ND;
|
|
switch (mode)
|
|
{
|
|
case 1:
|
|
answ = CNC_MODE.MDI;
|
|
break;
|
|
case 2:
|
|
answ = CNC_MODE.AUTO;
|
|
break;
|
|
case 3:
|
|
answ = CNC_MODE.SEMI;
|
|
break;
|
|
case 4:
|
|
answ = CNC_MODE.JOG_MAN;
|
|
break;
|
|
case 5:
|
|
answ = CNC_MODE.JOG_INC;
|
|
break;
|
|
case 6:
|
|
answ = CNC_MODE.PROFILE;
|
|
break;
|
|
case 7:
|
|
answ = CNC_MODE.HOME;
|
|
break;
|
|
case 8:
|
|
answ = CNC_MODE.HANDLE_INC;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Recupero dati dinamici...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getDynData()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
stopwatch.Restart();
|
|
try
|
|
{
|
|
string actf = oData.real_feed.ToString();
|
|
string acts = oData.real_speed.ToString();
|
|
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);
|
|
outVal.Add("ACT_TOOL", oData.actual_tool.ToString());
|
|
}
|
|
if (utils.CRB("SendAxPos"))
|
|
{
|
|
// salvo info assi...
|
|
outVal.Add("AX_SEL", oData.ax_sel.ToString());
|
|
outVal.Add("NUM_AX_SEL", oData.num_ax_sel.ToString());
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError(exc, "Errore in getDynData");
|
|
}
|
|
stopwatch.Stop();
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Recupero dati override (da area G che è già stata letta...)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override Dictionary<string, string> getOverrides()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
outVal.Add("FEED_OVER", (oData.feed_ov).ToString());
|
|
outVal.Add("RAPID_OVER", (oData.rapid_override).ToString());
|
|
return outVal;
|
|
}
|
|
/// <summary>
|
|
/// Recupera e processa allarmi CNC...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getCncAlarms()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
// se ho allarmi li accodo...
|
|
if (oData.last_nc_error != 0)
|
|
{
|
|
try
|
|
{
|
|
outVal.Add("CNC_ALARM", (oData.last_nc_error).ToString());
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error(exc, "Eccezione in getCncAlarms");
|
|
}
|
|
}
|
|
return outVal;
|
|
}
|
|
#if false
|
|
|
|
/// <summary>
|
|
/// Override salvataggio valori in memoria...
|
|
/// </summary>
|
|
/// <param name="tipo">tipo di DUMP</param>
|
|
public override void saveMemDump(dumpType tipo)
|
|
{
|
|
#if false
|
|
// se l'area ha una size > 0...
|
|
if (areaD.arraySize > 0)
|
|
{
|
|
dump_MemArea(tipo, FANUC.MemType.D, areaD.startIdx, areaD.arraySize);
|
|
}
|
|
// se l'area ha una size > 0...
|
|
if (areaR.arraySize > 0)
|
|
{
|
|
dump_MemArea(tipo, FANUC.MemType.R, areaR.startIdx, areaR.arraySize);
|
|
}
|
|
// se l'area ha una size > 0...
|
|
if (areaX.arraySize > 0)
|
|
{
|
|
dump_MemArea(tipo, FANUC.MemType.X, areaX.startIdx, areaX.arraySize);
|
|
}
|
|
// se l'area ha una size > 0...
|
|
if (areaY.arraySize > 0)
|
|
{
|
|
dump_MemArea(tipo, FANUC.MemType.Y, areaY.startIdx, areaY.arraySize);
|
|
}
|
|
// se l'area ha una size > 0...
|
|
if (areaPAR.arraySize > 0)
|
|
{
|
|
dump_ParArea(tipo, areaPAR.startIdx, areaPAR.arraySize);
|
|
}
|
|
#endif
|
|
}
|
|
/// <summary>
|
|
/// Dump area D della memoria
|
|
/// </summary>
|
|
/// <param name="tipo">tipo di DUMP: START (sovrascrivendo) / SAMPLE (salva tanti campionamenti)</param>
|
|
/// <param name="tipoMem">tipo memoria</param>
|
|
/// <param name="memIndex">area memoria di partenza</param>
|
|
/// <param name="memSizeByte">dimensione memoria</param>
|
|
private void dump_MemArea(dumpType tipo, FANUC.MemType tipoMem, int memIndex, int memSizeByte)
|
|
{
|
|
DateTime adesso = DateTime.Now;
|
|
string nomeFileB = "";
|
|
string nomeFileW = "";
|
|
string nomeFileDW = "";
|
|
Dictionary<string, string> mappaValori = new Dictionary<string, string>();
|
|
// per sicurezza verifico < 9999 byte
|
|
if (memSizeByte > 9999)
|
|
{
|
|
memSizeByte = 9999;
|
|
}
|
|
// leggo TUTTI i (MAX 9999) byte della memoria D...
|
|
byte[] MemBlockCurr = new byte[memSizeByte];
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("START MemDump", tipoMem);
|
|
}
|
|
|
|
stopwatch.Restart();
|
|
#if false
|
|
OsaiMemRW(R, tipoMem, memIndex, ref MemBlockCurr);
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(currIobConf.codIOB, string.Format("R{0}-{1}", MemBlockCurr.Length, tipoMem), stopwatch.ElapsedTicks);
|
|
}
|
|
#endif
|
|
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("END MemDump", tipoMem);
|
|
}
|
|
|
|
// seconda del tipo di lettura definisco i nomi delle variabili...
|
|
if (tipo == dumpType.SAMPLE)
|
|
{
|
|
nomeFileB = string.Format(@"{0}\SAMPLES\{1}_{2}_Byte_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem, adesso);
|
|
nomeFileW = string.Format(@"{0}\SAMPLES\{1}_{2}_W_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem, adesso);
|
|
nomeFileDW = string.Format(@"{0}\SAMPLES\{1}_{2}_DW_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem, adesso);
|
|
}
|
|
else
|
|
{
|
|
// salvo in file i dati letti come BYTE
|
|
nomeFileB = string.Format(@"{0}\{1}_{2}_Byte.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem);
|
|
nomeFileW = string.Format(@"{0}\{1}_{2}_W.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem);
|
|
nomeFileDW = string.Format(@"{0}\{1}_{2}_DW.dat", utils.dataDatDir, currIobConf.codIOB, tipoMem);
|
|
}
|
|
|
|
// salvo in file i dati letti come BYTE
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockCurr.Length; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), MemBlockCurr[i].ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFileB);
|
|
|
|
// salvo in file i dati letti come Word (2byte)
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockCurr.Length / 2; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt16(MemBlockCurr, i * 2).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFileW);
|
|
|
|
// salvo in file i dati letti come DWord (4byte)
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < MemBlockCurr.Length / 4; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockCurr, i * 4).ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFileDW);
|
|
}
|
|
/// <summary>
|
|
/// Dump area PARAMETRI
|
|
/// </summary>
|
|
/// <param name="tipo">tipo di DUMP: START (sovrascrivendo) / SAMPLE (salva tanti campionamenti)</param>
|
|
/// <param name="memIndex">Parametro di partenza</param>
|
|
/// <param name="numPar">Numero parametri da esportare... memoria</param>
|
|
private void dump_ParArea(dumpType tipo, int memIndex, int numPar)
|
|
{
|
|
DateTime adesso = DateTime.Now;
|
|
string nomeFile = "";
|
|
Dictionary<string, string> mappaValori = new Dictionary<string, string>();
|
|
// per sicurezza verifico < 9999 parametri
|
|
if (numPar > 9999)
|
|
{
|
|
numPar = 9999;
|
|
}
|
|
|
|
// leggo TUTTI i (MAX 9999) byte della memoria D...
|
|
object[] paramsArray = new object[numPar];
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("START ParamDump");
|
|
}
|
|
|
|
stopwatch.Restart();
|
|
#if false
|
|
for (int i = 0; i < numPar; i++)
|
|
{
|
|
OSAI_ref.F_RW_Param_Integer(false, memIndex + i, 3, ref paramsArray[i]);
|
|
}
|
|
#endif
|
|
|
|
if (utils.CRB("recTime"))
|
|
{
|
|
TimingData.addResult(currIobConf.codIOB, string.Format("R{0}-PAR", 4 * numPar), stopwatch.ElapsedTicks);
|
|
}
|
|
|
|
if (verboseLog)
|
|
{
|
|
lgInfo("END ParamDump");
|
|
}
|
|
|
|
// seconda del tipo di lettura definisco i nomi delle variabili...
|
|
if (tipo == dumpType.SAMPLE)
|
|
{
|
|
nomeFile = string.Format(@"{0}\SAMPLES\{1}_{2}_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, currIobConf.codIOB, "PAR", adesso);
|
|
}
|
|
else
|
|
{
|
|
nomeFile = string.Format(@"{0}\{1}_{2}.dat", utils.dataDatDir, currIobConf.codIOB, "PAR");
|
|
}
|
|
|
|
// salvo in file i dati letti
|
|
mappaValori = new Dictionary<string, string>();
|
|
for (int i = 0; i < paramsArray.Length; i++)
|
|
{
|
|
mappaValori.Add(i.ToString("0000"), paramsArray[i].ToString());
|
|
}
|
|
utils.WritePlain(mappaValori, nomeFile);
|
|
}
|
|
#endif
|
|
}
|
|
}
|