Files
MoonPro.net/MapoDb/DataLayer.cs
T
2017-10-03 10:33:53 +02:00

860 lines
35 KiB
C#

using SteamWare;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Globalization;
using System.Reflection;
using System.Threading;
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.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;
// 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;
public DS_ProdTempiTableAdapters.DatiConfermatiTableAdapter taDatiConfermati;
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.ProduzioneAs400TableAdapter taAs400;
// table adapter x utility
public DS_UtilityTableAdapters.v_selArticoliTableAdapter taSelArt;
public DS_UtilityTableAdapters.v_selODLTableAdapter taSelOdlFree;
public DS_UtilityTableAdapters.CommentiTableAdapter taComm;
/// <summary>
/// init dei table adapters
/// </summary>
protected void initTA()
{
// istanzio oggetto
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();
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();
taDatiConfermati = new DS_ProdTempiTableAdapters.DatiConfermatiTableAdapter();
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();
taAs400 = new DS_ProdTempiTableAdapters.ProduzioneAs400TableAdapter();
taSelArt = new DS_UtilityTableAdapters.v_selArticoliTableAdapter();
taSelOdlFree = new DS_UtilityTableAdapters.v_selODLTableAdapter();
taComm = new DS_UtilityTableAdapters.CommentiTableAdapter();
}
/// <summary>
/// effettua setup dei connection strings da web.config delal singola applicazione
/// </summary>
protected virtual void setupConnectionStringBase()
{
string connectionString = memLayer.ML.confReadString("MoonProConnectionString");
// connections del db
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;
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;
taDatiConfermati.Connection.ConnectionString = connectionString;
taPzProd2conf.Connection.ConnectionString = connectionString;
taTempiCicloRilevati.Connection.ConnectionString = connectionString;
taDatiProd.Connection.ConnectionString = connectionString;
taTempoByClass.Connection.ConnectionString = connectionString;
taCalFF.Connection.ConnectionString = connectionString;
taMSE.Connection.ConnectionString = connectionString;
taAs400.Connection.ConnectionString = connectionString;
taSelArt.Connection.ConnectionString = connectionString;
taSelOdlFree.Connection.ConnectionString = connectionString;
taComm.Connection.ConnectionString = connectionString;
}
#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(taQL, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taQFQ, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taQRM, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taRMD, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taSCL, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taVSCli, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taVSItm, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taVSRM, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taRPT, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taO4I, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taOH, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
//SetAllCommandTimeouts(taSC2C, memLayer.ML.confReadInt("sqlLongCommandTimeout"));
SetAllCommandTimeouts(taComm, memLayer.ML.confReadInt("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 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>
/// <returns></returns>
public bool confermaProdMacchina(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto)
{
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, 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.confReadString("_smtpCli");
mittente = memLayer.ML.confReadString("_fromEmail");
oggetto = "Link autorizzazione device per GPW";
baseUrl = memLayer.ML.confReadString("baseUrl");
baseWebUrl = memLayer.ML.confReadString("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.confReadString("_fromEmail");
oggetto = memLayer.ML.confReadString("oggettoChgTc");
pageUrl = string.Format("{0}{1}", memLayer.ML.confReadString("baseUrlAdmin"), memLayer.ML.confReadString("pageUrlApprODL"));
corpo = string.Format(memLayer.ML.confReadString("corpoChgTc"), Environment.NewLine, pageUrl);
if (memLayer.ML.confReadBool("_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.confReadString("dominio");
string UsrName = memLayer.ML.confReadString("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.confReadString("dominio");
UsrName = memLayer.ML.confReadString("user");
}
string Secret = authProxy.getSecret(Dominio, UsrName, matricola, DeviceName, adesso);
string devSecret = SteamCrypto.EncryptString(Secret, memLayer.ML.confReadString("cookieName"));
try
{
// creo device + cookie!
fatto = authProxy.createNewCookie(Dominio, UsrName, matricola, DeviceName, Description, IPv4, memLayer.ML.confReadString("cookieName"), DateTime.Now.AddDays(memLayer.ML.confReadInt("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.confReadString("cookieName"), DateTime.Now.AddDays(memLayer.ML.confReadInt("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 = (DS_applicazione.AnagraficaOperatoriRow)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)
{
// 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"))
{
// conto la richiesta nel contatore REDIS
long nCall = memLayer.ML.setRCntI(mHash("COUNT:processInput"));
//... se == nCall2Log scrivo su log e resetto
long nCall2Log = memLayer.ML.cdvi("nCall2Log");
if (nCall >= nCall2Log)
{
// loggo
logger.lg.scriviLog(string.Format("processInput: effettuate {0} call", nCall), tipoLog.INFO);
// resetto!
memLayer.ML.resetRCnt(mHash("COUNT:processInput"));
}
}
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 != "")
{
// 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 encessario, altrimenti è in cache...)
connDb.scriviKeepAlive(idxMacchina, DateTime.Now);
// ora processo e salvo il valore del microstato... INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
connDb.checkMicroStato(idxMacchina, valore, dataOraEvento, contatore);
// verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro....
// registro in risposta che è andato tutto bene...
answ = "OK";
}
catch (Exception exc)
{
if (memLayer.ML.confReadInt("_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);
// ora processo e salvo il valore del microstato...
MapoDb.obj.checkMicroStato(idxMacchina, valore, dataOraEvento, contatore);
// verifico se sia una macchina MULTI ed in tal caso calcolo i SUB-systems e CHIAMERO' alla fine pure loro....
answ = "OK"; // registro in risposta che è andato tutto bene...
}
catch (Exception exc)
{
if (memLayer.ML.confReadInt("_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;
}
#region definizioni hash x REDIS
/// <summary>
/// Hash Redis contenente i dati MP di una specifico TYPE (es StsatusMacchina, 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 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));
}
#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:{0}{1}", Environment.NewLine, exc));
}
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();
// 2017.09.13: inserisco gestione singleton condizionale
if (memLayer.ML.CRB("disable_singleton"))
{
// instanzio un nuovo oggetto MapoDb
MapoDb connDb = new MapoDb();
tabMSFD = connDb.taMSFD.getByIdxMacc(idxMacchina);
}
else
{
tabMSFD = MapoDb.obj.taMSFD.getByIdxMacc(idxMacchina);
}
try
{
DS_applicazione.MSFDRow rigaMSFD = tabMSFD[0];
// 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("BSR", rigaMSFD.BSR.ToString());
answ.Add("IdxFamMacc", rigaMSFD.IdxFamiglia.ToString());
answ.Add("simplePallet", rigaMSFD.simplePallet.ToString());
answ.Add("palletChange", rigaMSFD.palletChange.ToString());
}
catch
{ }
// 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"))
{
// conto la richiesta nel contatore REDIS
long nCall = memLayer.ML.setRCntI(mHash("COUNT:insEnabled"));
//... se == nCall2Log scrivo su log e resetto
long nCall2Log = memLayer.ML.cdvi("nCall2Log");
if (nCall >= nCall2Log)
{
// loggo
logger.lg.scriviLog(string.Format("insEnabled: effettuate {0} call", nCall), tipoLog.INFO);
// resetto!
memLayer.ML.resetRCnt(mHash("COUNT: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 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"))
{
// conto la richiesta nel contatore REDIS
long nCall = memLayer.ML.setRCntI(mHash("COUNT:sLogEnabled"));
//... se == nCall2Log scrivo su log e resetto
long nCall2Log = memLayer.ML.cdvi("nCall2Log");
if (nCall >= nCall2Log)
{
// loggo
logger.lg.scriviLog(string.Format("sLogEnabled: effettuate {0} call", nCall), tipoLog.INFO);
// resetto!
memLayer.ML.resetRCnt(mHash("COUNT:sLogEnabled"));
}
try
{
answ = Convert.ToBoolean(mDatiMacchinaVal(idxMacchina, "sLogEnabled"));
}
catch
{ }
}
// ...oppure dritto su DB
else
{
answ = MapoDb.obj.sLogEnabled(idxMacchina);
}
return answ;
}
#endregion
#region gestione State Machine Ingressi
/// <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
}
}
public enum tipoSelettore
{
articoli
}