2383 lines
87 KiB
C#
2383 lines
87 KiB
C#
using MapoSDK;
|
|
using Newtonsoft.Json;
|
|
using SteamWare;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
|
|
namespace MapoDb
|
|
{
|
|
/// <summary>
|
|
/// classe gestione operazioni su DB tramite MapoDb
|
|
/// </summary>
|
|
public class DataLayer
|
|
{
|
|
#region area table adapters
|
|
|
|
// Table adapter x DS_Applicazione
|
|
public DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter taAG;
|
|
public DS_applicazioneTableAdapters.MacchineTableAdapter taMacchine;
|
|
public DS_applicazioneTableAdapters.StatoMacchineTableAdapter taStatoMacchine;
|
|
public DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter taAnagEventi;
|
|
public DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter taAnagStati;
|
|
public DS_applicazioneTableAdapters.KeepAliveTableAdapter taKeepAlive;
|
|
public DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter taStati;
|
|
public DS_applicazioneTableAdapters.EventListTableAdapter taEventi;
|
|
public DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter taOp;
|
|
public DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter taOp2ins;
|
|
public DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter taTranIngr;
|
|
public DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter taRemReb;
|
|
public DS_applicazioneTableAdapters.SignalLogTableAdapter taSigLog;
|
|
public DS_applicazioneTableAdapters.FluxLogTableAdapter taFL;
|
|
// Table adapter x DS_ProdTempi
|
|
public DS_ProdTempiTableAdapters.AnagArticoliTableAdapter taAnagArt;
|
|
public DS_ProdTempiTableAdapters.ODLTableAdapter taODL;
|
|
public DS_ProdTempiTableAdapters.DatiMacchineTableAdapter taDatiMacchine;
|
|
public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter taDatiProdMacch;
|
|
public DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter taDatiProdMacchPer;
|
|
public DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter taDatiStatoMacch;
|
|
public DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter taPostazioni;
|
|
#if false
|
|
public DS_ProdTempiTableAdapters.DatiConfermatiTableAdapter taDatiConfermati;
|
|
#endif
|
|
public DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter taPzProd2conf;
|
|
public DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter taTempiCicloRilevati;
|
|
public DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter taDatiProd;
|
|
public DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter taTempoByClass;
|
|
public DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter taTurniMacc;
|
|
public DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter taCalFF;
|
|
public DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter taMSE;
|
|
public DS_ProdTempiTableAdapters.PromesseODLTableAdapter taPODL;
|
|
public DS_ProdTempiTableAdapters.RegistroControlliTableAdapter taRC;
|
|
public DS_ProdTempiTableAdapters.RegistroScartiTableAdapter taRS;
|
|
public DS_ProdTempiTableAdapters.StatoProdTableAdapter taStatoProd;
|
|
// table adapter x utility
|
|
public DS_UtilityTableAdapters.v_selArticoliTableAdapter taSelArt;
|
|
public DS_UtilityTableAdapters.v_selMacchineTableAdapter taSelMacc;
|
|
public DS_UtilityTableAdapters.v_selODLTableAdapter taSelOdlFree;
|
|
public DS_UtilityTableAdapters.CommentiTableAdapter taComm;
|
|
|
|
// table adapter x planner
|
|
public DS_PlanTableAdapters.MachineParamsTableAdapter taMacParams;
|
|
public DS_PlanTableAdapters.CalStopTableAdapter taPlanCalStop;
|
|
public DS_PlanTableAdapters.CalDispTableAdapter taPlanCalDisp;
|
|
public DS_PlanTableAdapters.RichiesteTableAdapter taPlanRichieste;
|
|
public DS_PlanTableAdapters.PromesseOUTTableAdapter taPromOut;
|
|
|
|
// tablet adapter x IS
|
|
public DS_IntServTableAdapters.IstanzeKITTableAdapter taIstK;
|
|
public DS_IntServTableAdapters.ProduzioneAs400TableAdapter taAs400;
|
|
public DS_IntServTableAdapters.TKS_SearchTableAdapter taTKS;
|
|
public DS_IntServTableAdapters.TransitoDatiTableAdapter taIS_TrDati;
|
|
public DS_IntServTableAdapters.WipSetupKitTableAdapter taWKS;
|
|
|
|
|
|
/// <summary>
|
|
/// init dei table adapters
|
|
/// </summary>
|
|
protected void initTA()
|
|
{
|
|
// istanzio oggetto
|
|
taAG = new DS_applicazioneTableAdapters.AnagraficaGruppiTableAdapter();
|
|
taMacchine = new DS_applicazioneTableAdapters.MacchineTableAdapter();
|
|
taStatoMacchine = new DS_applicazioneTableAdapters.StatoMacchineTableAdapter();
|
|
taAnagEventi = new DS_applicazioneTableAdapters.AnagraficaEventiTableAdapter();
|
|
taAnagStati = new DS_applicazioneTableAdapters.AnagraficaStatiTableAdapter();
|
|
taKeepAlive = new DS_applicazioneTableAdapters.KeepAliveTableAdapter();
|
|
taStati = new DS_applicazioneTableAdapters.DiarioDiBordoTableAdapter();
|
|
taEventi = new DS_applicazioneTableAdapters.EventListTableAdapter();
|
|
taOp = new DS_applicazioneTableAdapters.AnagraficaOperatoriTableAdapter();
|
|
taOp2ins = new DS_applicazioneTableAdapters.AnagraficaOperatori2insTableAdapter();
|
|
taTranIngr = new DS_applicazioneTableAdapters.TransizioneIngressiTableAdapter();
|
|
taRemReb = new DS_applicazioneTableAdapters.RemoteRebootLogTableAdapter();
|
|
taSigLog = new DS_applicazioneTableAdapters.SignalLogTableAdapter();
|
|
taFL = new DS_applicazioneTableAdapters.FluxLogTableAdapter();
|
|
taAnagArt = new DS_ProdTempiTableAdapters.AnagArticoliTableAdapter();
|
|
taODL = new DS_ProdTempiTableAdapters.ODLTableAdapter();
|
|
taDatiMacchine = new DS_ProdTempiTableAdapters.DatiMacchineTableAdapter();
|
|
taDatiProdMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaTableAdapter();
|
|
taDatiProdMacchPer = new DS_ProdTempiTableAdapters.stp_repDonati_getDatiProdMacchinaPeriodoTableAdapter();
|
|
taDatiStatoMacch = new DS_ProdTempiTableAdapters.stp_repDonati_getLastStatoDurataMacchinaTableAdapter();
|
|
taPostazioni = new DS_ProdTempiTableAdapters.PostazioniMapoTableAdapter();
|
|
taTurniMacc = new DS_ProdTempiTableAdapters.TurniMacchinaTableAdapter();
|
|
#if false
|
|
taDatiConfermati = new DS_ProdTempiTableAdapters.DatiConfermatiTableAdapter();
|
|
#endif
|
|
taPzProd2conf = new DS_ProdTempiTableAdapters.stp_PzProd_getByMacchinaTableAdapter();
|
|
taTempiCicloRilevati = new DS_ProdTempiTableAdapters.TempiCicloRilevatiTableAdapter();
|
|
taDatiProd = new DS_ProdTempiTableAdapters.DatiProduzioneTableAdapter();
|
|
taTempoByClass = new DS_ProdTempiTableAdapters.stp_TempoByIdxMaccPeriodClassTableAdapter();
|
|
taCalFF = new DS_ProdTempiTableAdapters.CalendFesteFerieTableAdapter();
|
|
taMSE = new DS_ProdTempiTableAdapters.MappaStatoExplTableAdapter();
|
|
taPODL = new DS_ProdTempiTableAdapters.PromesseODLTableAdapter();
|
|
taRC = new DS_ProdTempiTableAdapters.RegistroControlliTableAdapter();
|
|
taRS = new DS_ProdTempiTableAdapters.RegistroScartiTableAdapter();
|
|
taStatoProd = new DS_ProdTempiTableAdapters.StatoProdTableAdapter();
|
|
|
|
taSelArt = new DS_UtilityTableAdapters.v_selArticoliTableAdapter();
|
|
taSelMacc = new DS_UtilityTableAdapters.v_selMacchineTableAdapter();
|
|
taSelOdlFree = new DS_UtilityTableAdapters.v_selODLTableAdapter();
|
|
taComm = new DS_UtilityTableAdapters.CommentiTableAdapter();
|
|
|
|
taMacParams = new DS_PlanTableAdapters.MachineParamsTableAdapter();
|
|
taPlanCalStop = new DS_PlanTableAdapters.CalStopTableAdapter();
|
|
taPlanCalDisp = new DS_PlanTableAdapters.CalDispTableAdapter();
|
|
taPlanRichieste = new DS_PlanTableAdapters.RichiesteTableAdapter();
|
|
taPromOut = new DS_PlanTableAdapters.PromesseOUTTableAdapter();
|
|
|
|
taIstK = new DS_IntServTableAdapters.IstanzeKITTableAdapter();
|
|
taAs400 = new DS_IntServTableAdapters.ProduzioneAs400TableAdapter();
|
|
taTKS = new DS_IntServTableAdapters.TKS_SearchTableAdapter();
|
|
taIS_TrDati = new DS_IntServTableAdapters.TransitoDatiTableAdapter();
|
|
taWKS = new DS_IntServTableAdapters.WipSetupKitTableAdapter();
|
|
}
|
|
/// <summary>
|
|
/// effettua setup dei connection strings da web.config delal singola applicazione
|
|
/// </summary>
|
|
protected virtual void setupConnectionStringBase()
|
|
{
|
|
string connectionString = memLayer.ML.confReadString("MoonProConnectionString");
|
|
string connectionStringIS = memLayer.ML.confReadString("MoonProConnectionStringIS");
|
|
string connectionStringES3 = memLayer.ML.confReadString("MoonProConnectionStringES3");
|
|
// connections del db
|
|
taAG.Connection.ConnectionString = connectionString;
|
|
taMacchine.Connection.ConnectionString = connectionString;
|
|
taStatoMacchine.Connection.ConnectionString = connectionString;
|
|
taAnagEventi.Connection.ConnectionString = connectionString;
|
|
taAnagStati.Connection.ConnectionString = connectionString;
|
|
taKeepAlive.Connection.ConnectionString = connectionString;
|
|
taStati.Connection.ConnectionString = connectionString;
|
|
taEventi.Connection.ConnectionString = connectionString;
|
|
taOp.Connection.ConnectionString = connectionString;
|
|
taOp2ins.Connection.ConnectionString = connectionString;
|
|
taTranIngr.Connection.ConnectionString = connectionString;
|
|
taRemReb.Connection.ConnectionString = connectionString;
|
|
taSigLog.Connection.ConnectionString = connectionString;
|
|
taFL.Connection.ConnectionString = connectionString;
|
|
taAnagArt.Connection.ConnectionString = connectionString;
|
|
taODL.Connection.ConnectionString = connectionString;
|
|
taDatiMacchine.Connection.ConnectionString = connectionString;
|
|
taDatiProdMacch.Connection.ConnectionString = connectionString;
|
|
taDatiProdMacchPer.Connection.ConnectionString = connectionString;
|
|
taDatiStatoMacch.Connection.ConnectionString = connectionString;
|
|
taPostazioni.Connection.ConnectionString = connectionString;
|
|
taTurniMacc.Connection.ConnectionString = connectionString;
|
|
#if false
|
|
taDatiConfermati.Connection.ConnectionString = connectionString;
|
|
#endif
|
|
taPzProd2conf.Connection.ConnectionString = connectionString;
|
|
taTempiCicloRilevati.Connection.ConnectionString = connectionString;
|
|
taDatiProd.Connection.ConnectionString = connectionString;
|
|
taTempoByClass.Connection.ConnectionString = connectionString;
|
|
taCalFF.Connection.ConnectionString = connectionString;
|
|
taMSE.Connection.ConnectionString = connectionString;
|
|
taPODL.Connection.ConnectionString = connectionString;
|
|
taRC.Connection.ConnectionString = connectionString;
|
|
taRS.Connection.ConnectionString = connectionString;
|
|
taStatoProd.Connection.ConnectionString = connectionString;
|
|
taSelArt.Connection.ConnectionString = connectionString;
|
|
taSelMacc.Connection.ConnectionString = connectionString;
|
|
taSelOdlFree.Connection.ConnectionString = connectionString;
|
|
taComm.Connection.ConnectionString = connectionString;
|
|
// area planner
|
|
taMacParams.Connection.ConnectionString = connectionStringES3;
|
|
taPlanCalStop.Connection.ConnectionString = connectionStringES3;
|
|
taPlanCalDisp.Connection.ConnectionString = connectionStringES3;
|
|
taPlanRichieste.Connection.ConnectionString = connectionStringES3;
|
|
taPromOut.Connection.ConnectionString = connectionStringES3;
|
|
// area IS
|
|
taIS_TrDati.Connection.ConnectionString = connectionStringIS;
|
|
taIstK.Connection.ConnectionString = connectionStringIS;
|
|
taAs400.Connection.ConnectionString = connectionStringIS;
|
|
taWKS.Connection.ConnectionString = connectionStringIS;
|
|
taTKS.Connection.ConnectionString = connectionStringIS;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Inizializzazione
|
|
|
|
protected DataLayer()
|
|
{
|
|
initTA();
|
|
setupConnectionStringBase();
|
|
|
|
// aggiunta x gestione timeout esteso (ove necessario)!
|
|
fixCommandTimeout();
|
|
}
|
|
|
|
/// <summary>
|
|
/// sistemazione timeout comandi nei tableadapter
|
|
/// </summary>
|
|
private void fixCommandTimeout()
|
|
{
|
|
SetAllCommandTimeouts(taComm, memLayer.ML.CRI("sqlLongCommandTimeout"));
|
|
}
|
|
void SetAllCommandTimeouts(object adapter, int timeout)
|
|
{
|
|
var commands = adapter.GetType().InvokeMember(
|
|
"CommandCollection",
|
|
BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
|
|
null, adapter, new object[0]);
|
|
var sqlCommand = (SqlCommand[])commands;
|
|
foreach (var cmd in sqlCommand)
|
|
{
|
|
cmd.CommandTimeout = timeout;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// oggetto static per fare chiamate sul magazzino
|
|
/// </summary>
|
|
public static DataLayer obj = new DataLayer();
|
|
|
|
#endregion
|
|
|
|
#region utility interne
|
|
|
|
/// <summary>
|
|
/// registra su REDIS eventuale superamento numero limite di call x il metodo in oggetto
|
|
/// </summary>
|
|
/// <param name="callCountKey"></param>
|
|
private static void saveCallRec(string callCountKey)
|
|
{
|
|
// conto la richiesta nel contatore REDIS
|
|
long nCall = memLayer.ML.setRCntI(mHash($"COUNT:pCall:{callCountKey}"));
|
|
//... se == nCall2Log scrivo su log e resetto
|
|
long nCall2Log = memLayer.ML.cdvi("nCall2Log");
|
|
if (nCall >= nCall2Log)
|
|
{
|
|
// loggo
|
|
logger.lg.scriviLog($"{callCountKey}: {nCall} call received", tipoLog.INFO);
|
|
// resetto!
|
|
memLayer.ML.resetRCnt(mHash($"COUNT:pCall:{callCountKey}"));
|
|
}
|
|
}
|
|
|
|
public static List<T> DataTableToList<T>(DataTable dt) where T : class, new()
|
|
{
|
|
List<T> lstItems = new List<T>();
|
|
if (dt != null && dt.Rows.Count > 0)
|
|
foreach (DataRow row in dt.Rows)
|
|
lstItems.Add(ConvertDataRowToGenericType<T>(row));
|
|
else
|
|
lstItems = null;
|
|
return lstItems;
|
|
}
|
|
|
|
private static T ConvertDataRowToGenericType<T>(DataRow row) where T : class, new()
|
|
{
|
|
Type entityType = typeof(T);
|
|
T objEntity = new T();
|
|
foreach (DataColumn column in row.Table.Columns)
|
|
{
|
|
object value = row[column.ColumnName];
|
|
if (value == DBNull.Value) value = null;
|
|
PropertyInfo property = entityType.GetProperty(column.ColumnName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
|
|
try
|
|
{
|
|
if (property != null && property.CanWrite)
|
|
property.SetValue(objEntity, value, null);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
return objEntity;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region utility public esposte
|
|
|
|
/// <summary>
|
|
/// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma --> adesso)
|
|
/// </summary>
|
|
/// <param name="idxMacchina">idx macchina da confermare</param>
|
|
/// <param name="modoConfProd">0=periodo, 1 = giorno, 2 = turno</param>
|
|
/// <param name="numPzConfermati">qta pezzi BUONI da confermare</param>
|
|
/// <param name="numPzScarto">qta pezzi SCARTO da confermare</param>
|
|
/// <param name="DataOraApp">DataOra in cui registrare approvazione</param>
|
|
/// <returns></returns>
|
|
public bool confermaProdMacchina(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = DataLayer.obj.taPzProd2conf.GetData(idxMacchina.ToString())[0];
|
|
// chiamo stored stp_ConfermaProduzCompleta(idxMacchina,MatrApp,dataFrom,dataTo,pezziConf)
|
|
taPzProd2conf.stp_ConfermaProduzCompleta(idxMacchina, MatrOpr, rigaProd.DataFrom, DataOraApp, numPzConfermati, numPzScarto, modoConfProd, DataOraApp, true);
|
|
//taPzProd2conf.stp_ConfermaProduzCompleta(idxMacchina, MatrOpr, rigaProd.DataFrom, rigaProd.DataTo, numPzConfermati, numPzScarto, modoConfProd, DateTime.Now, true);
|
|
// indico eseguito!
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in conferma prod macchina:{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// invia una mail al destinatario x linkare nuovi devices tramite URL
|
|
/// </summary>
|
|
/// <param name="destinatario"></param>
|
|
/// <param name="UserAuthKey"></param>
|
|
/// <param name="idxDipendente"></param>
|
|
/// <returns></returns>
|
|
public bool sendUserAuthEmail(string destinatario, string UserAuthKey, int idxDipendente)
|
|
{
|
|
bool fatto = false;
|
|
string smtpCli = "";
|
|
string mittente = "";
|
|
string oggetto = "";
|
|
string userUrl = "";
|
|
string baseUrl = "";
|
|
string userWebUrl = "";
|
|
string baseWebUrl = "";
|
|
string corpo = "";
|
|
try
|
|
{
|
|
// compongo la stringa
|
|
smtpCli = memLayer.ML.CRS("_smtpCli");
|
|
mittente = memLayer.ML.CRS("_fromEmail");
|
|
oggetto = "Link autorizzazione device per GPW";
|
|
baseUrl = memLayer.ML.CRS("baseUrl");
|
|
baseWebUrl = memLayer.ML.CRS("baseWebUrl");
|
|
userUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseUrl);
|
|
userWebUrl = string.Format("{2}jumper.aspx?UserAuthkey={0}&idxDipendente={1}", UserAuthKey, idxDipendente, baseWebUrl);
|
|
corpo = string.Format("Hai ricevuto questa email su richiesta tua o dell'Admin per poter procedere a registrare un (nuovo) devices con GPW:{0}<br/>Per proseguire clicca sul link seguente(rete interna):<br />{0}{0}{1}{0}{0}<br /><br />oppure sul link seguente (internet):<br />{0}{0}{2}{0}{0}<br /><br />Team GPW Steamware", Environment.NewLine, userUrl, userWebUrl);
|
|
gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo);
|
|
fatto = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return fatto;
|
|
}
|
|
/// <summary>
|
|
/// Invia email di avviso che ci sono dei TC da confermare
|
|
/// </summary>
|
|
/// <param name="destinatario"></param>
|
|
/// <returns></returns>
|
|
public bool sendWarnTcChangeReq(string destinatario)
|
|
{
|
|
bool fatto = false;
|
|
string mittente = "";
|
|
string oggetto = "";
|
|
string pageUrl = "";
|
|
string corpo = "";
|
|
try
|
|
{
|
|
// compongo la stringa
|
|
mittente = memLayer.ML.CRS("_fromEmail");
|
|
oggetto = memLayer.ML.CRS("oggettoChgTc");
|
|
pageUrl = string.Format("{0}{1}", memLayer.ML.CRS("baseUrlAdmin"), memLayer.ML.CRS("pageUrlApprODL"));
|
|
corpo = string.Format(memLayer.ML.CRS("corpoChgTc"), Environment.NewLine, pageUrl);
|
|
if (memLayer.ML.CRB("_useAuthSmtp"))
|
|
{
|
|
gestEmail.geAuth.mandaEmail(mittente, destinatario, oggetto, corpo);
|
|
}
|
|
else
|
|
{
|
|
gestEmail.ge.mandaEmail(mittente, destinatario, oggetto, corpo);
|
|
}
|
|
fatto = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// effettua enroll del device
|
|
/// </summary>
|
|
/// <param name="UserAuthKey"></param>
|
|
/// <param name="IPv4"></param>
|
|
/// <param name="DeviceName"></param>
|
|
/// <param name="Description"></param>
|
|
/// <param name="idxDipendente"></param>
|
|
/// <returns></returns>
|
|
public bool enrollDevice(string UserAuthKey, string IPv4, string DeviceName, string Description, int matricola)
|
|
{
|
|
bool fatto = false;
|
|
// in primis testo se dipendente ed authKey sono validi..
|
|
if (taOp.getByMatrAuthKey(matricola, UserAuthKey).Rows.Count > 0)
|
|
{
|
|
// salvo matrOpr
|
|
MatrOpr = matricola;
|
|
/************************************************
|
|
* Gestione riconoscimento devices
|
|
*
|
|
* - cerco IP del device, testo se è rete interna (A) o extranet/internet (B) cercando substring "localNet" da web.config
|
|
* (A): device interni: c'è un DHCP, e "dhcpLeaseTime" deve essere pari a lease time---
|
|
* - verifico se IP già in uso da un tempo < "dhcpLeaseTime" --> in questo caso segnalo errore e rimbalzo (NON permetto di registrare device a nuovo utente... sospetto uso "improprio" del device
|
|
* - se tempo > dhcpLeaseTime allora può aver cambiato IP: aggiorno IP e descrizione del device e proseguo
|
|
* (B): all'esterno vedo tutta una subnet NATtata con unico IP, non è + discriminante
|
|
* - le timbrature "da esterno" devono essere confermate (instrodurre "tipo timbratura" x cui interne sono autoconfermate, esterne sono "grayed" (da confermare, da admin o ad esempio se si accende secondo device utente entro 5/10 min)
|
|
* - le timbrature ext DOVREBBERO chiedere location (jScript?) e inviarla, visibile in conferma
|
|
*
|
|
*
|
|
* **********************************************/
|
|
// calcolo il secret...
|
|
DateTime adesso = DateTime.Now;
|
|
string Dominio = memLayer.ML.CRS("dominio");
|
|
string UsrName = memLayer.ML.CRS("user");
|
|
// recupero dati da matricola...
|
|
try
|
|
{
|
|
DataLayer_AnagGen.UTENTERow rigaUt = user_std.UtSn.rigaUtenteDaMatricola(matricola.ToString());
|
|
if (rigaUt != null)
|
|
{
|
|
Dominio = rigaUt.DOMINIO;
|
|
UsrName = rigaUt.USER_NAME;
|
|
}
|
|
else
|
|
{
|
|
logger.lg.scriviLog(string.Format("non sono riuscito a recuperare RIGA utente per matricola {0}", matricola), tipoLog.ERROR);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
logger.lg.scriviLog(string.Format("Eccezione! non sono riuscito a recuperare utente per matricola {0}", matricola), tipoLog.ERROR);
|
|
Dominio = memLayer.ML.CRS("dominio");
|
|
UsrName = memLayer.ML.CRS("user");
|
|
}
|
|
string Secret = authProxy.getSecret(Dominio, UsrName, matricola, DeviceName, adesso);
|
|
string devSecret = SteamCrypto.EncryptString(Secret, memLayer.ML.CRS("cookieName"));
|
|
try
|
|
{
|
|
// creo device + cookie!
|
|
fatto = authProxy.createNewCookie(Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire")));
|
|
// loggo!
|
|
logger.lg.scriviLog(string.Format("Effettuato enroll nuovo device: utente {0}\\{1} | matricola {2} | DeviceName {3} | Descrizione {4} | IP {5} | nome cookcie {6} | valido sino a {7:yyyy/MM/dd}", Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.CRS("cookieName"), DateTime.Now.AddDays(memLayer.ML.CRI("cookieDayExpire"))));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore enroll nuovo device:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
return fatto;
|
|
}
|
|
/// <summary>
|
|
/// MatrOpr in sessione
|
|
/// </summary>
|
|
public static int MatrOpr
|
|
{
|
|
get
|
|
{
|
|
int idx = 0;
|
|
try
|
|
{
|
|
idx = memLayer.ML.IntSessionObj("MatrOpr");
|
|
}
|
|
catch
|
|
{ }
|
|
return idx;
|
|
}
|
|
set
|
|
{
|
|
memLayer.ML.setSessionVal("MatrOpr", value);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Cognome Nome da MatrOpr in sessione
|
|
/// </summary>
|
|
public static string CognomeNomeOpr
|
|
{
|
|
get
|
|
{
|
|
// cerco operatore...
|
|
string answ = "";
|
|
try
|
|
{
|
|
DS_applicazione.AnagraficaOperatoriRow oper = DataLayer.obj.taOp.getByMatrOpr(MatrOpr)[0];
|
|
answ = string.Format("{0} {1}", oper.Cognome, oper.Nome);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processa input da IOB eventualmente registrando i segnali inviati
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="valore"></param>
|
|
/// <param name="dtEve"></param>
|
|
/// <param name="dtCurr"></param>
|
|
/// <param name="contatore"></param>
|
|
/// <returns></returns>
|
|
public static string processInput(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore)
|
|
{
|
|
string answ = "";
|
|
// 2018.10.26 controllo dtEve e dtCurr
|
|
if (dtEve == null || dtCurr == null)
|
|
{
|
|
logger.lg.scriviLog(string.Format("procInput: valori nulli date: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr));
|
|
}
|
|
else if (dtEve.Length < 17 || dtCurr.Length < 17)
|
|
{
|
|
logger.lg.scriviLog(string.Format("procInput: valori data non corretti: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr));
|
|
}
|
|
else
|
|
{
|
|
// 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi...
|
|
dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve;
|
|
dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr;
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("processInput");
|
|
}
|
|
DateTime dataOraEvento = DateTime.Now;
|
|
DateTime dtEvento, dtCorrente;
|
|
// controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto
|
|
if (dtEve != dtCurr)
|
|
{
|
|
// delta è un calcolo MOLTO approssimativo della differenza temporale...
|
|
Int64 delta = 0;
|
|
try
|
|
{
|
|
// se ho meno decimali x evento rispetto dtCorrente...
|
|
if (dtEve.Length < dtCurr.Length)
|
|
{
|
|
logger.lg.scriviLog(string.Format("processInput: fix valore dtEve: {0} vs dtCurr: {1}", dtEve, dtCurr), tipoLog.INFO);
|
|
dtEve = dtEve.PadRight(dtCurr.Length, '0');
|
|
}
|
|
delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve);
|
|
// log della classe del delta (1-10, 10-100, 100-1k, 1k-10k, > 10k ms)
|
|
string deltaClass = "";
|
|
// faccio SEMPRE calcolo esatto sennò sbaglia...
|
|
CultureInfo provider = CultureInfo.InvariantCulture;
|
|
string format = "yyyyMMddHHmmssfff";
|
|
dtEvento = DateTime.ParseExact(dtEve, format, provider);
|
|
dtCorrente = DateTime.ParseExact(dtCurr, format, provider);
|
|
Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks;
|
|
TimeSpan ts = new TimeSpan(tiks);
|
|
double ms = Math.Abs(ts.TotalMilliseconds);
|
|
// calcolo ESATTO dataora evento
|
|
dataOraEvento = dataOraEvento.AddTicks(-tiks);
|
|
if (ms <= 10)
|
|
{
|
|
deltaClass = "delta 0-10 ms";
|
|
}
|
|
else if (ms <= 100)
|
|
{
|
|
deltaClass = "delta 10-100 ms";
|
|
}
|
|
else if (ms <= 1000)
|
|
{
|
|
deltaClass = "delta 100-1000 ms";
|
|
}
|
|
else if (ms <= 10000)
|
|
{
|
|
deltaClass = "delta 1-10 sec";
|
|
}
|
|
else
|
|
{
|
|
deltaClass = "delta > 10 sec";
|
|
}
|
|
// se ho deltaClass loggo
|
|
if (deltaClass != "")
|
|
{
|
|
logger.lg.scriviLog("Correzione " + deltaClass);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
// inizio processing vero e proprio INPUT...
|
|
if (idxMacchina != null && valore != null)
|
|
{
|
|
if (idxMacchina != "" && valore != "")
|
|
{
|
|
// 2017.07.11 se richiesto di NON usare singleton... riporto FUORI la gestione NUOVO oggetto
|
|
if (memLayer.ML.CRB("disable_singleton"))
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
// se abilitato registro evento sul DB
|
|
if (idxMacchina != "" && DataLayer.sLogEnab(idxMacchina))
|
|
{
|
|
connDb.saveSigLog(idxMacchina, valore, dataOraEvento, contatore);
|
|
}
|
|
// continuo col resto
|
|
try
|
|
{
|
|
// scrivo keep alive!!! (se necessario, altrimenti è in cache...)
|
|
connDb.scriviKeepAlive(idxMacchina, DateTime.Now);
|
|
// verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro....
|
|
if (DataLayer.isMulti(idxMacchina))
|
|
{
|
|
// inizio preprocessing
|
|
string newVal = "";
|
|
// processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
|
|
foreach (var item in mTabMSMI(idxMacchina))
|
|
{
|
|
newVal = preProcInput(item.Key, valore);
|
|
// ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
|
|
connDb.checkMicroStato(item.Key, newVal, dataOraEvento, contatore);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
|
|
connDb.checkMicroStato(idxMacchina, valore, dataOraEvento, contatore);
|
|
}
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
if (memLayer.ML.CRI("_logLevel") > 5)
|
|
{
|
|
string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc);
|
|
logger.lg.scriviLog(errore, tipoLog.EXCEPTION);
|
|
answ = errore;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// se abilitato registro evento sul DB
|
|
if (idxMacchina != "" && MapoDb.obj.sLogEnabled(idxMacchina))
|
|
{
|
|
MapoDb.obj.saveSigLog(idxMacchina, valore, dataOraEvento, contatore);
|
|
}
|
|
// continuo col resto
|
|
try
|
|
{
|
|
// scrivo keep alive!!! (se encessario, altrimenti è in cache...)
|
|
MapoDb.obj.scriviKeepAlive(idxMacchina, DateTime.Now);
|
|
// verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro....
|
|
if (MapoDb.obj.isMulti(idxMacchina))
|
|
{
|
|
// inizio preprocessing
|
|
string newVal = "";
|
|
// processo OGNI macchina a stati dell'impianto... (KEY: IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
|
|
foreach (var item in getMSMI_DB(idxMacchina))
|
|
{
|
|
newVal = preProcInput(item.Key, valore);
|
|
// ora processo e salvo il valore del microstato...
|
|
MapoDb.obj.checkMicroStato(item.Key, newVal, dataOraEvento, contatore);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ora processo e salvo il valore del microstato...
|
|
MapoDb.obj.checkMicroStato(idxMacchina, valore, dataOraEvento, contatore);
|
|
}
|
|
answ = "OK"; // registro in risposta che è andato tutto bene...
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
if (memLayer.ML.CRI("_logLevel") > 5)
|
|
{
|
|
string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc);
|
|
logger.lg.scriviLog(errore, tipoLog.EXCEPTION);
|
|
answ = errore;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: parametri macchina/valore vuoti";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/valore";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI data conf Macchine2FamigliaIngressi
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="valore"></param>
|
|
/// <returns></returns>
|
|
private static string preProcInput(string idxMacchina, string valore)
|
|
{
|
|
string newVal = "";
|
|
try
|
|
{
|
|
// variabili
|
|
int valINT = 0;
|
|
int BitFilt = 0;
|
|
int BSR = 0;
|
|
bool ExplodeBit = false;
|
|
int NumBit = 0;
|
|
int newValInt = 0;
|
|
// recupero parametri...
|
|
int.TryParse(DataLayer.mDatiMacchinaVal(idxMacchina, "BitFilt"), out BitFilt);
|
|
int.TryParse(DataLayer.mDatiMacchinaVal(idxMacchina, "BSR"), out BSR);
|
|
Boolean.TryParse(DataLayer.mDatiMacchinaVal(idxMacchina, "ExplodeBit"), out ExplodeBit);
|
|
int.TryParse(DataLayer.mDatiMacchinaVal(idxMacchina, "NumBit"), out NumBit); // non usato (x ora)
|
|
// recupero valore
|
|
valINT = int.Parse(valore, NumberStyles.HexNumber);
|
|
// filtro
|
|
newValInt = utility.bMaskInt(valINT, BitFilt);
|
|
// effettuo eventuale BitShiftRight
|
|
if (BSR > 0)
|
|
{
|
|
newValInt = newValInt >> BSR;
|
|
}
|
|
// effettuo eventuale esplosione in BIT esclusivi
|
|
if (ExplodeBit)
|
|
{
|
|
newValInt = Convert.ToInt32(1 << newValInt);
|
|
}
|
|
// riconverto a STRING HEX!!!
|
|
newVal = newValInt.ToString("X");
|
|
}
|
|
catch
|
|
{
|
|
newVal = valore;
|
|
}
|
|
|
|
return newVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa registrazione FL da IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="flux"></param>
|
|
/// <param name="valore"></param>
|
|
/// <param name="dtEve"></param>
|
|
/// <param name="dtCurr"></param>
|
|
/// <param name="contatore"></param>
|
|
/// <returns></returns>
|
|
public static string processFluxLog(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore)
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
// scrivo keep alive!!! (se necessario, altrimenti è in cache...)
|
|
connDb.scriviKeepAlive(idxMacchina, DateTime.Now);
|
|
// 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi...
|
|
dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve;
|
|
dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr;
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("processFluxLog");
|
|
}
|
|
string answ = "";
|
|
DateTime dataOraEvento = DateTime.Now;
|
|
DateTime dtEvento, dtCorrente;
|
|
// controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo dataOraEvento corretto
|
|
if (dtEve != dtCurr)
|
|
{
|
|
Int64 delta = 0;
|
|
try
|
|
{
|
|
// se ho meno decimali x evento rispetto dtCorrente...
|
|
if (dtEve.Length < dtCurr.Length)
|
|
{
|
|
dtEve = dtEve.PadRight(dtCurr.Length, '0');
|
|
}
|
|
delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve);
|
|
// se meno di 60'000 ms ...
|
|
if (delta < 59999)
|
|
{
|
|
dataOraEvento = dataOraEvento.AddMilliseconds(-delta);
|
|
}
|
|
else
|
|
{
|
|
// in questo caso elimino i MS dalle stringhe e converto i datetime....
|
|
CultureInfo provider = CultureInfo.InvariantCulture;
|
|
string format = "yyyyMMddHHmmssfff";
|
|
dtEvento = DateTime.ParseExact(dtEve, format, provider);
|
|
dtCorrente = DateTime.ParseExact(dtCurr, format, provider);
|
|
Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks;
|
|
dataOraEvento = dataOraEvento.AddTicks(-tiks);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore calcolo ms evento/ora corrente da device remoto:{0}dtEve : {1}{0}dtCurr: {2}{0}{3}", Environment.NewLine, dtEve, dtCurr, exc), tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
// inizio processing vero e proprio INPUT...
|
|
if (idxMacchina != null && valore != null)
|
|
{
|
|
if (idxMacchina != "" && valore != "")
|
|
{
|
|
DataLayer.obj.taFL.InsNew(idxMacchina, dataOraEvento, flux, valore, contatore);
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: parametri macchina/valore vuoti";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/valore";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Processa registrazione di uno stream di dati LIVE da IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="liveData">Dati live nel formato di lista di KVP chiave/valore1</param>
|
|
/// <returns></returns>
|
|
public static string processLiveJson(string idxMacchina, liveIOB liveData)
|
|
{
|
|
if (liveData == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(liveData));
|
|
}
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("processLiveJson");
|
|
}
|
|
string answ = "";
|
|
DateTime dataOraEvento = DateTime.Now;
|
|
// inizio processing vero e proprio INPUT...
|
|
if (!string.IsNullOrEmpty(idxMacchina) && liveData != null)
|
|
{
|
|
// SE ho dei segnali...
|
|
if (liveData.dataList.Count > 0)
|
|
{
|
|
// salvo in Redis nell'area CURR_VAL TUTTI i valori live
|
|
memLayer.ML.redSaveHashList(LiveCurrValHash(idxMacchina), liveData.dataList);
|
|
// accodo in buffer ULTIMI valori con dataora uno ad uno...
|
|
KeyValuePair<string, string>[] newData = new KeyValuePair<string, string>[1];
|
|
foreach (var item in liveData.dataList)
|
|
{
|
|
// accodo update valori...
|
|
newData[0] = new KeyValuePair<string, string>(dataOraEvento.ToString(), item.Value);
|
|
memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: formato liveData errato (split #)";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/liveData come Json";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Processa registrazione di uno stream di dati LIVE da IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="liveData">Dati live nel formato chiave1|valore1#chiave2|valore2#chiave3|valore3</param>
|
|
/// <returns></returns>
|
|
public static string processLiveRec(string idxMacchina, string liveData)
|
|
{
|
|
if (liveData == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(liveData));
|
|
}
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("processLiveRec");
|
|
}
|
|
string answ = "";
|
|
DateTime dataOraEvento = DateTime.Now;
|
|
// inizio processing vero e proprio INPUT...
|
|
if (idxMacchina != null && liveData != null)
|
|
{
|
|
if (idxMacchina != "" && liveData != "")
|
|
{
|
|
// prendo il vettore LiveData e lo splitto per variabili inviate
|
|
string[] liveSignals = liveData.Split('|');
|
|
// SE ho dei segnali...
|
|
if (liveSignals.Length > 0)
|
|
{
|
|
KeyValuePair<string, string>[] liveSet = new KeyValuePair<string, string>[liveSignals.Length];
|
|
string[] kvp;
|
|
int i = 0;
|
|
foreach (string liveKVP in liveSignals)
|
|
{
|
|
// ogni variabile la splitto come chiave/valore
|
|
kvp = liveKVP.Split(':');
|
|
liveSet[i] = new KeyValuePair<string, string>(kvp[0], kvp[1]);
|
|
i++;
|
|
}
|
|
// salvo in Redis nell'area CURR_VAL TUTTI i valori live
|
|
memLayer.ML.redSaveHash(LiveCurrValHash(idxMacchina), liveSet);
|
|
// accodo in buffer ULTIMI valori con dataora uno ad uno...
|
|
KeyValuePair<string, string>[] newData = new KeyValuePair<string, string>[1];
|
|
foreach (var item in liveSet)
|
|
{
|
|
// accodo update valori...
|
|
newData[0] = new KeyValuePair<string, string>(dataOraEvento.ToString(), item.Value);
|
|
memLayer.ML.redSaveHash(LiveBufferHash(idxMacchina, item.Key), newData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: formato liveData errato (split #)";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: parametri macchina/liveData vuoti";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/liveData";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Processa registrazione di un counter x una data macchina IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="counter">contapezzi</param>
|
|
/// <returns></returns>
|
|
public static string saveCounter(string idxMacchina, string counter)
|
|
{
|
|
if (counter == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(counter));
|
|
}
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("saveCounter");
|
|
}
|
|
string answ = "";
|
|
// inizio processing vero e proprio INPUT...
|
|
if (idxMacchina != null && counter != null)
|
|
{
|
|
if (idxMacchina != "" && counter != "")
|
|
{
|
|
int newCounter = -1;
|
|
int.TryParse(counter, out newCounter);
|
|
// se il conteggio è >= 0 SALVO come nuovo conteggio...
|
|
if (newCounter >= 0)
|
|
{
|
|
// salvo in Redis nell'area CURR_VAL TUTTI i valori live
|
|
memLayer.ML.setRSV(pzCountHash(idxMacchina), counter);
|
|
}
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: parametri macchina/counter vuoti";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/counter";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina">Macchina</param>
|
|
/// <param name="qty">Pezzi da registrare</param>
|
|
/// <returns></returns>
|
|
public static string saveCaricoPezzi(string idxMacchina, string qty)
|
|
{
|
|
// default: 0, non registrato come cautela...
|
|
string answ = "0";
|
|
if (qty == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(qty));
|
|
}
|
|
// controllo per proseguire
|
|
if (!string.IsNullOrEmpty(idxMacchina) && !string.IsNullOrEmpty(qty))
|
|
{
|
|
int numPzIncr = -1;
|
|
int.TryParse(qty, out numPzIncr);
|
|
// se il conteggio è >= 0 SALVO evento...
|
|
if (numPzIncr >= 0)
|
|
{
|
|
// recupero ODL corrente
|
|
var currData = currODLRowTab(idxMacchina);
|
|
// registro evento 120 --> contapezzi in blocco !!!HARD CODED!!! !!!FIXME!!!
|
|
int idxEvento = 120;
|
|
MapoDb.obj.scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, qty);
|
|
}
|
|
// registro in risposta che è andato tutto bene... ovvero la qty richiesta...
|
|
answ = qty;
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/incremento";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Salvataggio su della mappa di memoria dell'IOB x ulteriori impieghi
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="currMemMap"></param>
|
|
/// <returns></returns>
|
|
public static bool setIobMemMap(string idxMacchina, plcMemMap currMemMap)
|
|
{
|
|
bool answ = false;
|
|
// se ho un area memoria valida...
|
|
if (currMemMap != null)
|
|
{
|
|
// salvo!
|
|
string serVal = JsonConvert.SerializeObject(currMemMap);
|
|
memLayer.ML.setRSV(memMapHash(idxMacchina), serVal);
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// GET elenco parametri correnti x IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static List<objItem> getCurrObjItems(string idxMacchina)
|
|
{
|
|
string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina));
|
|
List<objItem> actValues = new List<objItem>();
|
|
if (serVal != null)
|
|
{
|
|
try
|
|
{
|
|
actValues = JsonConvert.DeserializeObject<List<objItem>>(serVal);
|
|
// ordino!
|
|
actValues.Sort((a, b) => (a.name.CompareTo(b.name)));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return actValues;
|
|
}
|
|
/// <summary>
|
|
/// GET elenco parametri che richiedono una WRITE x IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static List<objItem> getCurrObjItemsPendigWrite(string idxMacchina)
|
|
{
|
|
string serVal = memLayer.ML.getRSV(currParametersHash(idxMacchina));
|
|
List<objItem> actValues = new List<objItem>();
|
|
List<objItem> writeValues = new List<objItem>();
|
|
if (serVal != null)
|
|
{
|
|
try
|
|
{
|
|
actValues = JsonConvert.DeserializeObject<List<objItem>>(serVal);
|
|
// cerco e rimuovo parametri sola lettura o SENZA richieste scrittura
|
|
foreach (var item in actValues)
|
|
{
|
|
if (item.writable && !string.IsNullOrEmpty(item.reqValue))
|
|
{
|
|
writeValues.Add(item);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in deserializzazione getIobCurrParam{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return writeValues;
|
|
}
|
|
/// <summary>
|
|
/// SET elenco parametri correnti x IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="currValues"></param>
|
|
/// <returns></returns>
|
|
public static bool setCurrObjItems(string idxMacchina, List<objItem> currValues)
|
|
{
|
|
bool answ = false;
|
|
if (currValues != null)
|
|
{
|
|
string serVal = JsonConvert.SerializeObject(currValues);
|
|
memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal);
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="innovations"></param>
|
|
/// <returns></returns>
|
|
public static bool upsertCurrObjItems(string idxMacchina, List<objItem> innovations)
|
|
{
|
|
bool answ = false;
|
|
if (innovations != null)
|
|
{
|
|
// leggo i valori attuali...
|
|
List<objItem> actValues = getCurrObjItems(idxMacchina);
|
|
// per ogni valore passatomi faccio insert o update
|
|
foreach (var item in actValues)
|
|
{
|
|
// cerco nelle innovazioni SE CI SIA un valore act
|
|
objItem trovato = innovations.Find(obj => obj.uid == item.uid);
|
|
// se non trovato...
|
|
if (trovato == null)
|
|
{
|
|
// aggiungo
|
|
innovations.Add(item);
|
|
}
|
|
}
|
|
// serializzo e salvo
|
|
string serVal = JsonConvert.SerializeObject(innovations);
|
|
memLayer.ML.setRSV(currParametersHash(idxMacchina), serVal);
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Rimuove Key dell'ODL corrente x una data macchina IOB
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string emptyCurrODL(string idxMacchina)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
memLayer.ML.redDelKey(currODLHash(idxMacchina));
|
|
answ = "OK";
|
|
}
|
|
catch
|
|
{
|
|
answ = "KO";
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Processa registrazione ODL corrente x macchina
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="currODL">cod ODL in produzione, se "" --> non c'è...</param>
|
|
/// <returns></returns>
|
|
public static string saveCurrODL(string idxMacchina, string currODL)
|
|
{
|
|
if (currODL == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(currODL));
|
|
}
|
|
// registro conteggio impiego chiamate REDIS
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("saveCurrODL");
|
|
}
|
|
string answ = "";
|
|
// inizio processing vero e proprio INPUT...
|
|
if (idxMacchina != null && currODL != null)
|
|
{
|
|
if (idxMacchina != "" && currODL != "")
|
|
{
|
|
memLayer.ML.setRSV(currODLHash(idxMacchina), currODL, memLayer.ML.CRI("currOdlCacheDur"));
|
|
// registro in risposta che è andato tutto bene...
|
|
answ = "OK";
|
|
}
|
|
else
|
|
{
|
|
string errore = string.Format("Errore: parametri macchina/currODL vuoti ({0}/{1})", idxMacchina, currODL);
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string errore = "Errore: mancano parametri macchina/currODL";
|
|
logger.lg.scriviLog(errore, tipoLog.ERROR);
|
|
answ = errore;
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#region definizioni hash x REDIS
|
|
|
|
/// <summary>
|
|
/// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...)
|
|
/// </summary>
|
|
/// <param name="dataType"></param>
|
|
/// <returns></returns>
|
|
public static string mHash(string dataType)
|
|
{
|
|
return memLayer.ML.redHash(dataType);
|
|
}
|
|
/// <summary>
|
|
/// Hash dati STATUS x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string dtMaccHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("DtMac:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati EXE TASK x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string exeTaskHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("ExeTask:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati OPT PARAMETERS x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string optParHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("OptPar:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati STATUS x la macchina specificata.
|
|
/// - dati ODL
|
|
/// - dati articolo
|
|
/// - dati produzione corrente
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string stMaccHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("StMac:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati COUNTER x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string pzCountHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("PzCount:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati MemoryMap x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string memMapHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("MemMap:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati CurrentParameters x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string currParametersHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("CurrentParameters:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati Current ODL x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string currODLHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("CurrODL:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati Current ODL ROW x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string currOdlRowHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("CurrOdlRow:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati Current StatoMacchina x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string currStatoMaccHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("CurrStatoMacc:{0}", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati tabella AnagStati macchina
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string currAnagStatiMacc()
|
|
{
|
|
return mHash(string.Format("Anag:StatiMacc"));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati LIVE x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string LiveCurrValHash(string idxMacchina)
|
|
{
|
|
return mHash(string.Format("LIVE:{0}:CURR_VAL", idxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati BUFFER x la macchina specificata
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="bufferName"></param>
|
|
/// <returns></returns>
|
|
public static string LiveBufferHash(string idxMacchina, string bufferName)
|
|
{
|
|
return mHash(string.Format("LIVE:{0}:{1}", idxMacchina, bufferName));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati STATE MACHINE INGRESSI x la FAMIGLIA INGRESSI specificata (per completare poi manca singolo micro stato corrente + valore letto x definire chiave)
|
|
/// </summary>
|
|
/// <param name="idxFamIn"></param>
|
|
/// <returns></returns>
|
|
public static string hSMI(int idxFamIn)
|
|
{
|
|
return mHash(string.Format("hSMI:{0}", idxFamIn));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati Macchine Multi SM Ingressi
|
|
/// </summary>
|
|
/// <param name="IdxMacchina">Macchina PRINCIPALE</param>
|
|
/// <returns></returns>
|
|
public static string hMSMI(string IdxMacchina)
|
|
{
|
|
return mHash(string.Format("hMSMI:{0}", IdxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati relativi all'associazione macchina <--> IOB
|
|
/// </summary>
|
|
/// <param name="IdxMacchina">Macchina PRINCIPALE</param>
|
|
/// <returns></returns>
|
|
public static string hM2IOB(string IdxMacchina)
|
|
{
|
|
return mHash(string.Format("hM2IOB:{0}", IdxMacchina));
|
|
}
|
|
/// <summary>
|
|
/// Hash dati MSE
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string hMSE
|
|
{
|
|
get
|
|
{
|
|
return mHash(string.Format("hMSE_DATA"));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione MSE
|
|
|
|
|
|
/// <summary>
|
|
/// Dati MSE serializzati in REDIS (get/set)
|
|
/// </summary>
|
|
public string currMSE
|
|
{
|
|
get
|
|
{
|
|
string answ = "";
|
|
logger.lg.scriviLog("Richiesta MSE da REDIS");
|
|
answ = memLayer.ML.getRSV(hMSE);
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
int MSE_cacheDuration = memLayer.ML.CRI("MSE_cacheDuration");
|
|
memLayer.ML.setRSV(hMSE, value, MSE_cacheDuration);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione task macchina
|
|
|
|
/// <summary>
|
|
/// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> mTaskMacchina(string idxMacchina)
|
|
{
|
|
// hard coded dimensione vettore DatiMacchine
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
// ORA recupero da memoria redis...
|
|
try
|
|
{
|
|
string currHash = exeTaskHash(idxMacchina);
|
|
answ = memLayer.ML.redGetHashDict(currHash);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione dati EXE TASK x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Aggiunge un task all'elenco di quelli salvati (in modalità upsert)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="taskKey"></param>
|
|
/// <param name="taskVal"></param>
|
|
/// <returns></returns>
|
|
public static bool addTask4Machine(string idxMacchina, taskType taskKey, string taskVal)
|
|
{
|
|
bool answ = false;
|
|
string currHash = exeTaskHash(idxMacchina);
|
|
try
|
|
{
|
|
// leggo task attuali...
|
|
var currTask = mTaskMacchina(idxMacchina);
|
|
currTask[taskKey.ToString()] = taskVal;
|
|
answ = memLayer.ML.redSaveHashDict(currHash, currTask);
|
|
logger.lg.scriviLog($"Task ADD - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()} | taskVal: {taskVal}");
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// RIMUOVE un task dall'elenco di quelli salvati
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="taskKey"></param>
|
|
/// <returns></returns>
|
|
public static bool remTask4Machine(string idxMacchina, taskType taskKey)
|
|
{
|
|
bool answ = false;
|
|
string currHash = exeTaskHash(idxMacchina);
|
|
try
|
|
{
|
|
// leggo task attuali...
|
|
var currTask = mTaskMacchina(idxMacchina);
|
|
currTask.Remove(taskKey.ToString());
|
|
memLayer.ML.redDelKey(currHash);
|
|
answ = memLayer.ML.redSaveHashDict(currHash, currTask);
|
|
logger.lg.scriviLog($"Task REM - idxMacchina: {idxMacchina} | taskKey: {taskKey.ToString()}");
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione OPT PARAMETERS macchina
|
|
|
|
/// <summary>
|
|
/// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> mOptParMacchina(string idxMacchina)
|
|
{
|
|
// hard coded dimensione vettore DatiMacchine
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
// ORA recupero da memoria redis...
|
|
try
|
|
{
|
|
string currHash = optParHash(idxMacchina);
|
|
answ = memLayer.ML.redGetHashDict(currHash);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione dati OPT PARAM x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiunge un PARAMETRO OPZIONALE all'elenco di quelli salvati (in modalità upsert)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="taskKey"></param>
|
|
/// <param name="taskVal"></param>
|
|
/// <returns></returns>
|
|
public static bool addOptPar4Machine(string idxMacchina, string taskKey, string taskVal)
|
|
{
|
|
bool answ = false;
|
|
string currHash = optParHash(idxMacchina);
|
|
try
|
|
{
|
|
// leggo task attuali...
|
|
var currVal = mOptParMacchina(idxMacchina);
|
|
currVal[taskKey] = taskVal;
|
|
answ = memLayer.ML.redSaveHashDict(currHash, currVal);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// RIMUOVE un PARAMETRO OPZIONALE dall'elenco di quelli salvati
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="taskKey"></param>
|
|
/// <returns></returns>
|
|
public static bool remOptPar4Machine(string idxMacchina, string taskKey)
|
|
{
|
|
bool answ = false;
|
|
string currHash = optParHash(idxMacchina);
|
|
try
|
|
{
|
|
// leggo task attuali...
|
|
var currVal = mOptParMacchina(idxMacchina);
|
|
currVal.Remove(taskKey);
|
|
memLayer.ML.redDelKey(currHash);
|
|
answ = memLayer.ML.redSaveHashDict(currHash, currVal);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region gestione attrezzaggi
|
|
|
|
public static string forceSplitOdl(string idxMacchina)
|
|
{
|
|
string answ = "KO";
|
|
DS_ProdTempi.ODLDataTable currData = null;
|
|
DateTime adesso = DateTime.Now;
|
|
// chiamo metodo redis/db...
|
|
try
|
|
{
|
|
// recupero ODL corrente
|
|
currData = currODLRowTab(idxMacchina);
|
|
if (currData.Count > 0)
|
|
{
|
|
// registro un evento di inizio attrezzaggio (idxTipoEv = 2)
|
|
int idxEvento = 2;
|
|
logger.lg.scriviLog($"Invio evento ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO);
|
|
inputComando resCmd = MapoDb.obj.scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-SPLIT", 0, "", adesso.AddMinutes(-1), adesso);
|
|
// chiamo splitOdl
|
|
MapoDb.obj.taODL.splitODL(currData[0].IdxODL, 0, idxMacchina, currData[0].TCRichAttr, currData[0].PzPallet, $"Nuovo ODL da forceSplitOdl", true);
|
|
// registro fine ODL (idxTipoEv = 1)
|
|
idxEvento = 1;
|
|
logger.lg.scriviLog($"Invio evento FINE ODL-SPLIT per macchina {idxMacchina}, evento {idxEvento}, articolo {currData[0].CodArticolo}", tipoLog.INFO);
|
|
resCmd = MapoDb.obj.scriviRigaEventoBarcode(idxMacchina, idxEvento, currData[0].CodArticolo, "ODL-START");
|
|
// chiamo refresh MSE
|
|
obj.taMSE.forceRecalc(0, idxMacchina);
|
|
// resetto stato macchina...
|
|
memLayer.ML.redDelKey(currStatoMaccHash(idxMacchina));
|
|
answ = "OK";
|
|
logger.lg.scriviLog($"Effettuato reset e ricalcoli x split ODL per macchina {idxMacchina}", tipoLog.INFO);
|
|
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione stato macchina
|
|
|
|
/// <summary>
|
|
/// Restituisce il valore dell'intera RIGA stato macchina corrente (da redis o da DB se non trovata...)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static DS_applicazione.StatoMacchineDataTable currSMTab(string idxMacchina)
|
|
{
|
|
DS_applicazione.StatoMacchineDataTable answTab = null;
|
|
string rCall = "";
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("hasStatoMacc");
|
|
try
|
|
{
|
|
rCall = memLayer.ML.getRSV(currStatoMaccHash(idxMacchina));
|
|
if (!string.IsNullOrEmpty(rCall))
|
|
{
|
|
answTab = JsonConvert.DeserializeObject<DS_applicazione.StatoMacchineDataTable>(rCall);
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.currStatoMaccTab(idxMacchina);
|
|
// salvo in redis...
|
|
rCall = JsonConvert.SerializeObject(answTab);
|
|
int currStatoMaccCacheDur = memLayer.ML.CRI("currStatoMaccCacheDur");
|
|
memLayer.ML.setRSV(currStatoMaccHash(idxMacchina), rCall, currStatoMaccCacheDur);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.currStatoMaccTab(idxMacchina);
|
|
}
|
|
return answTab;
|
|
}
|
|
/// <summary>
|
|
/// Elenco stati macchina
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static DS_applicazione.AnagraficaStatiDataTable AnagraficaStati()
|
|
{
|
|
DS_applicazione.AnagraficaStatiDataTable answTab = null;
|
|
// cerco in cache...
|
|
string rCall = "";
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("hasAnagStati");
|
|
try
|
|
{
|
|
rCall = memLayer.ML.getRSV(currAnagStatiMacc());
|
|
if (!string.IsNullOrEmpty(rCall))
|
|
{
|
|
answTab = JsonConvert.DeserializeObject<DS_applicazione.AnagraficaStatiDataTable>(rCall);
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.taAnagSt.GetData();
|
|
// salvo in redis...
|
|
rCall = JsonConvert.SerializeObject(answTab);
|
|
int anagrCacheDur = memLayer.ML.CRI("anagrCacheDur");
|
|
memLayer.ML.setRSV(currAnagStatiMacc(), rCall, anagrCacheDur);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.taAnagSt.GetData();
|
|
}
|
|
return answTab;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione dati macchina
|
|
|
|
/// <summary>
|
|
/// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> mDatiMacchine(string idxMacchina)
|
|
{
|
|
// hard coded dimensione vettore DatiMacchine
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
// ORA recupero da memoria redis...
|
|
try
|
|
{
|
|
string currHash = dtMaccHash(idxMacchina);
|
|
answ = memLayer.ML.redGetHashDict(currHash);
|
|
// se è vuoto... leggo da DB e popolo!
|
|
if (answ.Count == 0)
|
|
{
|
|
answ = resetDatiMacchina(idxMacchina);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione dati Macchine x Redis - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Resetta (rileggendo) i dati della macchina
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> resetDatiMacchina(string idxMacchina)
|
|
{
|
|
string currHash = dtMaccHash(idxMacchina);
|
|
// inizio con un bel reset...
|
|
memLayer.ML.redFlushKey(currHash);
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
DS_applicazione.MSFDDataTable tabMSFD = new DS_applicazione.MSFDDataTable();
|
|
// 2018.01.08 SEMPRE senza singleton: instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
tabMSFD = connDb.taMSFD.getByIdxMacc(idxMacchina);
|
|
|
|
// se ho righe...
|
|
DS_applicazione.MSFDDataTable tab = new DS_applicazione.MSFDDataTable();
|
|
DS_applicazione.MSFDRow rigaMSFD;
|
|
if (tabMSFD.Rows.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
rigaMSFD = tabMSFD[0];
|
|
}
|
|
catch
|
|
{
|
|
rigaMSFD = tab.NewMSFDRow();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rigaMSFD = tab.NewMSFDRow();
|
|
}
|
|
// ora provo a compilare...
|
|
try
|
|
{
|
|
// salvo 1:1 i valori... STATO
|
|
answ.Add("IdxMicroStato", rigaMSFD.IdxMicroStato.ToString());
|
|
answ.Add("IdxStato", rigaMSFD.IdxStato.ToString());
|
|
answ.Add("CodArticolo", rigaMSFD.CodArticolo);
|
|
answ.Add("insEnabled", rigaMSFD.insEnabled.ToString());
|
|
answ.Add("sLogEnabled", rigaMSFD.sLogEnabled.ToString());
|
|
answ.Add("pallet", rigaMSFD.pallet);
|
|
answ.Add("CodArticolo_A", rigaMSFD.CodArticolo_A);
|
|
answ.Add("CodArticolo_B", rigaMSFD.CodArticolo_B);
|
|
answ.Add("TempoCicloBase", rigaMSFD.TempoCicloBase.ToString());
|
|
answ.Add("PzPalletProd", rigaMSFD.PzPalletProd.ToString());
|
|
answ.Add("MatrOpr", rigaMSFD.MatrOpr.ToString());
|
|
answ.Add("lastVal", rigaMSFD.lastVal);
|
|
answ.Add("TCBase", rigaMSFD.TempoCicloBase.ToString());
|
|
|
|
//...e SETUP
|
|
answ.Add("CodMacc", rigaMSFD.codmacchina);
|
|
answ.Add("IdxFamIn", rigaMSFD.IdxFamigliaIngresso.ToString());
|
|
answ.Add("Multi", rigaMSFD.Multi.ToString());
|
|
answ.Add("BitFilt", rigaMSFD.BitFilt.ToString());
|
|
answ.Add("MaxVal", rigaMSFD.MaxVal.ToString());
|
|
answ.Add("BSR", rigaMSFD.BSR.ToString());
|
|
answ.Add("ExplodeBit", rigaMSFD.ExplodeBit.ToString());
|
|
answ.Add("NumBit", rigaMSFD.NumBit.ToString());
|
|
answ.Add("IdxFamMacc", rigaMSFD.IdxFamiglia.ToString());
|
|
answ.Add("simplePallet", rigaMSFD.simplePallet.ToString());
|
|
answ.Add("palletChange", rigaMSFD.palletChange.ToString());
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione dati MSFD:{0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
|
|
}
|
|
// verifico il timeout che cambia a seconda che sia vero o falso insEnabled...
|
|
int tOutShort = memLayer.ML.cdvi("TmOut.MS.S");
|
|
int tOutLong = memLayer.ML.cdvi("TmOut.MS.L");
|
|
int redDtMacTOut = (answ["insEnabled"].ToLower() == "true") ? tOutShort : tOutLong;
|
|
// salvo in redis!
|
|
memLayer.ML.redSaveHashDict(currHash, answ, redDtMacTOut);
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore booleano se la macchina sia abilitata all'input
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static bool insEnab(string idxMacchina)
|
|
{
|
|
bool answ = false;
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("insEnabled");
|
|
try
|
|
{
|
|
answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "insEnabled"));
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
// ...oppure dritto su DB
|
|
else
|
|
{
|
|
if (memLayer.ML.CRB("disable_singleton"))
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
answ = connDb.insEnabled(idxMacchina);
|
|
}
|
|
else
|
|
{
|
|
// leggo DB da singleton
|
|
answ = MapoDb.obj.insEnabled(idxMacchina);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore dell'intera RIGA ODL corrente (da redis o da DB se non trovata...)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static DS_ProdTempi.ODLDataTable currODLRowTab(string idxMacchina)
|
|
{
|
|
DS_ProdTempi.ODLDataTable answTab = null;
|
|
string rCall = "";
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("hasODL_row");
|
|
try
|
|
{
|
|
rCall = memLayer.ML.getRSV(currOdlRowHash(idxMacchina));
|
|
if (!string.IsNullOrEmpty(rCall))
|
|
{
|
|
answTab = JsonConvert.DeserializeObject<DS_ProdTempi.ODLDataTable>(rCall);
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.currODLTab(idxMacchina);
|
|
// salvo in redis...
|
|
rCall = JsonConvert.SerializeObject(answTab);
|
|
int currOdlRowCacheDur = memLayer.ML.CRI("currOdlRowCacheDur");
|
|
memLayer.ML.setRSV(currOdlRowHash(idxMacchina), rCall, currOdlRowCacheDur);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog($"Eccezione in recupero currODLRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
answTab = MapoDb.obj.currODLTab(idxMacchina);
|
|
}
|
|
return answTab;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static string currODL(string idxMacchina)
|
|
{
|
|
string answ = "";
|
|
string rCall = "";
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("hasODL");
|
|
try
|
|
{
|
|
rCall = memLayer.ML.getRSV(currODLHash(idxMacchina));
|
|
if (rCall != null && rCall != "")
|
|
{
|
|
answ = rCall;
|
|
}
|
|
else
|
|
{
|
|
answ = MapoDb.obj.currODL(idxMacchina);
|
|
// salvo in redis...
|
|
saveCurrODL(idxMacchina, answ);
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza ODL NO invio/gestione ODL)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="forceDb">indica se forzare lettura da db (true) o meno</param>
|
|
/// <returns></returns>
|
|
public static string currODL(string idxMacchina, bool forceDb)
|
|
{
|
|
string answ = "";
|
|
// faccio comunque verifica se sia stato letto da poco il valore... x cui anche a fronte di richiesta lettura da DB per 3 sec tengo buono valore in cache redis...
|
|
string rKey = memLayer.ML.redHash($"ODL:{idxMacchina}");
|
|
string _idxOdl = memLayer.ML.getRSV(rKey);
|
|
if (forceDb)
|
|
{
|
|
if (_idxOdl != null && _idxOdl != "")
|
|
{
|
|
answ = _idxOdl;
|
|
}
|
|
else
|
|
{
|
|
answ = MapoDb.obj.currODL(idxMacchina);
|
|
// salvo in redis...
|
|
saveCurrODL(idxMacchina, answ);
|
|
memLayer.ML.setRSV(rKey, answ, 3);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
answ = currODL(idxMacchina);
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel Signal Log
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static bool sLogEnab(string idxMacchina)
|
|
{
|
|
bool answ = false;
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("sLogEnabled");
|
|
try
|
|
{
|
|
answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "sLogEnabled"));
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
// ...oppure dritto su DB
|
|
else
|
|
{
|
|
answ = MapoDb.obj.sLogEnabled(idxMacchina);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static int pzCounterTC(string idxMacchina)
|
|
{
|
|
int answ = -1;
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("getCounterTC");
|
|
}
|
|
// variabile x controllo dati recuperati
|
|
DS_ProdTempi.StatoProdDataTable datiProdAct = null;
|
|
bool odlFound = false;
|
|
int taSP_ms_ant = memLayer.ML.cdvi("taStatoProd_ms_anticipo");
|
|
DateTime dataRif = DateTime.Now.AddMilliseconds(-taSP_ms_ant);
|
|
odlFound = getStatoProd(idxMacchina, ref datiProdAct, dataRif);
|
|
// se NON avesse recuperato --> aspetto taSP_ms_ant e poi RICHIAMO procedura...
|
|
int maxTry = 3;
|
|
while (!odlFound && maxTry > 0)
|
|
{
|
|
logger.lg.scriviLog(string.Format("[pzCounterTC] Impossibile recuperare dati ODL x idxMacchina {0}", idxMacchina), tipoLog.ERROR);
|
|
// sleep...
|
|
System.Threading.Thread.Sleep(taSP_ms_ant);
|
|
// riprovo lettura...
|
|
odlFound = getStatoProd(idxMacchina, ref datiProdAct, dataRif);
|
|
maxTry--;
|
|
}
|
|
|
|
// ora proseguo SE ho trovato i dati...
|
|
if (odlFound)
|
|
{
|
|
// ...a questo punto recupero DAVVERO i dati (o almeno ci provo...)
|
|
try
|
|
{
|
|
// controllo
|
|
answ = datiProdAct[0].PzTotODL;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("[pzCounterTC] Eccezione in recupero PzTotODL x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger.lg.scriviLog(string.Format("[pzCounterTC] Dati ODL x idxMacchina {0} non recuperati dopo tentativi reiterati...", idxMacchina), tipoLog.ERROR);
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Recupero dati stato prod da macchina...
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="datiProdAct"></param>
|
|
/// <param name="dataRif"></param>
|
|
/// <returns></returns>
|
|
private static bool getStatoProd(string idxMacchina, ref DS_ProdTempi.StatoProdDataTable datiProdAct, DateTime dataRif)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// recupero con stored NUOVA...
|
|
datiProdAct = DataLayer.obj.taStatoProd.GetData(idxMacchina, dataRif);
|
|
if (datiProdAct.Rows.Count > 0)
|
|
{
|
|
// solo SE ho idxODL (altrimenti loggo errore)
|
|
if (datiProdAct[0].IdxOdl > 0)
|
|
{
|
|
answ = true;
|
|
}
|
|
else
|
|
{
|
|
// verifico se ho già questo errore attivo IN REDIS (altrimenti reinvio)
|
|
logger.lg.scriviLog(string.Format("pzCounterTC: Non trovato currODL x idxMacchina {0} | IdxOdl {1} | pzTot {2} | dataRif {3}", idxMacchina, datiProdAct[0].IdxOdl, datiProdAct[0].PzTotODL, dataRif), tipoLog.WARNING);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger.lg.scriviLog("pzCounterTC: Non trovate righe in currODL x idxMacchina " + idxMacchina + ": datiProdAct vuota", tipoLog.WARNING);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("[pzCounterTC] Eccezione in pzCounterTC x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il contapezzi salvato per la macchina
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static int pzCounter(string idxMacchina)
|
|
{
|
|
int answ = -1;
|
|
string rCall = "";
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("getCounter");
|
|
try
|
|
{
|
|
rCall = memLayer.ML.getRSV(pzCountHash(idxMacchina));
|
|
if (rCall != "" && rCall != null)
|
|
{
|
|
int.TryParse(rCall, out answ);
|
|
}
|
|
else
|
|
{
|
|
answ = pzCounterTC(idxMacchina);
|
|
// salvo in redis...
|
|
saveCounter(idxMacchina, answ.ToString());
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI)
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static bool isMulti(string idxMacchina)
|
|
{
|
|
bool answ = false;
|
|
if (memLayer.ML.CRB("IOB_RedEnab"))
|
|
{
|
|
saveCallRec("isMulti");
|
|
try
|
|
{
|
|
answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "Multi") == "1");
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
// ...oppure dritto su DB
|
|
else
|
|
{
|
|
answ = MapoDb.obj.isMulti(idxMacchina);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region gestione State Machine Ingressi
|
|
|
|
|
|
/// <summary>
|
|
/// Recupera (da DB) i dati della State Machine multi ingressi nel formato
|
|
/// key: IdxMacchina
|
|
/// value: IdxFamigliaIngresso
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] getMSMI_DB(string idxMacchina)
|
|
{
|
|
DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable();
|
|
// 2017.09.13: inserisco gestione singleton condizionale
|
|
if (memLayer.ML.CRB("disable_singleton"))
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
tabMSMI = connDb.taMSFD.getMulti(idxMacchina);
|
|
}
|
|
else
|
|
{
|
|
// leggo DB da singleton
|
|
tabMSMI = MapoDb.obj.taMSFD.getMulti(idxMacchina);
|
|
}
|
|
KeyValuePair<string, string>[] answ = new KeyValuePair<string, string>[tabMSMI.Count];
|
|
// salvo tutti i valori StateMachineIngressi...
|
|
int i = 0;
|
|
foreach (var item in tabMSMI)
|
|
{
|
|
answ[i] = new KeyValuePair<string, string>(item.IdxMacchina, item.IdxFamigliaIngresso.ToString());
|
|
i++;
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restitusice elenco KVP
|
|
/// key: IdxMacchina
|
|
/// value: IdxFamigliaIngresso
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] mTabMSMI(string idxMacchina)
|
|
{
|
|
// hard coded dimensione vettore DatiMacchine
|
|
KeyValuePair<string, string>[] answ = new KeyValuePair<string, string>[1];
|
|
// iniziualizzo con un valore... 0/0
|
|
answ[0] = new KeyValuePair<string, string>("0", "0");
|
|
// ORA recupero da memoria redis...
|
|
try
|
|
{
|
|
string currHash = hMSMI(idxMacchina);
|
|
answ = memLayer.ML.redGetHash(currHash);
|
|
// se è vuoto... leggo da DB e popolo!
|
|
if (answ.Length == 0)
|
|
{
|
|
answ = resetMSMI(idxMacchina);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Resetta (rileggendo) i dati della State Machine multi ingressi nel formato
|
|
/// key: IdxMacchina
|
|
/// value: IdxFamigliaIngresso
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] resetMSMI(string idxMacchina)
|
|
{
|
|
string currHash = hMSMI(idxMacchina);
|
|
DS_applicazione.MSFDDataTable tabMSMI = new DS_applicazione.MSFDDataTable();
|
|
// 2017.09.13: inserisco gestione singleton condizionale
|
|
if (memLayer.ML.CRB("disable_singleton"))
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
tabMSMI = connDb.taMSFD.getMulti(idxMacchina);
|
|
}
|
|
else
|
|
{
|
|
// leggo DB da singleton
|
|
tabMSMI = MapoDb.obj.taMSFD.getMulti(idxMacchina);
|
|
}
|
|
KeyValuePair<string, string>[] answ = new KeyValuePair<string, string>[tabMSMI.Count];
|
|
// salvo tutti i valori StateMachineIngressi...
|
|
int i = 0;
|
|
foreach (var item in tabMSMI)
|
|
{
|
|
answ[i] = new KeyValuePair<string, string>(item.IdxMacchina, item.IdxFamigliaIngresso.ToString());
|
|
i++;
|
|
}
|
|
// verifico il timeout (default 60 sec...)
|
|
int tOut = (memLayer.ML.cdvi("TmOut.MSMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.MSMI");
|
|
// salvo in redis!
|
|
memLayer.ML.redSaveHash(currHash, answ, tOut);
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restitusice elenco KVP dei campi della State Machine ingressi nel formato
|
|
/// key: cState_nVal (current MICRO-STATE + "_" + new Value)
|
|
/// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE
|
|
/// </summary>
|
|
/// <param name="idxFamIn"></param>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] mTabSMI(int idxFamIn)
|
|
{
|
|
// hard coded dimensione vettore DatiMacchine
|
|
KeyValuePair<string, string>[] answ = new KeyValuePair<string, string>[1];
|
|
// iniziualizzo con un valore... 0/0
|
|
answ[0] = new KeyValuePair<string, string>("0", "0");
|
|
// ORA recupero da memoria redis...
|
|
try
|
|
{
|
|
string currHash = hSMI(idxFamIn);
|
|
answ = memLayer.ML.redGetHash(currHash);
|
|
// se è vuoto... leggo da DB e popolo!
|
|
if (answ.Length == 0)
|
|
{
|
|
answ = resetSMI(idxFamIn);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
logger.lg.scriviLog(string.Format("Errore in compilazione State Machine Ingressi x Redis:{0}{1}", Environment.NewLine, exc));
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Resetta (rileggendo) i dati della State Machine ingressi nel formato
|
|
/// key: cState_nVal (current MICRO-STATE + "_" + new Value)
|
|
/// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
|
|
/// </summary>
|
|
/// <param name="idxFamIn"></param>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] resetSMI(int idxFamIn)
|
|
{
|
|
string currHash = hSMI(idxFamIn);
|
|
DS_applicazione.TransizioneIngressiDataTable tabSMI = new DS_applicazione.TransizioneIngressiDataTable();
|
|
// 2017.09.13: inserisco gestione singleton condizionale
|
|
if (memLayer.ML.CRB("disable_singleton"))
|
|
{
|
|
// instanzio un nuovo oggetto MapoDb
|
|
MapoDb connDb = new MapoDb();
|
|
tabSMI = connDb.taTransIngr.getByIdxFamIng(idxFamIn);
|
|
}
|
|
else
|
|
{
|
|
// leggo DB da singleton
|
|
tabSMI = MapoDb.obj.taTransIngr.getByIdxFamIng(idxFamIn);
|
|
}
|
|
KeyValuePair<string, string>[] answ = new KeyValuePair<string, string>[tabSMI.Count];
|
|
// salvo tutti i valori StateMachineIngressi...
|
|
int i = 0;
|
|
string key = "";
|
|
string val = "";
|
|
foreach (var item in tabSMI)
|
|
{
|
|
key = string.Format("{0}_{1}", item.IdxMicroStato, item.ValoreIngresso);
|
|
val = string.Format("{0}_{1}", item.IdxTipoEvento, item.next_IdxMicroStato);
|
|
answ[i] = new KeyValuePair<string, string>(key, val);
|
|
i++;
|
|
}
|
|
// verifico il timeout (default 60 sec...)
|
|
int tOut = (memLayer.ML.cdvi("TmOut.SMI") <= 0) ? 60 : memLayer.ML.cdvi("TmOut.SMI");
|
|
// salvo in redis!
|
|
memLayer.ML.redSaveHash(currHash, answ, tOut);
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il valore SPECIFICATO per la state machine ingressi
|
|
/// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
|
|
/// </summary>
|
|
/// <param name="idxFamIn"></param>
|
|
/// <param name="idxMicroStato"></param>
|
|
/// <param name="valoreIn"></param>
|
|
/// <returns></returns>
|
|
public static string valoreSMI(int idxFamIn, int idxMicroStato, int valoreIn)
|
|
{
|
|
string currHash = hSMI(idxFamIn);
|
|
string field = string.Format("{0}_{1}", idxMicroStato, valoreIn);
|
|
return memLayer.ML.redGetHashField(currHash, field);
|
|
}
|
|
/// <summary>
|
|
/// Restituisce valore di una singola chiave del dizionario DatiMacchina
|
|
/// </summary>
|
|
/// <param name="idxMacchina"></param>
|
|
/// <param name="chiave"></param>
|
|
/// <returns></returns>
|
|
public static string mDatiMacchinaVal(string idxMacchina, string chiave)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = mDatiMacchine(idxMacchina)[chiave];
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
#if false
|
|
|
|
/// <summary>
|
|
/// Elenco task ammessi (x IOB-WIN da eseguire...)
|
|
/// </summary>
|
|
public enum taskType
|
|
{
|
|
/// <summary>
|
|
/// Task nullo / fake
|
|
/// </summary>
|
|
nihil,
|
|
/// <summary>
|
|
/// Rimanda a PLC eventuale segnale NON in setup (MA NON RESETTA)
|
|
/// </summary>
|
|
fixStopSetup,
|
|
/// <summary>
|
|
/// Indica al PLC di forzare il reset del contapezzi
|
|
/// </summary>
|
|
forceResetPzCount,
|
|
/// <summary>
|
|
/// Indica al PLC di forzare il NUOVO valore di contapezzi (impostato come value)
|
|
/// </summary>
|
|
forceSetPzCount,
|
|
/// <summary>
|
|
/// Imposta Articolo su PLC
|
|
/// </summary>
|
|
setArt,
|
|
/// <summary>
|
|
/// Imposta Commessa su PLC
|
|
/// </summary>
|
|
setComm,
|
|
/// <summary>
|
|
/// Set Programma CNC su PLC
|
|
/// </summary>
|
|
setProg,
|
|
/// <summary>
|
|
/// Indica al PLC iniziato setup (e secondo casi ferma contapezzi /resetta)
|
|
/// </summary>
|
|
startSetup,
|
|
/// <summary>
|
|
/// Indica al PLC finito setup (e secondo casi ferma contapezzi /resetta)
|
|
/// </summary>
|
|
stopSetup,
|
|
/// <summary>
|
|
/// Richiesta invio watchdog a PLC
|
|
/// </summary>
|
|
sendWatchDogMes2Plc
|
|
}
|
|
public enum tipoSelettore
|
|
{
|
|
articoli
|
|
}
|
|
|
|
#endif |