using Newtonsoft.Json; using SteamWare; using System; using System.Collections.Generic; namespace AppData { /// /// Classe con metodi di supporto per COMUNICAZIONE /// public class ComLib { /// /// Wrapper traduzione termini /// /// /// public static string traduci(string lemma) { return user_std.UtSn.Traduci(lemma); } #region conf posizioni redis protected static string redOutPath = "NKC:SERV:BREQ"; protected static string redMsgCount = "NKC:SERV:BREQ:MCount"; protected static string redMsgList = "NKC:SERV:BREQ:MList"; protected static string redMLCurrStack = "NKC:SERV:TAKT:CurrStack"; #endregion #region definizione classi impiegate con PROD /// /// Stati degli oggetti TAKT e Stack /// public enum CStatus { /// /// Programmato /// Programmed = 0, /// /// In corso /// Running, /// /// Completato /// Done } /// /// Stati degli oggetti Batch /// public enum BatchStatus { /// /// CSV importato /// Imported = 0, /// /// Nesting richiesto (In corso) /// EstimationRequested, /// /// Nesting Completato /// EstimationDone, /// /// Nesting richiesto (In corso) /// NestRequested, /// /// Nesting Completato /// NestDone, /// /// Nesting approvato /// Approved, /// /// Nesting scartato /// Discarded } /// /// Posizione / Activity degli oggetti Batch /// public enum BatchPosition { /// /// Non iniziato /// NotStarted = 0, /// /// Stack In corso /// StackStarted, /// /// Stack Completato /// StackDone, /// /// Stack currently in LOAD /// Current, /// /// Stack completed /// Completed } public static string PositionStatusDescr(object value) { string answ = ""; try { ComLib.BatchPosition pStatus = (ComLib.BatchPosition)Enum.Parse(typeof(ComLib.BatchPosition), value.ToString()); switch (pStatus) { case BatchPosition.NotStarted: answ = traduci("NotStarted"); break; case BatchPosition.StackStarted: answ = traduci("Stacking"); break; case BatchPosition.StackDone: answ = traduci("StackDone"); break; default: break; } } catch { } return answ; } public static string BatchStatusDescr(object value) { string answ = ""; try { ComLib.BatchStatus bStatus = (ComLib.BatchStatus)Enum.Parse(typeof(ComLib.BatchStatus), value.ToString()); switch (bStatus) { case BatchStatus.Imported: answ = "Imported"; break; case BatchStatus.EstimationRequested: answ = "Estimation Requested"; break; case BatchStatus.EstimationDone: answ = "Estimation Completed"; break; case BatchStatus.NestRequested: answ = "Nesting Requested"; break; case BatchStatus.NestDone: answ = "Nesting Completed"; break; case BatchStatus.Approved: answ = "Nesting Approved"; break; case BatchStatus.Discarded: answ = "Nesting Discarded"; break; default: break; } } catch { } return answ; } /// /// Stati degli oggetti PANEL/SHEET /// public enum PStatus { /// /// Programmato /// Programmed = 0, /// /// Presente / letto su PROD e pronto su scissor lift /// Present, /// /// Stampa in corso /// Printing, /// /// Stampa completata /// Printed, /// /// Lavorazione in corso /// Machining, /// /// Lavorazione completata /// Machined, /// /// Completato / scaricato da macchina (anche su tavola di scarico) /// Out } /// /// dati del materiale /// public class MaterialData { /// /// Identificativo univoco del materiale (DA ANAGRAFICA db) /// public int MaterialId { get; set; } /// /// Codice P/N del materiale (cliente) /// public string MaterialPN { get; set; } /// /// Codice P/N del materiale (cliente) /// public string MaterialDescription { get; set; } } /// /// Dati delal lavorazione /// public class WorkData { /// /// Percorso del programma da eseguire /// public string ProgramPath { get; set; } /// /// Data inizio processing /// public DateTime DtStart { get; set; } /// /// Data fine processing /// public DateTime DtEnd { get; set; } /// /// Tempo di lavorazione in minuti decimali /// public double WorkTimeMin { get { double answ = 0; if (DtStart != null && DtEnd != null) { try { answ = DtEnd.Subtract(DtStart).TotalMinutes; } catch { } } return answ; } } } /// /// Singolo Pannello da lavorare /// public class Panel { /// /// Identificativo univoco pannello /// public int PanelId { get; set; } /// /// Materiale /// public MaterialData Material { get; set; } /// /// Stato del pannello /// public PStatus Status { get; set; } /// /// Tempi processo x fase printing /// public WorkData Printing { get; set; } /// /// Tempi processo x fase CNC /// public WorkData Machining { get; set; } /// /// Tempi processo x scarico /// public WorkData Unloading { get; set; } } /// /// Classe che rappresenta gli stack da lavorare /// public class WStack { /// /// Identificativo univoco stack /// public int StackId { get; set; } /// /// Stato dello Stack di pannelli /// public CStatus Status { get; set; } /// /// Codice dataMAtrix dello stack /// public string DataMatrix { get; set; } /// /// Data inizio processing dello Stack /// public DateTime DtStart { get; set; } /// /// Data inizio processing dello Stack /// public DateTime DtEnd { get; set; } /// /// Elenco dei pannelli(sheets) dello Stack /// public List PanelsList { get; set; } /// /// Numero di Panels da lavorare /// public int NumPanels { get { int answ = 0; try { answ = PanelsList.Count; } catch { } return answ; } } } /// /// Oggetto globale TAKT /// public class Takt { /// /// Codice univoco oggetto TAKT (data.num) /// public string TaktId { get; set; } /// /// Stato del TAKT /// public CStatus Status { get; set; } /// /// Elenco degli Stack da lavorare /// public List StackList { get; set; } /// /// Numero di Stack da lavorare /// public int NumStack { get { int answ = 0; try { answ = StackList.Count; } catch { } return answ; } } } #endregion #region definizione classi impiegate con NEST public class Parte { public int PartId { get; set; } public string DataMatrix { get; set; } public string ExtCode { get; set; } public string Description { get; set; } public int MatId { get; set; } public string PostProc { get; set; } public string ProcessReq { get; set; } public string CadFilePath { get; set; } public int Qty { get; set; } } /// /// Classe gestione richeiste di processing per il NESTING /// public class Ordine { public string OrdCod { get; set; } public string DestPlant { get; set; } public string DataMatrix { get; set; } public string ExtCode { get; set; } public string Model { get; set; } public int Qty { get; set; } public List Items { get; set; } } public class Batch { /// /// ID del batch in esecuzione /// public int BatchId { get; set; } /// /// tempo amssimo eprmesso x nesting (minuti) /// public int maxTime { get; set; } /// /// Tipo di processing richeisto /// public int procType { get; set; } /// /// Elenco degli ordini /// public List Orders { get; set; } } /// /// Salva su redis l'oggetto dei materiali serializzato /// /// public static bool sendMaterials() { bool answ = false; // leggo tab MNATERIALS da DB var table = DataLayer.man.taMat.GetData(); // serializzo string redVal = JsonConvert.SerializeObject(table); // salvo string redKey = $"NKC:SERV:CONF:MATERIALS"; // scrivo per ora solo su REDIS memLayer.ML.setRSV(redKey, redVal); return answ; } /// /// Restituisce il prossimo codice di envelope per comunicare con sistemi esterni /// /// Batch contenuto nell'envelope /// note opzionali (motivo envelope) /// public static string getNextEnv(int BatchID, string note) { // incremento counter long nextIndex = memLayer.ML.setRCntI(redMsgCount); // salvo contenuto della busta string answ = $"Z{nextIndex:000000000000}"; Dictionary lista = new Dictionary(); lista.Add(answ, $"{BatchID}|{note}"); memLayer.ML.redSaveHashDict(redMsgList, lista); // ritorno return answ; } /// /// Invia una richiesta di esecuzione di Nesting x un Batch /// /// Batch di cui si chiede processing /// note opzionali /// public static bool sendBatchReq(int BatchID, string note) { bool answ = false; // per prima cosa mi serve una "nuova busta" per inviare i messaggi string nextEnv = getNextEnv(BatchID, note); // preparo il contenuto della busta ed invio i messaggi... try { // in base allo stato del BATCH corrente determino il tempo e le opzioni da inviare... var batch = DataLayer.man.taBL.getByKey(BatchID); int mTime = 1; int pType = 1; if (batch[0].STATUS < (int)BatchStatus.EstimationDone) { mTime = memLayer.ML.cdvi("estimMaxTime"); } else { mTime = memLayer.ML.cdvi("nestMaxTime"); pType = 2; } // leggo tab ORDINI da DB var tblOrd = DataLayer.man.taOL.getByBatch(BatchID); // serializzo string redVal = JsonConvert.SerializeObject(tblOrd); // salvo string redKey = $"{redOutPath}:{nextEnv}:ORDERS"; // scrivo su REDIS memLayer.ML.setRSV(redKey, redVal); var tblItm = DataLayer.man.taIL.getByBatch(BatchID); // serializzo redVal = JsonConvert.SerializeObject(tblItm); // salvo redKey = $"{redOutPath}:{nextEnv}:ITEMS"; // scrivo su REDIS memLayer.ML.setRSV(redKey, redVal); // ora versione gerarchica var currBatch = new Batch() { BatchId = BatchID, maxTime = mTime, procType = pType }; // serializzo redVal = JsonConvert.SerializeObject(currBatch); // salvo redKey = $"{redOutPath}:{nextEnv}:DATA"; // scrivo su REDIS memLayer.ML.setRSV(redKey, redVal); // invio notifica che c'è una busta da processare redKey = $"{redOutPath}:CURR"; // scrivo su REDIS memLayer.ML.setRSV(redKey, nextEnv); answ = true; } catch { } // restituisco ok return answ; } #endregion #region metodi helper di conversione /// /// Helper x serializzare l'oggetto /// /// /// public static string serializeTakt(Takt currData) { string answ = JsonConvert.SerializeObject(currData); return answ; } /// /// Helper x deserializzare l'oggetto /// /// /// public static Takt deserializeTakt(string rawData) { Takt answ = JsonConvert.DeserializeObject(rawData); return answ; } #endregion #region metodi x data persistence /// /// Salvo il Takt inviato /// /// Origine del dato: SERV / PROD / NEST /// /// public static bool saveTakt(string origin, Takt currData) { bool answ = false; try { // calcolo valori redis string redKey = $"NKC:{origin.ToUpper()}:TAKT:{currData.TaktId}"; string redVal = serializeTakt(currData); // scrivo per ora solo su REDIS memLayer.ML.setRSV(redKey, redVal); answ = true; } catch { } return answ; } /// /// Salvo il Takt inviato /// /// Origine del dato: SERV / PROD / NEST /// /// public static Takt readTakt(string origin, string TaktId) { Takt answ = null; try { string redKey = $"NKC:{origin.ToUpper()}:TAKT:{TaktId}"; string redVal = memLayer.ML.getRSV(redKey); answ = deserializeTakt(redVal); } catch { } return answ; } #endregion #region metodi per PROD /// /// Fornisce il prossimo TAKT da elaborare oppure null se non ce ne fossero altri da elaborare per la data CORRENTE /// /// public Takt prodGetNextTakt() { return null; } /// /// Valore dello Stack correntemente in processing per ML (MachineLoad) /// public static string taktMLCurrStack { get { return memLayer.ML.getRSV(redMLCurrStack); } set { memLayer.ML.setRSV(redMLCurrStack, value); } } #endregion } }