Bozza adapter REST x Citizen

This commit is contained in:
Samuele Locatelli
2024-11-11 19:57:49 +01:00
parent 3cb7040609
commit 6770ab73d0
2 changed files with 715 additions and 407 deletions
+353 -369
View File
@@ -39,41 +39,6 @@ namespace IOB_WIN_NEXT.IobRest
}
}
protected void setupRestConf(string restConfFile)
{
// se ho file specifico
if (!string.IsNullOrEmpty(getOptJsonKVP("REST_CONF")))
{
string rawData = "";
// leggo file e decodifico...
string confPath = $"{Application.StartupPath}/DATA/CONF/{restConfFile}";
lgInfo($"Apertura file {confPath}");
using (StreamReader sr = new StreamReader(confPath))
{
rawData = sr.ReadToEnd().Replace("\n", "").Replace("\r", "");
}
// continuo decodifica
if (!string.IsNullOrEmpty(rawData))
{
restParams = JsonConvert.DeserializeObject<RestParamConf>(rawData);
if (restParams != null)
{
// inizializzo dal file di conf le variabili necessarie...
tOutSec = restParams.timeOutSec;
apiUrl = restParams.apiUrl ?? "http://localhost:8733";
}
}
}
// sistemo conf standard x call REST
restOptStd = new RestClientOptions
{
Timeout = TimeSpan.FromSeconds(tOutSec),
BaseUrl = new Uri(apiUrl)
};
}
#endregion Public Constructors
#region Public Methods
@@ -233,7 +198,7 @@ namespace IOB_WIN_NEXT.IobRest
}
/// <summary>
/// Effettua lettura semafori principale
/// Effettua lettura semafori principale
/// <paramref name="currDispData">Parametri da aggiornare x display in form</paramref>
/// </summary>
public override void readSemafori(ref newDisplayData currDispData)
@@ -251,8 +216,10 @@ namespace IOB_WIN_NEXT.IobRest
}
currDispData.semIn = Semaforo.SV;
// effettua refresh dati da leggere SPECIFICi x citizen...
refreshData();
// decodifica e gestione
decodeToBaseBitmap();
decodeToBaseBitmap(ref currDispData);
// display
reportRawInput(ref currDispData);
}
@@ -267,22 +234,363 @@ namespace IOB_WIN_NEXT.IobRest
lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}");
checkVetoQueueIn();
}
}
/// <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("Rest: ConnKO - tryConnect");
}
// in primis salvo data ping...
lastPING = DateTime.Now;
// se passa il ping faccio il resto...
if (testPingMachine == IPStatus.Success)
{
string szStatusConnection = "";
try
{
// ora provo connessione...
parentForm.commPlcActive = true;
// chiamo metodo connect
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"));
// forse va eliminato...
lgInfo($"GetConnection | {checkResp}");
if (checkResp != null && checkResp.ToLower().Contains("true"))
{
connectionOk = true;
}
else
{
lgError($"Errore check connessione | checkResp: {checkResp}");
}
// refresh stato connessione!!!
if (connectionOk)
{
queueInEnabCurr = true;
if (adpRunning)
{
lgInfo("Connessione OK");
}
}
else
{
lgError("Impossibile procedere, connessione mancante...");
}
}
catch (Exception exc)
{
lgFatal($"Errore nella connessione all'Adapter IobRest.Base: {szStatusConnection}{Environment.NewLine}{exc}");
connectionOk = false;
lgInfo($"Eccezione in TryConnect, Adapter IobRest.Base 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: Rest controllo PING fallito per IP {cIobConf.cncPingAddr}");
}
}
}
}
else
{
needRefresh = true;
}
}
public override void tryDisconnect()
{
// registro solo che è disconnesso
connectionOk = false;
queueInEnabCurr = false;
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// Api Url di base x chiamate REST
/// </summary>
protected string apiUrl = "http://localhost:8733";
/// <summary>
/// Timeout chiamate REST
/// </summary>
protected int tOutSec = 60;
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Parametri specifici Client Rest
/// </summary>
protected RestParamConf restParams { get; set; } = new RestParamConf();
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// verifica stato ok ovvero connected oppure open
/// </summary>
/// <param name="currState"></param>
/// <returns></returns>
protected bool checkStateOk(System.ServiceModel.CommunicationState currState)
{
bool answ = false;
#if false
answ == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created;
#endif
return answ;
}
/// <summary>
/// Esecuzione chiamata Rest tipo GET
/// </summary>
/// <param name="resource"></param>
/// <returns></returns>
protected string ExecuteCallGet(string resource)
{
string answ = "";
if (!string.IsNullOrEmpty(resource))
{
// client chiamate rest
using (var client = new RestClient(restOptStd))
{
var currReq = new RestRequest(resource, Method.Get);
currReq.AddHeader("Content-type", "application/json");
// effettuo vera chiamata
var currResp = client.Get(currReq);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
answ = currResp.Content ?? "";
}
}
}
return answ;
}
/// <summary>
/// restituisce URL della risorsa eventualmente completato con token o altro
/// </summary>
/// <param name="resName"></param>
/// <returns></returns>
protected string GetUrlResource(string resName)
{
string answ = "";
if (restParams != null && restParams.CallList != null && restParams.CallList.Count > 0)
{
if (restParams.CallList.ContainsKey(resName))
{
answ = restParams.CallList[resName].Url;
// eseguo eventuale sostituzione (se trovo "[[")
if (answ.Contains("[["))
{
string pattern = @"\[\[.*\]\]";
Regex regex = new Regex(pattern);
Match match = regex.Match(resName);
if (match.Success)
{
string key = match.Value.Replace("[[", "").Replace("]]", "");
// cerco nella LUT...
if (RestDataLUT.ContainsKey(key))
{
// sostituisco!
answ = answ.Replace($"[[{key}]]", RestDataLUT[key]);
}
}
}
}
}
return answ;
}
/// <summary>
/// Upsert in cache LUT del parametro
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected void RestLutUpsert(string key, string value)
{
if (RestDataLUT.ContainsKey(key))
{
RestDataLUT[key] = value;
}
else
{
RestDataLUT.Add(key, value);
}
}
/// <summary>
/// Recupero valore da cache LUT
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected string RestLutGet(string key)
{
string value = "";
if (RestDataLUT.ContainsKey(key))
{
value = RestDataLUT[key];
}
return value;
}
/// <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 di setup x prox pesata...
upsertKey(item.uid, item.value);
#if false
bool fatto = false;
bool isPesata = false;
bool isIN = false;
gestWeightOut answ = new gestWeightOut();
// se è richiesta pesata IN/OUT --> mando chiamata
if (item.uid == "reqPesata")
{
isPesata = true;
isIN = item.reqValue.ToUpper() == "IN";
//isIN = item.value.ToUpper() == "IN";
try
{
answ = reqWeight(isIN);
}
catch (Exception exc)
{
lgError($"Eccezione in plcWriteParams.reqWeight | isIn: {isIN}{Environment.NewLine}{exc}");
}
}
else if (item.uid == "RM" || item.uid.StartsWith("Cod"))
{
// comunque segno fatto x altri casi
fatto = true;
}
// se è pesata...
if (isPesata)
{
// se è OK
if (answ.feedback == "C")
{
lgInfo($"reqWeight | Effettuato richiesta | {answ.feedback} | {answ.notes}");
// resetto pesata
upsertKey(item.uid, "");
}
else
{
lgError($"reqWeight | Errore in richiesta peso Rest | {answ.feedback} | {answ.notes}");
}
item.value = "";
item.reqValue = "";
item.lastRead = DateTime.Now;
item.UM = "";
// salvo esito richiesta comunque
upsertKey("logReq", $"{answ.feedback} | {answ.notes}");
// faccio in modo di eseguire subito getDynData
demFactDynData = 1;
processDynData();
}
else
{
// se fatto --> aggiorno!
if (fatto)
{
//item.value = item.reqValue;
item.reqValue = "";
item.lastRead = DateTime.Now;
item.UM = "";
}
}
#endif
}
}
protected void setupRestConf(string restConfFile)
{
// se ho file specifico
if (!string.IsNullOrEmpty(getOptJsonKVP("REST_CONF")))
{
string rawData = "";
// leggo file e decodifico...
string confPath = $"{Application.StartupPath}/DATA/CONF/{restConfFile}";
lgInfo($"Apertura file {confPath}");
using (StreamReader sr = new StreamReader(confPath))
{
rawData = sr.ReadToEnd().Replace("\n", "").Replace("\r", "");
}
// continuo decodifica
if (!string.IsNullOrEmpty(rawData))
{
restParams = JsonConvert.DeserializeObject<RestParamConf>(rawData);
if (restParams != null)
{
// inizializzo dal file di conf le variabili necessarie...
tOutSec = restParams.timeOutSec;
apiUrl = restParams.apiUrl ?? "http://localhost:8733";
}
}
}
// sistemo conf standard x call REST
restOptStd = new RestClientOptions
{
Timeout = TimeSpan.FromSeconds(tOutSec),
BaseUrl = new Uri(apiUrl)
};
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// LookUpTable informazioni raccolte
/// </summary>
protected Dictionary<string, string> RestDataLUT = new Dictionary<string, string>();
/// <summary>
/// Conf client RestSharp standard:
/// - timeout 1 min
/// </summary>
private RestClientOptions restOptStd = new RestClientOptions { Timeout = TimeSpan.FromSeconds(60) };
#endregion Private Fields
#region Private Methods
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
private void decodeToBaseBitmap()
protected virtual void decodeToBaseBitmap(ref newDisplayData currDispData)
{
// init a zero...
B_input = 0;
if (queueInEnabCurr)
{
/* -----------------------------------------------------
* bitmap MAPO STD 60
* bitmap MAPO STD 60
* B0: POWER_ON
* B1: RUN
* B2: pzCount
@@ -295,8 +603,6 @@ namespace IOB_WIN_NEXT.IobRest
// per prima cosa controllo ping e se sia connesso...
#if false
if (connectionOk)
{
@@ -432,7 +738,7 @@ namespace IOB_WIN_NEXT.IobRest
if (verboseLog)
{
lgInfo($"Trasformazione B_input: {B_input} | currRun = {currRun}");
}
}
#endif
}
else
@@ -442,333 +748,11 @@ namespace IOB_WIN_NEXT.IobRest
}
/// <summary>
/// Esecuzione chiamata Rest tipo GET
/// Esegue lettura dati + salvataggio in LUT
/// </summary>
/// <param name="resource"></param>
/// <returns></returns>
protected string ExecuteCallGet(string resource)
{
string answ = "";
if (!string.IsNullOrEmpty(resource))
{
// client chiamate rest
using (var client = new RestClient(restOptStd))
{
var currReq = new RestRequest(resource, Method.Get);
currReq.AddHeader("Content-type", "application/json");
// effettuo vera chiamata
var currResp = client.Get(currReq);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
answ = $"{currResp.Content}";
}
}
}
return answ;
}
/// <summary>
/// LookUpTable informazioni raccolte
/// </summary>
protected Dictionary<string, string> dataLUT = new Dictionary<string, string>();
/// <summary>
/// restituisce URL della risorsa eventualmente completato con token o altro
/// </summary>
/// <param name="resName"></param>
/// <returns></returns>
protected string GetUrlResource(string resName)
{
string answ = "";
if (restParams != null && restParams.CallList != null && restParams.CallList.Count > 0)
{
if (restParams.CallList.ContainsKey(resName))
{
answ = restParams.CallList[resName].Url;
// eseguo eventuale sostituzione (se trovo "[[")
if (answ.Contains("[["))
{
string pattern = @"\[\[.*\]\]";
Regex regex = new Regex(pattern);
Match match = regex.Match(resName);
if (match.Success)
{
string key = match.Value.Replace("[[", "").Replace("]]", "");
// cerco nella LUT...
if (dataLUT.ContainsKey(key))
{
// sostituisco!
answ = answ.Replace($"[[{key}]]", dataLUT[key]);
}
}
}
}
}
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("Rest: ConnKO - tryConnect");
}
// in primis salvo data ping...
lastPING = DateTime.Now;
// se passa il ping faccio il resto...
if (testPingMachine == IPStatus.Success)
{
string szStatusConnection = "";
try
{
// ora provo connessione...
parentForm.commPlcActive = true;
// chiamo metodo connect
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"));
// forse va eliminato...
lgInfo($"GetConnection | {checkResp}");
if (checkResp != null && checkResp.ToLower().Contains("true"))
{
connectionOk = true;
}
else
{
lgError($"Errore check connessione | checkResp: {checkResp}");
}
// refresh stato connessione!!!
if (connectionOk)
{
queueInEnabCurr = true;
if (adpRunning)
{
lgInfo("Connessione OK");
}
}
else
{
lgError("Impossibile procedere, connessione mancante...");
}
}
catch (Exception exc)
{
lgFatal($"Errore nella connessione all'Adapter IobRest.Base: {szStatusConnection}{Environment.NewLine}{exc}");
connectionOk = false;
lgInfo($"Eccezione in TryConnect, Adapter IobRest.Base 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: Rest controllo PING fallito per IP {cIobConf.cncPingAddr}");
}
}
}
}
else
{
needRefresh = true;
}
}
public override void tryDisconnect()
{
// registro solo che è disconnesso
connectionOk = false;
queueInEnabCurr = false;
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// Api Url di base x chiamate REST
/// </summary>
protected string apiUrl = "http://localhost:8733";
/// <summary>
/// Timeout chiamate REST
/// </summary>
protected int tOutSec = 60;
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// verifica stato ok ovvero connected oppure open
/// </summary>
/// <param name="currState"></param>
/// <returns></returns>
protected bool checkStateOk(System.ServiceModel.CommunicationState currState)
{
bool answ = false;
#if false
answ == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created;
#endif
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 di setup x prox pesata...
upsertKey(item.uid, item.value);
#if false
bool fatto = false;
bool isPesata = false;
bool isIN = false;
gestWeightOut answ = new gestWeightOut();
// se è richiesta pesata IN/OUT --> mando chiamata
if (item.uid == "reqPesata")
{
isPesata = true;
isIN = item.reqValue.ToUpper() == "IN";
//isIN = item.value.ToUpper() == "IN";
try
{
answ = reqWeight(isIN);
}
catch (Exception exc)
{
lgError($"Eccezione in plcWriteParams.reqWeight | isIn: {isIN}{Environment.NewLine}{exc}");
}
}
else if (item.uid == "RM" || item.uid.StartsWith("Cod"))
{
// comunque segno fatto x altri casi
fatto = true;
}
// se è pesata...
if (isPesata)
{
// se è OK
if (answ.feedback == "C")
{
lgInfo($"reqWeight | Effettuato richiesta | {answ.feedback} | {answ.notes}");
// resetto pesata
upsertKey(item.uid, "");
}
else
{
lgError($"reqWeight | Errore in richiesta peso Rest | {answ.feedback} | {answ.notes}");
}
item.value = "";
item.reqValue = "";
item.lastRead = DateTime.Now;
item.UM = "";
// salvo esito richiesta comunque
upsertKey("logReq", $"{answ.feedback} | {answ.notes}");
// faccio in modo di eseguire subito getDynData
demFactDynData = 1;
processDynData();
}
else
{
// se fatto --> aggiorno!
if (fatto)
{
//item.value = item.reqValue;
item.reqValue = "";
item.lastRead = DateTime.Now;
item.UM = "";
}
}
#endif
}
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// Conf client RestSharp standard:
/// - timeout 1 min
/// </summary>
private RestClientOptions restOptStd = new RestClientOptions { Timeout = TimeSpan.FromSeconds(60) };
#endregion Private Fields
#if false
/// <summary>
/// Esegue richiesta PESO
/// </summary>
/// <param name="reqIN">Tipo richiesta: IN (true) / OUT (false)</param>
/// <returns></returns>
protected gestWeightOut reqWeight(bool reqIN)
{
lgInfo($"reqWeight | IN: {reqIN}");
gestWeightOut answ = null;
try
{
Stopwatch sw = new Stopwatch();
sw.Start();
// preparo parametri
string tipoRic = reqIN ? "IN" : "OUT";
string rm = getCurrProdData("RM", $"{DateTime.Now:yyyyMMdd-HHmmss}");// string.IsNullOrEmpty(currProdData["RM"]) ? $"{DateTime.Now:yyyyMMdd-HHmmss}" : currProdData["RM"];
string Cod1 = getCurrProdData("Cod1", ""); //string.IsNullOrEmpty(currProdData["Cod1"]) ? "" : currProdData["Cod1"];
string Cod2 = getCurrProdData("Cod2", ""); //string.IsNullOrEmpty(currProdData["Cod2"]) ? "" : currProdData["Cod2"];
string Cod3 = getCurrProdData("Cod3", ""); //string.IsNullOrEmpty(currProdData["Cod3"]) ? "" : currProdData["Cod3"];
string Cod4 = getCurrProdData("Cod4", ""); //string.IsNullOrEmpty(currProdData["Cod4"]) ? "" : currProdData["Cod4"];
string Cod5 = getCurrProdData("Cod5", ""); //string.IsNullOrEmpty(currProdData["Cod5"]) ? "" : currProdData["Cod5"];
string Cod6 = getCurrProdData("Cod6", ""); //string.IsNullOrEmpty(currProdData["Cod6"]) ? "" : currProdData["Cod6"];
// faccio chiamata
answ = RestConn.memWeight(tipoRic, rm, Cod1, Cod2, Cod3, Cod4, Cod5, Cod6);
sw.Stop();
lgInfo($"reqWeight: effettuata chiamata SOAP in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}");
}
catch (Exception exc)
{
lgError($"reqWeight | errore richiesta pesatura{Environment.NewLine}{exc}");
}
return answ;
}
protected void SavePesata(ref Dictionary<string, string> currDict, WeightRec newRec)
{
DictUpsert(ref currDict, "RM", newRec.RM ?? "");
string tag = newRec.isIn ? "In" : "Out";
DictUpsert(ref currDict, $"lastWeight{tag}", $"{newRec.weight:N2}");
// registro record completo ultima pesata
DictUpsert(ref currDict, $"lastRec{tag}", formatPesata(newRec));
// la aggiungo alle pesate archiviate...
AppendPesata(newRec);
}
#endif
#region Private Properties
/// <summary>
/// Parametri specifici Client Rest
/// </summary>
protected RestParamConf restParams { get; set; } = new RestParamConf();
#endregion Private Properties
protected virtual void refreshData()
{ }
#endregion Private Methods
}
}
+362 -38
View File
@@ -1,13 +1,15 @@
using IOB_UT_NEXT;
using IOB_UT_NEXT;
using MapoSDK;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using static IOB_WIN_NEXT.IobRest.Citizen.Responses;
namespace IOB_WIN_NEXT.IobRest
{
@@ -34,25 +36,225 @@ namespace IOB_WIN_NEXT.IobRest
{
setupRestConf(getOptJsonKVP("REST_CONF"));
}
// fixme todo levare forzatura test iniziale...
if (EnableTest || true)
{
// test folder salvataggio log
var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
var fPath = Directory.GetParent(appPath).FullName;
basePath = Path.Combine(fPath, "Test");
if (!Directory.Exists(basePath))
{
Directory.CreateDirectory(basePath);
}
string token = TestCitizenCall("gettoken/mecmaticames/mecmatica@mes");
string gLamp = TestCitizenCall($"getsingleladderio/{token}/Y/8E");
string yLamp = TestCitizenCall($"getsingleladderio/{token}/Y/21");
string rLamp = TestCitizenCall($"getsingleladderio/{token}/Y/22");
string qtyTot = TestCitizenCall($"gettotalquantity/{token}");
string qtyReq = TestCitizenCall($"getneededquantity/{token}");
string qtyWrk = TestCitizenCall($"getworkedquantity/{token}");
string cTime = TestCitizenCall($"getcycletime/{token}");
string pName = TestCitizenCall($"getmainprogram/{token}");
string cAlarm = ExecuteCallGet($"getalarm/{token}");
var sAlarm = JsonConvert.DeserializeObject<WarnInfo>(cAlarm);
cAlarm = JsonConvert.SerializeObject(sAlarm, Formatting.Indented);
lgInfo($"Call: getalarm/{token} | resp: {cAlarm}");
string allAlarm = ExecuteCallGet($"getallalarmlog/{token}");
var alarmList = JsonConvert.DeserializeObject<List<AlarmInfo>>(allAlarm);
allAlarm = JsonConvert.SerializeObject(alarmList, Formatting.Indented);
lgInfo($"Call: getallalarmlog/{token} | resp: {allAlarm}");
string err = TestCitizenCall($"getsingleladderio/ABC/Y/22");
// salvo i valori
File.WriteAllText(Path.Combine(basePath, "token.txt"), token);
File.WriteAllText(Path.Combine(basePath, "gLamp.txt"), gLamp);
File.WriteAllText(Path.Combine(basePath, "yLamp.txt"), yLamp);
File.WriteAllText(Path.Combine(basePath, "rLamp.txt"), rLamp);
File.WriteAllText(Path.Combine(basePath, "qtyTot.txt"), qtyTot);
File.WriteAllText(Path.Combine(basePath, "qtyReq.txt"), qtyReq);
File.WriteAllText(Path.Combine(basePath, "qtyWrk.txt"), qtyWrk);
File.WriteAllText(Path.Combine(basePath, "cTime.txt"), cTime);
File.WriteAllText(Path.Combine(basePath, "pName.txt"), pName);
File.WriteAllText(Path.Combine(basePath, "cAlarm.txt"), cAlarm);
File.WriteAllText(Path.Combine(basePath, "allAlarm.txt"), allAlarm);
File.WriteAllText(Path.Combine(basePath, "err.txt"), err);
}
}
#endregion Public Constructors
#region Public Methods
/// <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("Rest: ConnKO - tryConnect");
}
// in primis salvo data ping...
lastPING = DateTime.Now;
bool checkMachine = false;
// se passa il ping faccio il resto...
if (testPingMachine == IPStatus.Success)
{
string szStatusConnection = "";
try
{
// ora provo connessione...
parentForm.commPlcActive = true;
// chiamo metodo connect
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"));
lgInfo($"GetConnection | {checkResp}");
bool.TryParse(checkResp, out checkMachine);
// forse va eliminato...
if (checkMachine)
{
connectionOk = true;
queueInEnabCurr = true;
if (adpRunning)
{
lgInfo("Connessione OK");
}
}
else
{
lgError($"Errore check connessione | checkResp: {checkResp}");
}
}
catch (Exception exc)
{
lgFatal($"Errore nella connessione all'Adapter IobRest.Base: {szStatusConnection}{Environment.NewLine}{exc}");
connectionOk = false;
lgInfo($"Eccezione in TryConnect, Adapter IobRest.Base 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: Rest controllo PING fallito per IP {cIobConf.cncPingAddr}");
}
}
}
}
else
{
needRefresh = true;
}
}
#endregion Public Methods
#region Internal Classes
/// <summary>
/// Struttura delle risposte alle chiamare REST specifiche
/// </summary>
internal class Responses
{
#region Internal Classes
/// <summary>
/// Struttura info restituiti da AlarmList
/// </summary>
internal class AlarmInfo
{
#region Public Properties
public DateTime date { get; set; } = DateTime.Today.AddYears(-10);
public string ErrorMessage { get; set; } = "";
public int id { get; set; } = 0;
public string message { get; set; } = "";
public string type { get; set; } = "";
#endregion Public Properties
}
/// <summary>
/// Struttura info restituiti x lettura Ladder
/// </summary>
internal class LadderIO
{
#region Public Properties
public string Address { get; set; } = "";
public string Description { get; set; } = "";
public string ErrorMessage { get; set; } = "";
public string IOType { get; set; } = "";
public string VarValue { get; set; } = "";
#endregion Public Properties
}
/// <summary>
/// Struttura dato AlarmState (singolo, corrente)
/// </summary>
internal class WarnInfo
{
#region Public Properties
public string ErrorMessage { get; set; } = "";
public bool IsAlarm { get; set; } = false;
public bool IsCaution { get; set; } = false;
public string message { get; set; } = "";
#endregion Public Properties
}
#endregion Internal Classes
}
#endregion Internal Classes
#region Private Fields
private string basePath = "";
#endregion Private Fields
#region Private Properties
/// <summary>
/// Elenco pesate attuali
/// </summary>
private List<AlarmInfo> listAllarmiCurr { get; set; } = new List<AlarmInfo>();
/// <summary>
/// CHiave redis di salvataggio ultimo set di allarmi scaricato
/// </summary>
private string redKeyAlarm { get; set; } = "";
#endregion Private Properties
#region Private Methods
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
private void decodeToBaseBitmap()
protected override void decodeToBaseBitmap(ref newDisplayData currDispData)
{
// init a zero...
B_input = 0;
if (queueInEnabCurr)
{
/* -----------------------------------------------------
* bitmap MAPO STD 60
* bitmap MAPO STD 60
* B0: POWER_ON
* B1: RUN
* B2: pzCount
@@ -65,34 +267,34 @@ namespace IOB_WIN_NEXT.IobRest
// per prima cosa controllo ping e se sia connesso...
#if false
if (connectionOk)
{
B_input = 1;
currDispData.semIn = Semaforo.SV;
// se ho pesate in memoria nel periodo richiesto --> RUN
if (listPesateCurr != null && listPesateCurr.Count > 0)
if (connectionOk)
{
B_input += (1 << 1);
B_input = 1;
currDispData.semIn = Semaforo.SV;
// controllo lampade... da rosso a verde...
if(RestLutGet("rLamp")=="1")
{
B_input += (1 << 3);
}
else if (RestLutGet("yLamp") == "1")
{
B_input += (1 << 4);
}
else if (RestLutGet("gLamp") == "1")
{
B_input += (1 << 1);
}
// accodo NON emergenza ... poi da cercare meglio...
B_input += (1 << 7);
}
// metto manuale
else
{
B_input += (1 << 4);
B_input = 0;
currDispData.semIn = Semaforo.SR;
}
// accodo NON emergenza
B_input += (1 << 7);
}
else
{
B_input = 0;
currDispData.semIn = Semaforo.SR;
}
#endif
#if false
// Controllo booleano PING e POWERON...
@@ -202,30 +404,152 @@ namespace IOB_WIN_NEXT.IobRest
if (verboseLog)
{
lgInfo($"Trasformazione B_input: {B_input} | currRun = {currRun}");
}
}
#endif
}
else
{
lgDebug($"[VETO getDataItemValue] | veto attivo alle {DateTime.Now:yyyy.MM.dd HH:mm:ss}");
lgDebug($"[VETO queueInEnabCurr] | veto attivo alle {DateTime.Now:yyyy.MM.dd HH:mm:ss}");
}
}
#endregion Public Constructors
protected class AlarmRec
/// <summary>
/// Esegue lettura dati + salvataggio in LUT
/// </summary>
protected override void refreshData()
{
public int id { get; set; } = 0;
public DateTime date { get; set; } = DateTime.Now;
public string message { get; set; } = "";
public string type { get; set; } = "";
bool checkMachine = false;
LadderIO ladderResp = new LadderIO();
// in primis testo che sia connessa...
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"));
lgInfo($"GetConnection | {checkResp}");
bool.TryParse(checkResp, out checkMachine);
// proseguo SOLO SE macchina OK, altrimenti disconnetto...
if (checkMachine)
{
// faccio refresh token comunque...
string token = ExecuteCallGet(GetUrlResource("GetToken"));
RestLutUpsert("token", token);
// ora controllo valori lampada SE scaduti
// FixMe ToDo !!! gestione con scadenza info x evitare troppe letture...
if (true)
{
// resetto 3 valori lamp
RestLutUpsert("gLamp", "0");
RestLutUpsert("yLamp", "0");
RestLutUpsert("rLamp", "0");
int signVal = 0;
string gLamp = ExecuteCallGet(GetUrlResource("GetLampGreen"));
ladderResp = JsonConvert.DeserializeObject<LadderIO>(gLamp);
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
{
int.TryParse(gLamp, out signVal);
RestLutUpsert("gLamp", gLamp);
}
// se il valore è zero --> proseguo con yellow!
if (signVal == 0)
{
string yLamp = ExecuteCallGet(GetUrlResource("GetLampYellow"));
ladderResp = JsonConvert.DeserializeObject<LadderIO>(yLamp);
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
{
int.TryParse(yLamp, out signVal);
RestLutUpsert("yLamp", yLamp);
}
}
// se il valore è zero --> proseguo con red!
if (signVal == 0)
{
string rLamp = ExecuteCallGet(GetUrlResource("GetLampRed"));
ladderResp = JsonConvert.DeserializeObject<LadderIO>(rLamp);
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
{
int.TryParse(rLamp, out signVal);
RestLutUpsert("rLamp", rLamp);
}
}
}
}
else
{
tryDisconnect();
}
}
/// <summary>
/// Elenco pesate attuali
/// Esegue gestioen contapezzi...
/// </summary>
private List<AlarmRec> listAllarmiCurr { get; set; } = new List<AlarmRec>();
public override void processContapezzi()
{
bool checkMachine = false;
LadderIO ladderResp = new LadderIO();
// in primis testo che sia connessa...
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"));
lgInfo($"GetConnection | {checkResp}");
bool.TryParse(checkResp, out checkMachine);
// proseguo SOLO SE macchina OK, altrimenti disconnetto...
if (checkMachine)
{
// faccio refresh token comunque...
string token = ExecuteCallGet(GetUrlResource("GetToken"));
RestLutUpsert("token", token);
// contapezzi corrente
int intVal = 0;
string qtyWrk = ExecuteCallGet(GetUrlResource("GetQtyProd"));
int.TryParse(qtyWrk, out intVal);
contapezziPLC = intVal;
RestLutUpsert("qtyWrk", qtyWrk);
// gestione altri contapezzi x
string qtyTot = ExecuteCallGet(GetUrlResource("GetQtyTot"));
string qtyReq = ExecuteCallGet(GetUrlResource("GetQtyReq"));
RestLutUpsert("qtyTot", qtyTot);
RestLutUpsert("qtyReq", qtyReq);
// gestione tempociclo e nome programma...
string cTime = ExecuteCallGet(GetUrlResource("GetCycleTime"));
string pName = ExecuteCallGet(GetUrlResource("GetProgName"));
RestLutUpsert("cTime", cTime);
RestLutUpsert("pName", pName);
}
}
/// <summary>
/// Recupero dati DYN, impiegando i valori della LUT...
/// </summary>
/// <returns></returns>
public override Dictionary<string, string> getDynData()
{
return RestDataLUT;
}
/// <summary>
/// Recupera il progName in modalità custom...
/// </summary>
/// <returns></returns>
public override string getPrgName()
{
return RestLutGet("pName");
}
/// <summary>
/// Test Chiamata Citizen
/// </summary>
/// <param name="urlReq"></param>
/// <returns></returns>
private string TestCitizenCall(string urlReq)
{
string answ = ExecuteCallGet(urlReq);
lgInfo($"Call: {urlReq} | resp: {answ}");
return answ;
}
#endregion Private Methods
}
}