Files
Mapo-IOB-WIN/IOB-WIN-FANUC/Iob/Fanuc.cs
T
Samuele Locatelli fa976dd2bb Update IOB BASE:
- aggiunto InitializeAsync
- gestione override x ogni IOB
2026-01-23 10:22:00 +01:00

2862 lines
120 KiB
C#

using EgwProxy.MultiCncLib.App.Native;
using EgwProxy.MultiCncLib.CNC;
using IOB_UT_NEXT;
using IOB_UT_NEXT.Config;
using MapoSDK;
using NLog;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace IOB_WIN_FANUC.Iob
{
public class Fanuc : Iob.GenericNext
{
/// <summary>
/// Oggetto logger della classe
/// </summary>
private static Logger _logger = LogManager.GetCurrentClassLogger();
#region Public Constructors
/// <summary>
/// estende l'init della classe base...
/// </summary>
/// <param name="caller">Form chiamante</param>
/// <param name="IobConfFull">Configurazione (v 4.x)</param>
public Fanuc(AdapterFormNext caller, IobConfTree IobConfFull) : base(caller, IobConfFull)
{
lgInfo("Start init Fanuc");
// i dati RAW principali sono 6 byte...
RawInput = new byte[6];
// gestione invio ritardato contapezzi
lastPzCountSend = DateTime.Now;
lastWarnODL = DateTime.Now;
int gSize = 8;
int rSize = 8;
int xSize = 8;
int ySize = 8;
if (IOBConfFull.Special.BankConf.AreaConf.ContainsKey("AREAG"))
{
gSize = IOBConfFull.Special.BankConf.AreaConf["AREAG"].Size;
}
if (IOBConfFull.Special.BankConf.AreaConf.ContainsKey("AREAR"))
{
rSize = IOBConfFull.Special.BankConf.AreaConf["AREAR"].Size;
}
if (IOBConfFull.Special.BankConf.AreaConf.ContainsKey("AREAX"))
{
xSize = IOBConfFull.Special.BankConf.AreaConf["AREAX"].Size;
}
if (IOBConfFull.Special.BankConf.AreaConf.ContainsKey("AREAY"))
{
ySize = IOBConfFull.Special.BankConf.AreaConf["AREAY"].Size;
}
MemBlockG = new byte[gSize];
MemBlockR = new byte[rSize];
MemBlockX = new byte[xSize];
MemBlockY = new byte[ySize];
// loggo aree di memoria avviate...
lgInfo($"Init area di memoria | MemBlockG: {gSize}b | MemBlockR: {rSize}b | MemBlockX: {xSize}b | MemBlockY: {ySize}b ");
areaD = FormatAreaFanuc("AreaD", "AREAD");
areaPAR = FormatAreaFanuc("AreaPARR", "PAR");
areaR = FormatAreaFanuc("AreaR", "AREAR");
areaX = FormatAreaFanuc("AreaX", "AREAX");
areaY = FormatAreaFanuc("AreaY", "AREAY");
lgInfo($"Set Mem | {areaD.areaName}: {areaD.startIdx} +{areaD.arraySize} | {areaR.areaName}: {areaR.startIdx} +{areaR.arraySize} | {areaX.areaName}: {areaX.startIdx} +{areaX.arraySize} | {areaY.areaName}: {areaY.startIdx} +{areaY.arraySize}");
lgInfoStartup($"Start init Adapter FANUC all'IP {IOBConfFull.Device.Connect.IpAddr}:{IOBConfFull.Device.Connect.Port} per IOB {IOBConfFull.General.CodIOB}");
// Creo oggetto connessione NC
parentForm.commPlcActive = true;
Runtime.CreateNC(CNC.NcType.FANUC, IOBConfFull.Device.Connect.IpAddr, IOBConfFull.Device.Connect.Port);
parentForm.commPlcActive = false;
// aggiungo referenza obj FANUC
FANUC_ref = (FANUC)Runtime.NC;
if (isVerboseLog)
{
lgInfo("FANUC_ref da EgwProxy.MultiCncLib");
}
// disconnetto e connetto...
if (isVerboseLog)
{
lgInfo("FANUC: tryDisconnect");
}
tryDisconnect();
lgInfo("FANUC: tryConnect");
tryConnect();
if (enablePzCountByApp)
{
lgInfo("FANUC: inizio gestione contapezzi");
try
{
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
// indicazione area)
if (!string.IsNullOrEmpty(IOBConfFull.Device.PzCountMode))
{
if (IOBConfFull.Device.PzCountMode.StartsWith("STD"))
{
lgInfo("Init contapezzi FANUC: pzCntReload(true)");
pzCntReload(true);
// refresh associazione Macchina - IOB
SendM2IOB();
// per adesso imposto lettura fanuc == contapezzi (poi farà vera lettura...)
contapezziPLC = contapezziIOB;
}
else
{
contapezziIOB = 0;
lgInfo($"Contapezzi STD disabilitato: modalità {IOBConfFull.Device.PzCountMode}");
}
}
else
{
contapezziIOB = 0;
lgInfo("Parametro mancante PzCountMode");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in contapezzi FANUC 01");
}
}
// finisco INIT ADAPTER
lgInfo("End init Adapter FANUC");
}
public override async Task InitializeAsync()
{
// invio altri dati accessori...
await SendMachineConfAsync();
}
/// <summary>
/// Formatta area x memorie Fanuc da conf caricata
/// </summary>
/// <param name="aName"></param>
/// <param name="mKey"></param>
/// <returns></returns>
private memAreaFanuc FormatAreaFanuc(string aName, string mKey)
{
var newArea = new memAreaFanuc() { areaName = aName };
if (IOBConfFull.Special.BankConf.AreaConf.ContainsKey(mKey))
{
var thisConf = IOBConfFull.Special.BankConf.AreaConf[mKey];
newArea.startIdx = thisConf.Start;
newArea.arraySize = thisConf.Size;
}
return newArea;
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Processo i task richiesti e li elimino dalla coda 1:1
/// </summary>
/// <param name="task2exe"></param>
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe, string codTav)
{
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
Dictionary<string, string> taskDone = new Dictionary<string, string>();
if (task2exe != null)
{
bool taskOk = false;
string taskVal = "";
string newVal = "";
string memAddr = "";
int newValInt = 0;
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
foreach (var item in task2exe)
{
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
switch (tName)
{
case taskType.setArt:
case taskType.setComm:
lgInfo($"Richiesta scrittura {tName}");
// salvo in memoria il valore richiesto...
if (memMap != null && memMap.mMapWrite != null)
{
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
memAddr = currMem.memAddr;
taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
memMap.mMapWrite[item.Key].value = newVal;
}
else
{
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
}
}
else
{
taskVal = $"NO BankConf found, SET task: {item.Key} --> {newVal} ({item.Value})";
}
upsertKey(item.Key, item.Value);
break;
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.setProg:
case taskType.sendWatchDogMes2Plc:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
lgTrace($"sendWatchDogMes2Plc | Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
break;
case taskType.setArtNum:
lgInfo($"Richiesta scrittura CodART numerico");
// in primis faccio una chiamata per tutta la tab SE fosse vuoto il dict
// di traduzione
if (DictNumArt == null || DictNumArt.Count == 0)
{
getNumArt("");
lgInfo($"Recuperato DictNumArt, trovati {DictNumArt.Count} rec");
}
// chiamo server x avere decodifica valore INT
newVal = getNumArt(item.Value);
// se c'è gestione semplificata num articolo --> usa trim dei soli
// caratteri alfabetici lasciando numeri..
if (numArtCharTrim)
{
newVal = baseUtils.GetNumbers(item.Value);
}
// converto int...
int.TryParse(newVal, out newValInt);
// procedo come il resto cercando mappatura in memMap: recupero dati da memMap...
if (memMap != null && memMap.mMapWrite != null)
{
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
memAddr = currMem.memAddr;
taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
memMap.mMapWrite[item.Key].value = newVal;
}
else
{
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
}
}
else
{
taskVal = $"NO BankConf found, SET task: {item.Key} --> {newVal} ({item.Value})";
}
// invio a controller...
taskOk = setNumArt(newValInt);
//se ho successo rileggo ed eventualmente sistemo valore
if (taskOk)
{
//var rVal = getValByParam("SET_NUM_ART");
var rVal = getValByMemAddr(memAddr);
if (rVal == newVal)
{
lgInfo("All OK");
// invio aggiornamento x reset richiesta... test!
sendOptVal(item.Key, newVal);
}
else
{
lgError($"setArtNum | Error | memAddr: {memAddr} | rVal: {rVal} | newVal: {newVal}");
}
}
else
{
lgError("setArtNum | Errore in scrittura SetNumArt");
}
// salvo in currProd..
upsertKey(item.Key, item.Value);
break;
case taskType.setCommNum:
lgInfo($"Richiesta scrittura cod COMMESSA numerica");
// chiamo server x avere decodifica valore INT
newVal = getNumComm(item.Value);
// converto int...
int.TryParse(newVal, out newValInt);
//riscrivo senza eventuali zeri...
newVal = newValInt > 0 ? $"{newValInt}" : newVal;
lgTrace($"Conv.Int numComm | newVal: {newVal} | newValInt: {newValInt}");
// procedo come il resto cercando mappatura in memMap: recupero dati da memMap...
if (memMap != null && memMap.mMapWrite != null)
{
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
memAddr = currMem.memAddr;
taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
memMap.mMapWrite[item.Key].value = newVal;
}
else
{
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
}
}
else
{
taskVal = $"NO BankConf found, SET task: {item.Key} --> {newVal} ({item.Value})";
}
// invio a controller...
taskOk = setNumCom(newValInt);
//se ho successo rileggo ed eventualmente sistemo valore
if (taskOk)
{
//var rVal = getValByParam("SET_NUM_COM");
var rVal = getValByMemAddr(memAddr);
if (rVal == newVal)
{
lgInfo("All OK");
// invio aggiornamento x reset richiesta... test!
sendOptVal(item.Key, newVal);
}
else
{
lgError($"setCommNum | Error | memAddr: {memAddr} | rVal: {rVal} | newVal: {newVal}");
}
}
else
{
lgError("setCommNum | Errore in scrittura SetNumCom");
}
// salvo in currProd..
upsertKey(item.Key, item.Value);
break;
case taskType.forceResetPzCount:
// set pezzi zero inizio setup
taskOk = setPzCnt(0);
taskVal = taskOk ? "forceResetPzCount: OK" : "forceResetPzCount | NO EXEC";
lgInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
// salvo in currProd..
upsertKey(item.Key, item.Value);
break;
case taskType.forceSetPzCount:
int pzCnt = 0;
int.TryParse(item.Value, out pzCnt);
// set pezzi richiesti inizio setup
taskOk = setPzCnt(pzCnt);
taskVal = taskOk ? "forceSetPzCount: OK" : "forceSetPzCount | NO EXEC";
lgInfo($"Chiamata forceSetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
// salvo in currProd..
upsertKey(item.Key, item.Value);
break;
case taskType.setPzComm:
int pzReq = 0;
int.TryParse(item.Value, out pzReq);
// set pezzi richiesti inizio setup
taskOk = setPzComm(pzReq);
taskVal = taskOk ? "setPzComm | RESET DONE: SETUP START" : "setPzComm | PZ RESET DISABLED | NO EXEC";
lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
// salvo in currProd..
upsertKey(item.Key, item.Value);
break;
case taskType.startSetup:
// reset contapezzi inizio setup
if (IOBConfFull.Counters.ResetOnSetupStart)
{
taskOk = resetContapezziPLC(codTav);
}
taskVal = taskOk ? "startSetup | RESET: SETUP START" : "startSetup | PZ RESET DISABLED | NO EXEC";
lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
break;
case taskType.stopSetup:
// reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
if (IOBConfFull.Counters.ResetOnSetupStop)
{
taskOk = resetContapezziPLC(codTav);
}
taskVal = taskOk ? "stopSetup | RESET: SETUP END" : "stopSetup | PZ RESET DISABLED | NO EXEC";
lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
break;
case taskType.endProd:
// reset contapezzi inizio setup
if (IOBConfFull.Counters.ResetOnProdEnd)
{
lgDebug($"Fanuc.executeTasks {tName} | resetContapezziPLC");
taskOk = resetContapezziPLC(codTav);
}
break;
case taskType.setParameter:
lgInfo($"setParameter | NO processing: taskOk: {taskOk} | taskVal: {taskVal}");
taskVal = "setParameter | SKIPPED | NO EXEC";
break;
default:
lgInfo($"executeTasks | default senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
}
}
return taskDone;
}
/// <summary>
/// Wrapper chiamata lettura/scrittura INTERO in area macro...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="memIndex"></param>
/// <param name="Value"></param>
/// <returns></returns>
public bool FanucMemMacroRW(bool bWrite, Int32 memIndex, ref short Value)
{
bool answ = false;
if (connectionOk)
{
if (FANUC_ref.Connected)
{
try
{
parentForm.commPlcActive = true;
// provo ad usare SEMPRE double...
short zeroVal = 0;
// in primis scrivo reset a zero...
answ = FANUC_ref.F_RW_Macro_Short(bWrite, memIndex, ref zeroVal);
// ora scrivo vero valore...
answ = FANUC_ref.F_RW_Macro_Short(bWrite, memIndex, ref Value);
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
catch (Exception exc)
{
numErroriCheck++;
lgError($"Eccezione in FanucMemMacroRW | Short | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
}
else
{
numErroriCheck++;
}
}
else
{
numErroriCheck++;
}
parentForm.commPlcActive = false;
return answ;
}
/// <summary>
/// Wrapper chiamata lettura/scrittura DOUBLE in area macro...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="memIndex"></param>
/// <param name="Value"></param>
/// <returns></returns>
public bool FanucMemMacroRW(bool bWrite, Int32 memIndex, ref double Value)
{
bool answ = false;
if (connectionOk)
{
if (FANUC_ref.Connected)
{
try
{
parentForm.commPlcActive = true;
short zeroVal = 0;
// in primis scrivo reset a zero...
answ = FANUC_ref.F_RW_Macro_Short(bWrite, memIndex, ref zeroVal);
// ora scrivo vero valore...
answ = FANUC_ref.F_RW_Macro_Double(bWrite, memIndex, ref Value);
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
catch (Exception exc)
{
numErroriCheck++;
lgError($"Eccezione in FanucMemMacroRW | Double | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
}
else
{
numErroriCheck++;
}
}
else
{
numErroriCheck++;
}
parentForm.commPlcActive = false;
return answ;
}
/// <summary>
/// wrapper chiamata lettura/scrittura SINGOLO BYTE...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="MemType"></param>
/// <param name="memIndex"></param>
/// <param name="Value"></param>
/// <returns></returns>
public bool FanucMemRW(bool bWrite, FANUC.MemType MemType, Int32 memIndex, ref byte Value)
{
bool answ = false;
if (connectionOk)
{
if (FANUC_ref.Connected)
{
try
{
parentForm.commPlcActive = true;
answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
catch (Exception exc)
{
numErroriCheck++;
lgError($"Eccezione in FanucMemMacroRW | Byte | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
}
else
{
numErroriCheck++;
}
}
else
{
numErroriCheck++;
}
parentForm.commPlcActive = false;
return answ;
}
/// <summary>
/// wrapper chiamata lettura/scrittura MULTI BYTE...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="MemType"></param>
/// <param name="memIndex"></param>
/// <param name="Value"></param>
/// <returns></returns>
public bool FanucMemRW(bool bWrite, FANUC.MemType MemType, Int32 memIndex, ref byte[] Value)
{
bool answ = false;
if (connectionOk)
{
if (FANUC_ref.Connected)
{
try
{
parentForm.commPlcActive = true;
answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
catch (Exception exc)
{
numErroriCheck++;
lgError($"Eccezione in FanucMemMacroRW | MultiByte | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
}
else
{
numErroriCheck++;
}
}
else
{
numErroriCheck++;
}
parentForm.commPlcActive = false;
return answ;
}
/// <summary>
/// Recupero dati dinamici...
/// </summary>
public override Dictionary<string, string> getDynData()
{
Dictionary<string, string> outVal = new Dictionary<string, string>();
// processo SOLO SE connected...
if (connectionOk)
{
if (FANUC_ref.Connected)
{
try
{
sw.Restart();
EgwProxy.MultiCncLib.Focas1.ODBDY2_1 answ = FANUC_ref.getAllDynData();
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("PROC-DYN-DATA"), sw.ElapsedTicks);
}
string actf = answ.actf.ToString();
string acts = answ.acts.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);
}
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)
{
numErroriCheck++;
lgError($"Errore in getDynData | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
sw.Stop();
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
}
// se supero soglia errori lettura --> disconnetto e resetto
if (numErroriCheck > maxErroriCheck)
{
lgError($"numErroriCheck: {numErroriCheck} --> disconnessione adapter con tryDisconnect");
numErroriCheck = 0;
connectionOk = false;
tryDisconnect();
}
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>();
// processo SOLO SE connected...
if (connectionOk)
{
if (FANUC_ref.Connected)
{
if (utils.CRB("enableMode") && MemBlockG != null && MemBlockG.Length > 0)
{
outVal.Add("FEED_OVER", MemBlockG[30].ToString());
outVal.Add("RAPID_OVER", MemBlockG[12].ToString());
}
}
}
return outVal;
}
/// <summary>
/// Recupero programma in lavorazione
/// </summary>
/// <returns></returns>
public override string getPrgName()
{
string prgName = "";
DateTime adesso = DateTime.Now;
try
{
// recupero nome programma MAIN
prgName = utils.purgedChar2String(FANUC_ref.getPrgNameMain());
// trimmo path del programma, ovvero "CNCMEMUSERPATH1"
prgName = prgName.Replace(utils.CRS("basePrgMemPath"), "");
lgInfo("Current PROG: {0}", prgName);
numErroriCheck = numErroriCheck > 0 ? numErroriCheck-- : 0;
}
catch (Exception exc)
{
numErroriCheck++;
lgError($"Eccezione in recupero PRG NAME MAIN | numErroriCheck: {numErroriCheck}{Environment.NewLine}{exc}");
}
// se supero soglia errori lettura --> disconnetto e resetto
if (numErroriCheck > maxErroriCheck)
{
lgError($"numErroriCheck: {numErroriCheck} --> disconnessione adapter con tryDisconnect");
numErroriCheck = 0;
connectionOk = false;
tryDisconnect();
}
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>();
sw.Restart();
EgwProxy.MultiCncLib.Focas1.ODBSYS answ = FANUC_ref.getSysInfo();
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("SYS-INFO"), sw.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 = memName.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;
}
return outVal;
}
/// <summary>
/// Effettua vero processing contapezzi:
/// 6711: pezzi lavorati
/// 6712: pezzi lavorati totali
/// 6713: pezzi richiesti
/// </summary>
public override void processContapezzi()
{
if (enablePzCountByApp)
{
// procedo SOLO SE ho connessione...
if (connectionOk)
{
try
{
// contapezzi ATTUALE
if (!string.IsNullOrEmpty(IOBConfFull.Device.PzCountMode))
{
// verifico quale modalità sia richiesta: STD (6711) oppure BIT
// (Custom, con indicazione area)
string memAddr = IOBConfFull.Device.PzCountMode;
if (memAddr.StartsWith("STD"))
{
// inizio verifica area memoria/parametro levando prima parte codice
memAddr = memAddr.Replace("STD.", "");
}
// var di appoggio
int cntAddr = 0;
object outputVal = new object();
// verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
if (memAddr.StartsWith("PAR."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 6711;
}
// processo parametro contapezzi (lavorati)
sw.Restart();
FANUC_ref.F_RW_Param_Integer(false, cntAddr, 3, ref outputVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-PAR", 4), sw.ElapsedTicks);
}
// salvo ultimo conteggio rilevato
int newVal = -1;
Int32.TryParse(outputVal.ToString(), out newVal);
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
}
// 2022.05.23 gestione MACRO da testare (Jetco)
else if (memAddr.StartsWith("MACRO."))
{
lgTrace($"Decodifica memoria MACRO | memAddr: {memAddr}");
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
// processo parametro
sw.Restart();
double macroVal = 0;
FANUC_ref.F_Read_macro(cntAddr, ref macroVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-MACRO", 5), sw.ElapsedTicks);
}
// salvo ultimo conteggio rilevato
int newVal = -1;
Int32.TryParse($"{macroVal}", out newVal);
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
}
// altrimenti se legge da area memoria specifica leggo da li...
// formato tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
if (isVerboseLog)
{
lgInfo("processContapezzi [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
// leggo!
sw.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo
// conteggio rilevato
switch (areaCounter.vType)
{
case "B":
byte valB = 0;
FANUC_ref.F_RW_Byte(false, areaCounter.mType, areaCounter.mPos, ref valB);
outputVal = valB;
break;
case "D":
ushort valW = 0;
FANUC_ref.F_RW_Word(false, areaCounter.mType, areaCounter.mPos, ref valW);
outputVal = valW;
break;
case "DW":
uint valDW = 0;
FANUC_ref.F_RW_DWord(false, areaCounter.mType, areaCounter.mPos, ref valDW);
if (isVerboseLog)
{
lgInfo("[1] valDW contapezzi: {0}", valDW);
}
outputVal = valDW;
if (isVerboseLog)
{
lgInfo("[2] outputVal contapezzi: {0}", outputVal);
}
break;
default:
break;
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), sw.ElapsedTicks);
}
// salvo...
int newVal = -1;
Int32.TryParse(outputVal.ToString(), out newVal);
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
//if (isVerboseLog)
//{
lgInfo("[3] contapezziPLC contapezzi: {0}", contapezziPLC);
//}
}
sw.Stop();
}
}
catch (Exception exc)
{
lgError(exc, "Errore in contapezzi FANUC 02");
connectionOk = false;
}
}
else
{
lgError("Errore: manca connessione in contapezzi FANUC");
}
}
}
/// <summary>
/// Esegue processing MODE (e nel contempo recupera altri dati dell'area G)
/// </summary>
public override void processMode()
{
// processo SOLO SE connected...
if (connectionOk)
{
if (FANUC_ref.Connected)
{
if (utils.CRB("enableMode") && MemBlockG != null && MemBlockG.Length > 0)
{
try
{
// leggo tutto da 0 a 43...
int memIndex = 0;
// controllo modalità lettura memoria
sw.Restart();
FanucMemRW(R, FANUC.MemType.G, memIndex, ref MemBlockG);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-G-AREA", MemBlockG.Length), sw.ElapsedTicks);
}
sw.Stop();
// 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...
bool sent = accodaFLog("CNC_MODE", sVal, qEncodeFLog("CNC_MODE", descrMode));
if (sent)
{ // traccio valore DynData x analisi
trackDynData("CNC_MODE", descrMode);
}
}
}
catch (Exception exc)
{
lgError(exc, string.Format("Errore in process Mode G43: {0}{1}", Environment.NewLine, exc));
connectionOk = false;
sw.Stop();
}
}
}
}
}
/// <summary>
/// Recupero altri counters se ci sono
/// </summary>
public override void processOtherCounters()
{
// processo verifica ed invio 1:1
checkSendCounter("PzReq", memNamePzReq, memAddrPzReq);
checkSendCounter("Articolo", memNameArt, memAddrArt);
checkSendCounter("Commessa", memNameCom, memAddrCom);
checkSendCounter("PzCount", memNamePzCnt, memAddrPzCnt);
checkSendCounter("FreeCounter", memNamePzCntFree, memAddrPzCntFree);
checkSendCounter("PzCntTOT", memNamePzCntTot, memAddrPzCntTot);
checkSendCounter("Cadenza", memNameCaden, memAddrCaden);
}
/// <summary>
/// Verifica se effettuare invio (a scadenza) del valore counter richiesto
/// </summary>
/// <param name="varName"></param>
/// <param name="currMemName"></param>
/// <param name="currMemAddr"></param>
private void checkSendCounter(string varName, string currMemName, string currMemAddr)
{
try
{
// gestione con ricerca in memoria Write / optPar...
if (string.IsNullOrEmpty(currMemAddr))
{
lgTrace($"{varName} disabilitato | NO memConf.Write | NO optPar");
}
else
{
DateTime adesso = DateTime.Now;
int currPeriod = memPeriod(currMemName);
// se non ha periodo abilito invio
bool doSend = currPeriod == 0;
// altrimenti verifica
if (!doSend)
{
if (VetoCounterSend.ContainsKey(currMemName))
{
// verifico scadenza...
if (VetoCounterSend[currMemName] < adesso)
{
VetoCounterSend[currMemName] = adesso.AddSeconds(currPeriod);
doSend = true;
lgInfo($"checkSendCounter | set veto for {varName} at {VetoCounterSend[currMemName]:HH:mm:ss}");
}
}
else
{
VetoCounterSend.Add(currMemName, adesso.AddSeconds(currPeriod));
doSend = true;
lgTrace($"{varName} | Veto still active until {VetoCounterSend[currMemName]:HH:mm:ss}");
}
}
// per il counter verifico SE sia da inviare...
if (doSend)
{
sendOptVal(currMemName, getValByMemAddr(currMemAddr));
}
}
}
catch (Exception exc)
{
lgError(exc, $"Eccezione | processOtherCounters.checkSendCounter | {varName} | {currMemName} | {currMemAddr}{Environment.NewLine}{exc}");
}
}
/// <summary>
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
/// aggiornare x display in form</paramref>
/// </summary>
public override void readSemafori(ref newDisplayData currDispData)
{
DateTime adesso = DateTime.Now;
base.readSemafori(ref currDispData);
// verifico non sia in veto invio iniziale...
if (queueInEnabCurr)
{
try
{
if (verboseLog)
{
lgInfo("inizio read semafori");
}
currDispData.semIn = Semaforo.SV;
// ogni lettura inizia da SUA area inizio controllo area R: se ha dati (> 0
// byte) --> leggo!
if (MemBlockR.Length > 0)
{
sw.Restart();
FanucMemRW(R, FANUC.MemType.R, areaR.startIdx, ref MemBlockR);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-R", MemBlockR.Length), sw.ElapsedTicks);
}
// log
if (verboseLog)
{
for (int i = 0; i < MemBlockR.Length; i++)
{
lgInfo(string.Format("MemBlockR{0}: {1}", i, utils.binaryForm(MemBlockR[i])));
}
}
}
// controllo area X: se ha dati (> 0 byte) --> leggo!
if (MemBlockX.Length > 0)
{
sw.Restart();
FanucMemRW(R, FANUC.MemType.X, areaX.startIdx, ref MemBlockX);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-X", MemBlockX.Length), sw.ElapsedTicks);
}
// log
if (verboseLog)
{
for (int i = 0; i < MemBlockX.Length; i++)
{
lgInfo(string.Format("MemBlockX{0}: {1}", i, utils.binaryForm(MemBlockX[i])));
}
}
}
// controllo area Y: se ha dati (> 0 byte) --> leggo!
if (MemBlockY.Length > 0)
{
sw.Restart();
FanucMemRW(R, FANUC.MemType.Y, areaY.startIdx, ref MemBlockY);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-Y", MemBlockY.Length), sw.ElapsedTicks);
}
// log
if (verboseLog)
{
for (int i = 0; i < MemBlockY.Length; i++)
{
lgInfo(string.Format("MemBlockY{0}: {1}", i, utils.binaryForm(MemBlockY[i])));
}
}
}
sw.Stop();
// salvo il solo BYTE dell'input decifrando il semaforo...
decodeToBitmap();
reportRawInput(ref currDispData);
}
catch (Exception exc)
{
lgError(string.Format("Eccezione in readSemafori:{0}{1}", Environment.NewLine, exc));
connectionOk = false;
currDispData.semIn = Semaforo.SR;
}
}
else
{
lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}");
checkVetoQueueIn();
}
}
/// <summary>
/// Effettua reset del contapezzi
/// </summary>
/// <returns></returns>
public override bool resetContapezziPLC(string codTav)
{
bool answ = false;
// scrivo valore 0 x il contapezzi
try
{
// contapezzi ATTUALE
if (!string.IsNullOrEmpty(IOBConfFull.Device.PzCountMode))
{
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
// indicazione area)
string memAddr = IOBConfFull.Device.PzCountMode;
if (memAddr.StartsWith("STD"))
{
// inizio verifica area memoria/parametro levando prima parte codice
memAddr = memAddr.Replace("STD.", "");
}
// var di appoggio
int cntAddr = 0;
// var contapezzi a zero....
object newVal = new object();
newVal = 0;
// verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
if (memAddr.StartsWith("PAR."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 6711;
}
// processo RESET contapezzi (lavorati)
sw.Restart();
FANUC_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W{0}-PAR", 4), sw.ElapsedTicks);
}
}
else if (memAddr.StartsWith("MACRO."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 9999;
}
// processo SET contapezzi (lavorati)
sw.Restart();
double vTransf = (double)0;
answ = FanucMemMacroRW(true, cntAddr, ref vTransf);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "MACRO-SHORT", sw.ElapsedTicks);
}
}
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
if (isVerboseLog)
{
lgInfo("resetContapezziPLC [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
// leggo!
sw.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
switch (areaCounter.vType)
{
case "B":
byte valB = 0;
FANUC_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB);
newVal = valB;
break;
case "D":
ushort valW = 0;
FANUC_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW);
newVal = valW;
break;
case "DW":
uint valDW = 0;
FANUC_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW);
break;
default:
break;
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), sw.ElapsedTicks);
}
}
sw.Stop();
answ = true;
}
}
catch (Exception exc)
{
lgError(exc, "Errore in RESET contapezzi FANUC");
connectionOk = false;
}
return answ;
}
/// <summary>
/// Override salvataggio valori in memoria...
/// </summary>
/// <param name="tipo">tipo di DUMP</param>
public override void saveMemDump(dumpType tipo)
{
// 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);
}
}
/// <summary>
/// Effettua impostazione del valore numerico ARTICOLO (specifico FANUC)
/// </summary>
/// <returns></returns>
public bool setNumArt(int valReq)
{
bool answ = false;
string memAddr = memAddrArt;
lgTrace($"INIT setNumArt | memAddr: {memAddr}");
if (!string.IsNullOrEmpty(memAddr))
{
// scrivo valore richiesto in area configurata
try
{
// var di appoggio
int cntAddr = 0;
// verifico se si tratta di lettura MACRO... formato tipo MACRO.6711
if (memAddr.StartsWith("MACRO."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 9999;
}
lgTrace($"MACRO | ART Write 01 | memAddr: {memAddr} | idx: {cntAddr}");
// processo SET contapezzi (lavorati)
sw.Restart();
// comincio scrivendo reset a zero x cominciare...
double vTransf = (double)valReq;
answ = FanucMemMacroRW(true, cntAddr, ref vTransf);
lgTrace($"MACRO | ART Write 02 | memAddr: {memAddr} | valReq: {valReq} | vTransf: {vTransf}");
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "MACRO-SHORT", sw.ElapsedTicks);
}
}
sw.Stop();
}
catch (Exception exc)
{
lgError(exc, "Errore in setNumArt FANUC");
connectionOk = false;
}
}
return answ;
}
/// <summary>
/// Effettua impostazione del valore numerico COMMESSA (specifico FANUC)
/// </summary>
/// <returns></returns>
public bool setNumCom(int valReq)
{
bool answ = false;
// verifico quale modalità sia richiesta
string memAddr = memAddrCom;
lgTrace($"INIT setNumCom | memAddr: {memAddr}");
if (!string.IsNullOrEmpty(memAddr))
{
lgTrace($"setNumCom | memAddr: {memAddr} | valReq: {valReq}");
// scrivo valore richiesto in area configurata
try
{
// var di appoggio
int cntAddr = 0;
// verifico se si tratta di lettura MACRO... formato tipo MACRO.6711
if (memAddr.StartsWith("MACRO."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 9999;
}
lgTrace($"MACRO | Com Write 01 | memAddr: {memAddr} | idx: {cntAddr}");
// processo SET contapezzi (lavorati)
sw.Restart();
double vTransf = (double)valReq;
answ = FanucMemMacroRW(true, cntAddr, ref vTransf);
lgTrace($"MACRO | Com Write 02 | memAddr: {memAddr} | valReq: {valReq} | vTransf: {vTransf}");
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "MACRO-SHORT", sw.ElapsedTicks);
}
}
sw.Stop();
}
catch (Exception exc)
{
lgError(exc, "Errore in setNumCom FANUC");
connectionOk = false;
}
answ = true;
}
return answ;
}
protected bool setPzCnt(int pzCnt)
{
bool answ = false;
// ...SE abilitato da conf IOB
if (IOBConfFull.Counters.EnableSetPzCount)
{
// scrivo valore del contapezzi
try
{
string memAddr = memAddrPzCnt;
lgTrace($"INIT setPzCnt | memAddr: {memAddr}");
// contapezzi ATTUALE
if (!string.IsNullOrEmpty(memAddr))
{
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
// indicazione area)
if (memAddr.StartsWith("STD"))
{
// inizio verifica area memoria/parametro levando prima parte codice
memAddr = memAddr.Replace("STD.", "");
}
// var di appoggio
int cntAddr = 0;
// var contapezzi a zero....
object newVal = new object();
newVal = pzCnt;
// verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
if (memAddr.StartsWith("PAR."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 6711;
}
// processo SET contapezzi (lavorati)
sw.Restart();
FANUC_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W{0}-PAR", 4), sw.ElapsedTicks);
}
}
else if (memAddr.StartsWith("MACRO."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 9999;
}
lgTrace($"MACRO | Pz Write 01 | memAddr: {memAddr} | idx: {cntAddr}");
// processo SET contapezzi (lavorati)
sw.Restart();
// se > 2^16 scrivo con INT, sennò con double...
short valTrShr = 0;
double valTrDbl = 0;
if (pzCnt < Math.Pow(2, 16))
{
valTrShr = (short)pzCnt;
answ = FanucMemMacroRW(true, cntAddr, ref valTrShr);
//answ = FANUC_ref.F_RW_Macro_Short(true, cntAddr, ref valTrShr);
lgTrace($"MACRO | Com Write 02 SHORT | memAddr: {memAddr} | pzCnt: {pzCnt} | valTrShr: {valTrShr}");
}
// sennò double!
else
{
valTrDbl = (double)pzCnt;
answ = FanucMemMacroRW(true, cntAddr, ref valTrDbl);
//answ = FANUC_ref.F_RW_Macro_Double(true, cntAddr, ref valTrDbl);
lgTrace($"MACRO | Com Write 02 DOUBLE | memAddr: {memAddr} | pzCnt: {pzCnt} | valTrDbl: {valTrDbl}");
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "MACRO-SHORT", sw.ElapsedTicks);
}
}
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
if (isVerboseLog)
{
lgInfo("setPzComm [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
// leggo!
sw.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
switch (areaCounter.vType)
{
case "B":
byte valB = (byte)pzCnt;
FANUC_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB);
newVal = valB;
break;
case "D":
ushort valW = (ushort)pzCnt;
FANUC_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW);
newVal = valW;
break;
case "DW":
uint valDW = (uint)pzCnt;
FANUC_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW);
break;
default:
break;
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), sw.ElapsedTicks);
}
}
sw.Stop();
}
}
catch (Exception exc)
{
lgError($"Errore in SET PzReq Commessa FANUC{Environment.NewLine}{exc}");
connectionOk = false;
}
answ = true;
}
return answ;
}
/// <summary>
/// Effettua impostazione del conteggio pezzi richiesti
/// </summary>
/// <returns></returns>
public override bool setPzComm(int pzReq)
{
bool answ = false;
// ...SE abilitato da conf IOB
if (IOBConfFull.Counters.EnableSetPzReq)
{
// scrivo valore 0 x il contapezzi
try
{
string memAddr = memAddrPzReq;
lgTrace($"INIT setPzComm | memAddr: {memAddr}");
// contapezzi ATTUALE
if (!string.IsNullOrEmpty(memAddr))
{
// verifico quale modalità sia richiesta: STD (6713) oppure BIT (Custom, con
// indicazione area)
if (memAddr.StartsWith("STD"))
{
// inizio verifica area memoria/parametro levando prima parte codice
memAddr = memAddr.Replace("STD.", "");
}
// var di appoggio
int cntAddr = 0;
// var contapezzi a zero....
object newVal = new object();
newVal = pzReq;
// verifico se si tratta di lettura parametro... formato tipo STD.PAR.6713
if (memAddr.StartsWith("PAR."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 6713;
}
// processo SET contapezzi (lavorati)
sw.Restart();
FANUC_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W{0}-PAR", 4), sw.ElapsedTicks);
}
}
else if (memAddr.StartsWith("MACRO."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
if (cntAddr == 0)
{
cntAddr = 9999;
}
lgTrace($"MACRO | Pz Write 01 | memAddr: {memAddr} | idx: {cntAddr}");
// processo SET contapezzi (lavorati)
sw.Restart();
// se > 2^16 scrivo con INT, sennò con double...
short valTrShr = 0;
double valTrDbl = 0;
if (pzReq < Math.Pow(2, 16))
{
valTrShr = (short)pzReq;
answ = FanucMemMacroRW(true, cntAddr, ref valTrShr);
//answ = FANUC_ref.F_RW_Macro_Short(true, cntAddr, ref valTrShr);
lgTrace($"MACRO | Com Write 02 SHORT | memAddr: {memAddr} | pzCnt: {pzReq} | valTrShr: {valTrShr}");
}
// sennò double!
else
{
valTrDbl = (double)pzReq;
answ = FanucMemMacroRW(true, cntAddr, ref valTrDbl);
//answ = FANUC_ref.F_RW_Macro_Double(true, cntAddr, ref valTrDbl);
lgTrace($"MACRO | Com Write 02 DOUBLE | memAddr: {memAddr} | pzCnt: {pzReq} | valTrDbl: {valTrDbl}");
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "MACRO-SHORT", sw.ElapsedTicks);
}
}
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
if (isVerboseLog)
{
lgInfo("setPzComm [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
// leggo!
sw.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
switch (areaCounter.vType)
{
case "B":
byte valB = (byte)pzReq;
FANUC_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB);
newVal = valB;
break;
case "D":
ushort valW = (ushort)pzReq;
FANUC_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW);
newVal = valW;
break;
case "DW":
uint valDW = (uint)pzReq;
FANUC_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW);
break;
default:
break;
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), sw.ElapsedTicks);
}
}
sw.Stop();
}
}
catch (Exception exc)
{
lgError($"Errore in SET PzReq Commessa FANUC{Environment.NewLine}{exc}");
connectionOk = false;
}
answ = true;
}
return answ;
}
/// <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("FANUC: ConnKO - tryConnect");
}
// in primis salvo data ping...
lastPING = DateTime.Now;
// ora PING!!!
Ping pingSender = new Ping();
IPAddress address = IPAddress.Loopback;
IPAddress.TryParse(IOBConfFull.Device.Connect.IpAddr, out address);
PingReply reply;
try
{
// se != null --> uso address...
if (address != null)
{
reply = pingSender.Send(address, 100);
}
else
{
reply = pingSender.Send(IOBConfFull.Device.Connect.IpAddr, 100);
}
}
catch
{
reply = pingSender.Send(IPAddress.Loopback, 100);
}
// se passa il ping faccio il resto...
if (reply.Status == IPStatus.Success)
{
string szStatusConnection = "";
try
{
// ora provo connessione...
parentForm.commPlcActive = true;
FANUC_ref.Connect(ref szStatusConnection);
parentForm.commPlcActive = false;
lgInfo("szStatusConnection: " + szStatusConnection);
connectionOk = true;
// refresh stato allarmi!!!
if (connectionOk)
{
checkVetoQueueIn();
dtAvvioAdp = DateTime.Now;
if (adpRunning)
{
lgInfo("Connessione OK");
}
}
else
{
lgError("Impossibile procedere, connessione mancante...");
}
}
catch (Exception exc)
{
lgFatal($"Errore nella connessione all'adapter FANUC: {szStatusConnection}{Environment.NewLine}{exc}");
connectionOk = false;
lgInfo($"Eccezione in TryConnect, Adapter NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
}
}
else
{
// loggo no risposta ping ...
connectionOk = false;
if (verboseLog || periodicLog)
{
lgInfo($"Attenzione: controllo PING fallito per IP {IOBConfFull.Device.Connect.PingIpAddr} - {reply.Status}");
}
}
}
}
// se non è ancora connesso faccio procesisng memoria caso disconnesso...
if (!connectionOk)
{
// processo semafori ed invio...
processMemoryDiscon();
}
}
/// <summary>
/// Override disconnessione
/// </summary>
public override void tryDisconnect()
{
if (connectionOk)
{
string szStatusConnection = "";
try
{
FANUC_ref.Disconnect(ref szStatusConnection);
connectionOk = false;
// resetto timing!
TimingData.resetData();
lgInfo(szStatusConnection);
lgInfo("Effettuata disconnessione adapter FANUC!");
}
catch (Exception exc)
{
lgFatal(exc, "Errore nella disconnessione dall'adapter FANUC");
}
}
else
{
lgError("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile...");
}
queueInEnabCurr = false;
}
#endregion Public Methods
#region Internal Fields
/// <summary>
/// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
/// </summary>
internal Dictionary<string, string> signLUT
{
get => IOBConfFull.Device.SigLUT;
}
#endregion Internal Fields
#region Protected Fields
/// <summary>
/// Dati dell'area D
/// </summary>
protected memAreaFanuc areaD;
/// <summary>
/// Dati dell'area PARameters
/// </summary>
protected memAreaFanuc areaPAR;
/// <summary>
/// Dati dell'area R
/// </summary>
protected memAreaFanuc areaR;
/// <summary>
/// Dati dell'area X
/// </summary>
protected memAreaFanuc areaX;
/// <summary>
/// Dati dell'area Y
/// </summary>
protected memAreaFanuc areaY;
/// <summary>
/// Oggetto MAIN x connessione FANUC
/// </summary>
protected FANUC FANUC_ref;
/// <summary>
/// Area memoria G (copia)
/// </summary>
protected byte[] MemBlockG = new byte[2];
/// <summary>
/// Area memoria R (copia)
/// </summary>
protected byte[] MemBlockR = new byte[2];
/// <summary>
/// Area memoria X (copia)
/// </summary>
protected byte[] MemBlockX = new byte[2];
/// <summary>
/// Area memoria Y (copia)
/// </summary>
protected byte[] MemBlockY = new byte[2];
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// decodifica il modo dai valori del byte G43
/// </summary>
/// <param name="currVal"></param>
/// <returns></returns>
protected static 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;
}
/// <summary>
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
/// </summary>
/// <param name="updatedPar"></param>
protected override void plcWriteParams(ref List<objItem> updatedPar)
{
lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
foreach (var item in updatedPar)
{
lgInfo($"ITEM | {item.uid} | {item.value}");
// salvo i valori ricevuti
upsertKey(item.uid, item.reqValue);
// se i valori richiesto e fatto corrispondono... resetto!
if (item.reqValue.Trim() == item.value.Trim())
{
// resetto richiesta!
item.reqValue = "";
}
}
}
#endregion Protected Methods
#region Private Properties
/// <summary>
/// Area memoria Articolo (numerico o stringa)
/// </summary>
private string memAddrArt
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setArtNum"))
{
memAddr = memMap.mMapWrite["setArtNum"].memAddr;
}
// se vuoto provo altra alternativa...
if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setArt"))
{
memAddr = memMap.mMapWrite["setArt"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.NumArtMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria cadenza
/// </summary>
private string memAddrCaden
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("Cadenza"))
{
memAddr = memMap.mMapWrite["Cadenza"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.PzCadMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria commessa
/// </summary>
private string memAddrCom
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setCommNum"))
{
memAddr = memMap.mMapWrite["setCommNum"].memAddr;
}
// se vuoto provo altra alternativa...
if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setComm"))
{
memAddr = memMap.mMapWrite["setComm"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.NumOdlMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria contapezzi (parziale/corrente)
/// </summary>
private string memAddrPzCnt
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("ContatoreParziale"))
{
memAddr = memMap.mMapWrite["ContatoreParziale"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.PzCountMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria PzCount FreeCounter
/// </summary>
private string memAddrPzCntFree
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("PzCntFree"))
{
memAddr = memMap.mMapWrite["PzCntFree"].memAddr;
}
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria contapezzi assoluto /GTot
/// </summary>
private string memAddrPzCntTot
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto"))
{
memAddr = memMap.mMapWrite["ContatoreAssoluto"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.PzTotMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria contatore pezzi richiesti
/// </summary>
private string memAddrPzReq
{
get
{
string memAddr = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setPzComm"))
{
memAddr = memMap.mMapWrite["setPzComm"].memAddr;
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memAddr))
{
memAddr = IOBConfFull.Device.PzReqMode;
}
// bonifica variabile da definizione STD iniziale...
if (memAddr.StartsWith("STD"))
{
memAddr = memAddr.Replace("STD.", "");
}
return memAddr;
}
}
/// <summary>
/// Area memoria Articolo
/// </summary>
private string memNameArt
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setArtNum"))
{
memName = "setArtNum";
}
// se vuoto provo altra alternativa...
if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setArt"))
{
memName = "setArt";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "SET_NUM_ART";
}
return memName;
}
}
private string memNameCaden
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("Cadenza"))
{
memName = "Cadenza";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "CICLE_CAD";
}
return memName;
}
}
private string memNameCom
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setCommNum"))
{
memName = "setCommNum";
}
// se vuoto provo altra alternativa...
if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setComm"))
{
memName = "setComm";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "SET_NUM_COM";
}
return memName;
}
}
private string memNamePzCnt
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("PzCntFree"))
{
memName = "PzCntFree";
}
else if (memMap.mMapWrite.ContainsKey("ContatoreParziale"))
{
memName = "ContatoreParziale";
}
else if (memMap.mMapRead.ContainsKey("PZ_COUNT"))
{
memName = "PZ_COUNT";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "PZCOUNT_MODE";
}
return memName;
}
}
private string memNamePzCntFree
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("ContatoreParziale"))
{
memName = "ContatoreParziale";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "PZ_COUNT";
}
return memName;
}
}
private string memNamePzCntTot
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto"))
{
memName = "ContatoreAssoluto";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "PZ_GTOT";
}
return memName;
}
}
private string memNamePzReq
{
get
{
string memName = "";
if (memMap != null && memMap.mMapWrite != null)
{
//cerco in primis modalità NUM altrimenti standard...
if (memMap.mMapWrite.ContainsKey("setPzComm"))
{
memName = "setPzComm";
}
}
// se non trovato... leggo da OPT_PAR
if (string.IsNullOrEmpty(memName))
{
memName = "PZ_REQ";
}
return memName;
}
}
#endregion Private Properties
#region Private Methods
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
private void decodeToBitmap()
{
// init a zero...
B_input = 0;
if (connectionOk)
{
// SE SI E' CONNESSO al FANUC allora è 1=powerON...
if (FANUC_ref.Connected)
{
B_input += 1 << 0;
}
// decodifico impiegando dictionary... cercando il TIPO di memoria & co...
string bKey = "";
string bVal = "";
// valore INVERTED (default è false)
bool invSignal = false;
int bitNum = 0;
int byte2check = 0;
for (int i = 0; i < 8; i++)
{
bKey = $"BIT{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"))
{
// procedo SOLO SE è enabled IOB
if (IobOnline)
{
try
{
currODL = utils.callUrl(urlGetCurrODL);
// solo SE HO un ODL...
if (string.IsNullOrEmpty(currODL) || currODL == "0")
{
if (periodicLog)
{
lgInfo(string.Format("Fanuc | Lettura ODL andata a vuoto: currODL: {0}", currODL));
}
}
else
{
// se variato o scaduto timeout log...
if (periodicLog || ($"{currIdxODL}" != currODL))
{
lgInfo(string.Format("Fanuc | 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;
}
}
}
else
{
// imposto currODL a vuoto!
currODL = "";
if (periodicLog)
{
lgInfo($"Fanuc | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto");
}
}
if (!string.IsNullOrEmpty(currODL) && currODL != "0")
{
// 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 (contapezziPLC != contapezziIOB)
{
// registro contapezzi
lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB {contapezziIOB}");
}
if (enablePzCountByApp)
{
// verifico se variato contapezzi...
if (contapezziPLC > contapezziIOB)
{
// salvo nuovo contapezzi (incremento di 1...) +
// richiesta refresh conteggio
contapezziIOB++;
needRefreshPzCount = true;
// salvo in semaforo!
B_input += 1 << 2;
// registro contapezzi
lgInfo($"contapezziPLC FANUC: {contapezziPLC} | contapezziIOB {contapezziIOB}");
}
// invio a server contapezzi (aggiornato)
string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString());
// verifica se tutto OK
if (retVal != contapezziIOB.ToString())
{
// errore salvataggio contapezzi
lgInfo($"Errore salvataggio Contapezzi FANUC: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}");
// rileggo il counter pezzi da server
pzCntReload(true);
}
// resetto timer...
lastPzCountSend = DateTime.Now;
}
}
}
else
{
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
{
lgInfo($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC FANUC: {contapezziPLC} | contapezziIOB {contapezziIOB}");
// resetto timer...
lastPzCountSend = DateTime.Now;
}
}
}
// altrimenti se è gestione nome prog corrente
else if (bVal.StartsWith("currPrgName"))
{
bool isMultiCond = bVal.Contains("/");
string val2Test = "";
int outVal = 0;
// in primis se ci fosse multicondizione separo...
if (isMultiCond)
{
var rawMultiCond = bVal.Split('/');
// il primo è test x programma...
val2Test = rawMultiCond[0];
// il secondo è test bit...
string sigTest = rawMultiCond[1];
// faccio test!
outVal = CalcAreaBitOut(sigTest, 0, ref byte2check, ref bitNum);
}
else
{
// test singola condizione prog name
val2Test = bVal;
}
// effettuo test del programma
int outProg = CalProgNameBitOut(val2Test, i);
// se è condizione singola o se la multi-condizion è garantita aggiungo...
if (!isMultiCond || outVal > 0)
{
// aggiungo!
B_input += outProg;
}
}
// area "normale" byte.bit
else
{
invSignal = false;
// cerco se sia inverse (primo char "!") --> registro e elimino char...
invSignal = bVal.StartsWith("!");
// se è da tracciare...
if (mem2trace.Contains($"|{bKey}|"))
{
if (invSignal)
{
lgTrace($"Segnale invertito | bVal: {bVal}");
}
}
int outCalc = CalcAreaBitOut(bVal, i, ref byte2check, ref bitNum);
// aggiungo!
B_input += outCalc;
// se è da tracciare...
if (mem2trace.Contains($"|{bKey}|"))
{
var bMapAct = Convert.ToString(byte2check, 2).PadLeft(8, '0');
var bMapReq = Convert.ToString((1 << bitNum), 2).PadLeft(8, '0');
lgTrace($"Valore | bKey: {bKey} | bVal: {bVal} | byte: {bMapAct} | tgt: {bMapReq} | B_input: {B_input}");
}
}
}
}
}
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
}
}
/// <summary>
/// Calcola valore bitmap segnale in uscita data condizione programName
/// </summary>
/// <param name="confTest">Conf search programma: nome e se inizia per % ricerca LIKE</param>
/// <param name="i">Indice del bit x calcolo out</param>
private int CalProgNameBitOut(string confTest, int i)
{
// OUT valore
int outVal = 0;
string prgNameTgt = "";
// il valore da cercare è quello inserito dopo il segno pipe...
if (confTest.Contains("|"))
{
var prgData = confTest.Split('|');
if (prgData.Length > 1)
{
prgNameTgt = prgData[1];
}
}
// ora verifico se prog corrente è valido
if (!string.IsNullOrEmpty(currPrgName))
{
// se contiene % allora cerco x like
if (prgNameTgt.Contains("%"))
{
// e se sia uguale al valore tgt senza %
if (currPrgName.Contains(prgNameTgt.Replace("%", "")))
{
// inserisco bit!
outVal += 1 << i;
}
}
// altrimenti ricerca puntuale (prima versione)
else
{
// e se sia uguale al valore tgt
if (currPrgName == prgNameTgt)
{
// inserisco bit!
outVal += 1 << i;
}
}
}
return outVal;
}
/// <summary>
/// Calcola il valore bitmap segnale in uscita data la bVal (mem area + bit) + indice i
/// </summary>
/// <param name="bVal">Conf memoria da signalLUT</param>
/// <param name="i">Indice del bit x calcolo out</param>
/// <param name="byte2check">Byte completo recuperato</param>
/// <param name="bitNum">Indice bit cercato</param>
/// <returns></returns>
private int CalcAreaBitOut(string bVal, int i, ref int byte2check, ref int bitNum)
{
// OUT valore
int outVal = 0;
// var accessorie
int byteNum = 0;
bool invSignal = false;
char area;
string memArea = "";
string[] memIdx;
// di norma è segnale normale => 1, altrimenti inverse => 0...
// cerco se sia inverse (primo char "!") --> registro e elimino char...
invSignal = bVal.StartsWith("!");
// tolgo comunque inversione...
bVal = bVal.Replace("!", "");
// recupero area...
area = bVal[0];
// altrimenti decodifico area...
memArea = bVal.Substring(1, bVal.Length - 1);
memIdx = memArea.Split('.');
// calcolo bit e byte number...
int.TryParse(memIdx[0], out byteNum);
if (memIdx.Length > 1)
{
int.TryParse(memIdx[1], out bitNum);
}
// in base al nome cerco in una delle aree.. e prendo solo solo quel bit
// di quel byte...
switch (area)
{
case 'G':
byte2check = MemBlockG[byteNum];
break;
case 'R':
byte2check = MemBlockR[byteNum];
break;
case 'X':
byte2check = MemBlockX[byteNum];
break;
case 'Y':
byte2check = MemBlockY[byteNum];
break;
default:
break;
}
// a secondo che sia segnale normale o inverso...
if (invSignal)
{
// controllo se il bit sia NON attivo (basso)... == 0...
if ((byte2check & (1 << bitNum)) == 0)
{
outVal += 1 << i;
}
}
else
{
// controllo se il bit sia attivo (alto)... != 0
if ((byte2check & (1 << bitNum)) != 0)
{
outVal += 1 << i;
}
}
return outVal;
}
/// <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);
}
sw.Restart();
FanucMemRW(R, tipoMem, memIndex, ref MemBlockCurr);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-{1}", MemBlockCurr.Length, tipoMem), sw.ElapsedTicks);
}
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, IOBConfFull.General.CodIOB, tipoMem, adesso);
nomeFileW = string.Format(@"{0}\SAMPLES\{1}_{2}_W_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, IOBConfFull.General.CodIOB, tipoMem, adesso);
nomeFileDW = string.Format(@"{0}\SAMPLES\{1}_{2}_DW_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, IOBConfFull.General.CodIOB, tipoMem, adesso);
}
else
{
// salvo in file i dati letti come BYTE
nomeFileB = string.Format(@"{0}\{1}_{2}_Byte.dat", utils.dataDatDir, IOBConfFull.General.CodIOB, tipoMem);
nomeFileW = string.Format(@"{0}\{1}_{2}_W.dat", utils.dataDatDir, IOBConfFull.General.CodIOB, tipoMem);
nomeFileDW = string.Format(@"{0}\{1}_{2}_DW.dat", utils.dataDatDir, IOBConfFull.General.CodIOB, tipoMem);
}
// salvo in file i dati letti come BYTE
mappaValori = new Dictionary<string, string>();
for (int i = 0; i < MemBlockCurr.Length; i++)
{
// versione pre dotNet8 (che usa "b" come stringa formato std)
var bitMap = Convert.ToString(MemBlockCurr[i], 2).PadLeft(8, '0');
mappaValori.Add($"[{i:0000}]", $"{bitMap}={MemBlockCurr[i]}");
//mappaValori.Add($"[{i:0000}]", $"{MemBlockCurr[i]:b}={MemBlockCurr[i]}");
}
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: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: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");
}
sw.Restart();
for (int i = 0; i < numPar; i++)
{
FANUC_ref.F_RW_Param_Integer(false, memIndex + i, 3, ref paramsArray[i]);
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-PAR", 4 * numPar), sw.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, IOBConfFull.General.CodIOB, "PAR", adesso);
}
else
{
nomeFile = string.Format(@"{0}\{1}_{2}.dat", utils.dataDatDir, IOBConfFull.General.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);
}
/// <summary>
/// Recupera il valore INT dal nome del parametro per successivo processing
/// </summary>
/// <param name="varName"></param>
/// <returns></returns>
private string getValByMemAddr(string memAddr)
{
lgTrace($"inizio getValByMemAddr | memAddr: {memAddr}");
string answ = "";
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
if (memAddr.StartsWith("STD"))
{
// inizio verifica area memoria/parametro levando prima parte codice
memAddr = memAddr.Replace("STD.", "");
}
// var di appoggio
int cntAddr = 0;
object outputVal = new object();
// verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
if (memAddr.StartsWith("PAR."))
{
// recupero parametro...
int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
// processo parametro
sw.Restart();
FANUC_ref.F_RW_Param_Integer(false, cntAddr, 3, ref outputVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R{0}-PAR", 4), sw.ElapsedTicks);
}
// salvo valore
answ = outputVal.ToString();
}
// 2022.05.23 gestione MACRO da testare (Jetco)
else if (memAddr.StartsWith("MACRO."))
{
double macroVal = 0;
// recupero parametro...
int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
lgTrace($"MACRO | Read 01 | memAddr: {memAddr} | idx: {cntAddr} | macroVal: {macroVal}");
// processo parametro
sw.Restart();
FANUC_ref.F_Read_macro(cntAddr, ref macroVal);
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, "R-MACRO", sw.ElapsedTicks);
}
// salvo valore
answ = macroVal.ToString();
lgTrace($"MACRO | Read 02 | memAddr: {memAddr} | idx: {cntAddr} | macroVal: {macroVal}");
}
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
if (isVerboseLog)
{
lgInfo("getValByParam [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
// leggo!
sw.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
switch (areaCounter.vType)
{
case "B":
byte valB = 0;
FANUC_ref.F_RW_Byte(false, areaCounter.mType, areaCounter.mPos, ref valB);
outputVal = valB;
break;
case "D":
ushort valW = 0;
FANUC_ref.F_RW_Word(false, areaCounter.mType, areaCounter.mPos, ref valW);
outputVal = valW;
break;
case "DW":
uint valDW = 0;
FANUC_ref.F_RW_DWord(false, areaCounter.mType, areaCounter.mPos, ref valDW);
if (isVerboseLog)
{
lgInfo("[1] valDW PAR: {0}", valDW);
}
outputVal = valDW;
if (isVerboseLog)
{
lgInfo("[2] outputVal PAR: {0}", outputVal);
}
break;
default:
break;
}
if (utils.CRB("recTime"))
{
TimingData.addResult(IOBConfFull.General.CodIOB, string.Format("R-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), sw.ElapsedTicks);
}
// salvo...
answ = outputVal.ToString();
if (isVerboseLog)
{
lgInfo($"[3] Mem letta: {memAddr} | {answ}");
}
}
sw.Stop();
return answ;
}
#endregion Private Methods
}
}