Files
Mapo-IOB-WIN/IOB-WIN/IobMTC.cs
T
Samuele E. Locatelli 3862c507c3 Ok anche recupero dati...
2019-11-16 10:55:54 +01:00

494 lines
14 KiB
C#

using IOB_UT;
using MapoSDK;
using MTConnect.Clients;
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using MTConnectDevices = MTConnect.MTConnectDevices;
using MTConnectStreams = MTConnect.MTConnectStreams;
namespace IOB_WIN
{
public class IobMTC : IobGeneric
{
/// <summary>
/// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
/// </summary>
Dictionary<string, string> signLUT = new Dictionary<string, string>();
/// <summary>
/// Oggetto MAIN x connessione MTC
/// </summary>
protected MTConnectClient MTC_ref;
/// <summary>
/// Estende l'init della classe base, impiegando il pacchetto Nuget TrackHound
/// https://github.com/TrakHound/MTConnect.NET
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public IobMTC(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
// gestione invio ritardato contapezzi
pzCountDelay = utils.CRI("pzCountDelay");
lastPzCountSend = DateTime.Now;
lastWarnODL = DateTime.Now;
}
/// <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)
{
// uso metodo base x ora
return base.executeTasks(task2exe);
}
/// <summary>
/// Effettua reset del contapezzi, in questo caso il conteggio dei KG
/// </summary>
/// <returns></returns>
public override bool resetContapezziCNC()
{
bool answ = false;
#if false
// ...SE abilitato da conf IOB
if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
{
// scrivo valore 0 x il contapezzi
try
{
pzCounter = 0;
}
catch (Exception exc)
{
lgError(exc, "Errore in RESET contapezzi MTC");
connectionOk = false;
}
answ = true;
}
else
{
lgError("Impossibile effettuare RESET contapezzi MTC, mancanza parametro OPT:ENABLE_PZ_RESET");
}
#endif
return answ;
}
/// <summary>
/// Effettua IMPOSTAZIONE FORZATA del contapezzi, in questo caso il conteggio dei KG
/// </summary>
/// <returns></returns>
public override bool setContapezziCNC(int newPzCount)
{
bool answ = false;
#if false
// ...SE abilitato da conf IOB
if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
{
// scrivo valore 0 x il contapezzi
try
{
pzCounter = newPzCount;
}
catch (Exception exc)
{
lgError(exc, "Errore in SET contapezzi MTC");
connectionOk = false;
}
answ = true;
}
else
{
lgError("Impossibile effettuare SET contapezzi MTC, mancanza parametro OPT:ENABLE_PZ_RESET");
}
#endif
return answ;
}
/// <summary>
/// Vera connessione ad MTC
/// </summary>
/// <returns></returns>
private short doConnect()
{
short esitoLink = 0;
// avvio un oggetto di comunicazione MTC
#if false
MTC_ref = new MTConnectClient($"http://{cIobConf.cncIpAddr}:{port}");
#endif
short port = 5000;
short.TryParse(cIobConf.cncPort, out port);
// test probe!
try
{
var probe = new Probe($"http://{cIobConf.cncIpAddr}:{port}").Execute();
}
catch
{ }
// ora avvio
try
{
lgInfo($"Chiamata apertura MTC Client: {cIobConf.cncIpAddr}:{port}");
MTC_ref = new MTConnectClient($"http://{cIobConf.cncIpAddr}:{port}");
// Subscribe to the Event handlers to receive the MTConnect documents
MTC_ref.ProbeReceived += DevicesSuccessful;
MTC_ref.CurrentReceived += StreamsSuccessful;
MTC_ref.SampleReceived += StreamsSuccessful;
MTC_ref.Start();
esitoLink = 1;
}
catch
{ }
return esitoLink;
}
void DevicesSuccessful(MTConnectDevices.Document document)
{
foreach (var device in document.Devices)
{
var dataItems = device.GetDataItems();
foreach (var dataItem in dataItems) Console.WriteLine(dataItem.Id + " : " + dataItem.Name);
}
}
void StreamsSuccessful(MTConnectStreams.Document document)
{
foreach (var deviceStream in document.DeviceStreams)
{
foreach (var dataItem in deviceStream.DataItems) Console.WriteLine(dataItem.DataItemId + " = " + dataItem.CDATA);
}
}
/// <summary>
/// Override disconnessione
/// </summary>
public override void tryDisconnect()
{
if (connectionOk)
{
string szStatusConnection = "";
try
{
MTC_ref.Stop();
connectionOk = false;
lgInfo(szStatusConnection);
lgInfo("Effettuata disconnessione adapter MTC!");
}
catch (Exception exc)
{
lgFatal(exc, "Errore nella disconnessione dall'adapter MTC");
}
}
else
{
lgError("IMPOSSIBILE effettuare disconnessione MTC: 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("MTC: ConnKO - tryConnect");
}
// in primis salvo data ping...
lastPING = DateTime.Now;
// se passa il ping faccio il resto...
if (testPing == IPStatus.Success)
{
string szStatusConnection = "";
try
{
// ora provo connessione...
parentForm.commPlcActive = true;
short esitoLink = doConnect();
lgInfo($"szStatusConnection MTC, esitoLink: {esitoLink}");
parentForm.commPlcActive = false;
connectionOk = true;
// refresh stato allarmi!!!
if (connectionOk)
{
if (adpRunning)
{
// carico status allarmi (completo)
lgInfo("Inizio refresh completo stato allarmi...");
forceAlarmCheck();
lgInfo("Completato refresh completo stato allarmi!");
}
else
{
lgInfo("Connessione OK");
}
}
else
{
lgError("Impossibile procedere, connessione mancante...");
}
}
catch (Exception exc)
{
lgFatal($"Errore nella connessione all'adapter MTC: {szStatusConnection}{Environment.NewLine}{exc}");
connectionOk = false;
lgInfo($"Eccezione in TryConnect, Adapter MTC 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: MTC controllo PING fallito per IP {cIobConf.cncIpAddr}");
}
}
}
}
else
{
needRefresh = true;
}
// se non è ancora connesso faccio procesisng memoria caso disconnesso...
if (!connectionOk)
{
// processo semafori ed invio...
processMemoryDiscon();
}
}
#region Metodi specifici (da verificare/completare in implementazione)
/// <summary>
/// controllo allarmi
/// </summary>
public override void forceAlarmCheck()
{
// controllo tutta la memoria allarmi SE richiesto
}
/// <summary>
/// Effettua vero processing contapezzi
/// </summary>
public override void processContapezzi()
{
if (utils.CRB("enableContapezzi"))
{
#if false
try
{
// hard coded... !!!FARE!!! rivedere megio conf
lastCountCNC = pzCounter;
// verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
if (cIobConf.optPar.Count > 0 && getOptPar("PZCOUNT_MODE") != "")
{
}
}
catch (Exception exc)
{
lgError(exc, "Errore in contapezzi MTC");
}
#endif
}
}
/// <summary>
/// Effettua lettura semafori principale
/// <paramref name="currDispData">Parametri da aggiornare x display in form</paramref>
/// </summary>
public override void readSemafori(ref newDisplayData currDispData)
{
base.readSemafori(ref currDispData);
try
{
if (verboseLog)
{
lgInfo("inizio read semafori");
}
currDispData.semIn = Semaforo.SV;
#if false
// effettuo TUTTE le letture
MTC_ref.ReadWords(MTCFinsTCP.Net.PlcMemory.CIO, 0, 60, out memReadCIO_IN);
MTC_ref.ReadWords(MTCFinsTCP.Net.PlcMemory.CIO, 100, 10, out memReadCIO_OUT);
//MTC_ref.ReadWords(MTCFinsTCP.Net.PlcMemory.DM, 0, 8, out memReadDM);
//MTC_ref.ReadWords(MTCFinsTCP.Net.PlcMemory.WR, 0, 8, out memReadWR);
lastCountCNC = pesoRilevato;
#endif
// decodifica e gestione
decodeToBaseBitmap();
reportRawInput(ref currDispData);
}
catch
{
currDispData.semIn = Semaforo.SR;
}
}
/// <summary>
/// Verifico se abbia ALMENO un errore...
/// </summary>
protected bool hasError
{
get
{
bool answ = false;
//!!! fare con check su conditions
return answ;
}
}
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
private void decodeToBaseBitmap()
{
// init a zero...
B_input = 0;
/* -----------------------------------------------------
* bitmap MAPO
* B0: POWER_ON
* B1: RUN
* B2: pzCount
* B3: allarme
* B4: manuale
* B5: carico SILOS
* B6: carico AUTOBOTTE
----------------------------------------------------- */
// bit 0 (poweron) imposto a 1 SE pingo...
B_input = testPing == IPStatus.Success ? 1 : 0;
#if false
bool caricoSilos = ((memReadCIO_IN[55] & (1 << 2)) != 0);
bool caricoAutobotte = ((memReadCIO_IN[50] & (1 << 2)) != 0);
// filtro DEVE ANDARE ma VIENE RILEVATO DOPO, POTREBEB andare da solo x scaricare...
bool runFiltro = ((memReadCIO_IN[0] & (1 << 1)) != 0);
// RUN se CIO_bit 0.01 è RUN FILTRO...
if ((caricoAutobotte || caricoSilos))
{
// SE HO carico silos OPPURE carico autobotte --> RUN
B_input += (1 << 1);
}
// ERROR generale (CORREGGERE!)
if (hasError)
{
B_input += (1 << 3);
}
// carico SILOS
if (caricoSilos)
{
B_input += (1 << 5);
}
// carico AUTOBOTTE
if (caricoAutobotte)
{
B_input += (1 << 6);
}
// process ODL e contapezzi
string currODL = "";
try
{
currODL = utils.callUrl(urlGetCurrODL);
// solo SE HO un ODL...
if (currODL == "" || currODL == "0")
{
if (periodicLog)
{
lgInfo(string.Format("MTC | Lettura ODL andata a vuoto: currODL: {0}", currODL));
}
}
else
{
// se variato o scaduto timeout log...
if (periodicLog || (currIdxODL.ToString() != currODL))
{
lgInfo(string.Format("MTC | 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;
}
}
#endif
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
}
}
/// <summary>
/// Recupero dati dinamici...
/// </summary>
public override Dictionary<string, string> getDynData()
{
// valore non presente in vers default... se gestito fare override
Dictionary<string, string> outVal = new Dictionary<string, string>();
#if false
outVal.Add("kgAct", pesoRilevato.ToString());
outVal.Add("kgImp", pesoRichiesto.ToString());
#endif
return outVal;
}
/// <summary>
/// OVerride metodo x scrittura parametri su PLC
/// </summary>
/// <param name="updatedPar"></param>
protected override void plcWriteParams(List<objItem> updatedPar)
{
int valInt = 0;
if (updatedPar != null)
{
// controllo i parametri... ne gestisco 4...
foreach (var item in updatedPar)
{
#if false
switch (item.uid)
{
case "kgRich":
int.TryParse(item.reqValue, out valInt);
pesoRichiesto = valInt;
break;
case "kgLotto":
int.TryParse(item.reqValue, out valInt);
quantitaLotto = valInt;
break;
case "portata":
int.TryParse(item.reqValue, out valInt);
portata = valInt;
break;
case "setComm":
commessa = item.reqValue;
break;
default:
break;
}
#endif
}
}
}
#endregion
}
}