using CMS_CORE_Library.Models; using System; using System.Collections.Generic; using System.IO; using System.Linq; using Thermo.Active.Database.Controllers; using Thermo.Active.Model.DTOModels; using Thermo.Active.Model.DTOModels.JobModels; using Thermo.Active.Utils; using static CMS_CORE_Library.Models.DataStructures; using static Thermo.Active.Config.ServerConfig; using static Thermo.Active.Database.Controllers.QueueController; using static Thermo.Active.Model.Constants; using Newtonsoft.Json; using System.Xml; using Thermo.Active.Model.DTOModels.ThRecipe; namespace Thermo.Active.NC { public class NcFileAdapter : NcAdapter { /// /// Recipe Live data /// public static LiveData RecipeLiveData = new LiveData(); /// /// Read file from local devices ad give back string content /// /// /// /// public CmsError ReadFileContent(string path, out string fileContent) { // init fileContent = ""; if (!string.IsNullOrEmpty(path)) { // check existing if (File.Exists(path)) { // read all lines as string fileContent = File.ReadAllText(path); } else { return FILE_NOT_FOUND_ERROR; } } else { return FILE_NOT_FOUND_ERROR; } return NO_ERROR; } /// /// Save string content to file /// /// /// /// public CmsError WriteFileContent(string path, string fileContent) { if (!string.IsNullOrEmpty(path)) { if (!string.IsNullOrEmpty(fileContent)) { File.WriteAllText(path, fileContent); } } else { return FILE_NOT_FOUND_ERROR; } return NO_ERROR; } public CmsError GetFileList(string path, out List fileList) { fileList = new List(); return numericalControl.FILES_RGetFileList(path, ref fileList); } public CmsError GetFileInfo(string path, out InfoFile fileInfo) { fileInfo = new InfoFile(); // if (FileExistWithNc(path)) // libraryError = LocalPartProgramFileInfo(path, out fileInfo); // else // libraryError = numericalControl.FILES_RGetFileInfo(path, ref fileInfo); CmsError libraryError = numericalControl.FILES_RGetFileInfo(path, ref fileInfo); if (libraryError.IsError()) return libraryError; string[] names = fileInfo.Name.Split('/'); if (names.Length > 0) { string name = names.Last(); if (!String.IsNullOrWhiteSpace(name)) fileInfo.PreviewBase64 = SupportFunctions.GetImageBase64String(PART_PRG_IMAGES, name); } return NO_ERROR; } public bool FileExistWithNc(string path) { if (NcConfig.NcVendor != NC_VENDOR.SIEMENS && NcConfig.NcVendor != NC_VENDOR.FANUC) { // TODO Fix in the future return File.Exists(path); } else { if (path.StartsWith("//")) return false; else return File.Exists(path); } } public CmsError GetActiveFileInfo(string path, out DTOActiveImageAndNameDataModel fileInfo) { fileInfo = new DTOActiveImageAndNameDataModel(); PROGRAM_TYPE_ENUM program = PROGRAM_TYPE_ENUM.NONE; CmsError libraryError = numericalControl.FILES_RGetProgramType(ref program); if (libraryError.IsError()) return libraryError; // Get selected process ushort selectedProcess = 0; libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; // JOB CASE if (program == PROGRAM_TYPE_ENUM.JOB) { // Create folder path with process string jobFolderPath = JOB_TMP_DIRECTORY + "\\" + selectedProcess + "\\"; // Get job data DTOJobModel model = SupportFunctions.ReadExtractedJobMetadata(selectedProcess); if (model == null) return FILE_NOT_FOUND_ERROR; string base64Img = model.Metadata.Generics.Images.Count() > 0 ? model.Metadata.Generics.Images[0].Base64 : ""; fileInfo = new DTOActiveImageAndNameDataModel() { Image = base64Img, Name = Path.GetFileName(path) // TODO: Get From NC }; return NO_ERROR; } // PART PROGRAM CASE else { string name = ""; libraryError = numericalControl.PROC_RSelectedPPName(selectedProcess, ref name); if (libraryError.IsError()) return libraryError; fileInfo = new DTOActiveImageAndNameDataModel() { Image = SupportFunctions.GetImageBase64String(PART_PRG_IMAGES, name), Name = Path.GetFileName(name) // TODO: Get From NC }; } return NO_ERROR; } public CmsError LocalPartProgramFileInfo(string path, out InfoFile fileInfo) { FileInfo fileData = new FileInfo(path); StreamReader fileRead = new StreamReader(path); int count = 0; string line = ""; fileInfo = new InfoFile() { Name = fileData.Name, CreationDate = fileData.CreationTime, LastModDate = fileData.LastAccessTime, AbsolutePath = path }; // Populate fileInfo content fileInfo.Content = new List(); while ((line = fileRead.ReadLine()) != null && count < 10) { fileInfo.Content.Add(line); count++; } fileRead.Close(); // Set image base 64 string foreach (string ext in VALID_IMAGE_EXTENSIONS) { string imagePath = PART_PRG_IMAGES + "/" + fileInfo.Name + ext; if (File.Exists(imagePath)) { fileInfo.PreviewBase64 = "data:image/" + ext + ";base64," + Convert.ToBase64String(File.ReadAllBytes(imagePath)); break; } } return NO_ERROR; } public CmsError GetActiveProgramInfo(out DTOActiveProgramDataModel dtoData) { dtoData = new DTOActiveProgramDataModel(); // Get selectedProcess process id ushort selectedProcess = 0; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; // Read active program data ActiveProgramDataModel data = new ActiveProgramDataModel(); libraryError = numericalControl.FILES_RActiveProgramData(selectedProcess, ref data); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return libraryError; // TODO FIX OSAI } public CmsError SetActiveProgramInfo(string path, out DTOActiveProgramDataModel dtoData) { dtoData = new DTOActiveProgramDataModel(); // Get selectedProcess process id ushort selectedProcess = 1; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); //if (libraryError.IsError()) // return libraryError; ActiveProgramDataModel data = new ActiveProgramDataModel(); libraryError = numericalControl.FILES_WSetActiveProgram(selectedProcess, path, ref data); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return libraryError; } public CmsError DeactivateProgram(out DTOActiveProgramDataModel dtoData) { dtoData = new DTOActiveProgramDataModel(); // Get selectedProcess process id ushort selectedProcess = 0; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; ActiveProgramDataModel data = new ActiveProgramDataModel(); libraryError = numericalControl.FILES_WDeactivateProgram(selectedProcess); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return libraryError; } public CmsError UploadPartProgram(string localPath, string fileName, out string newFilePath) { // Upload to NC newFilePath = ""; CmsError libraryError = numericalControl.FILES_UploadPartProgram(localPath, fileName, ref newFilePath); if (libraryError.IsError()) return libraryError; // Delete local file File.Delete(localPath + "\\" + fileName); return libraryError; } public CmsError UploadPartProgramAndActivate(string localPath, string fileName, out ActiveProgramDataModel programData) { programData = new ActiveProgramDataModel(); // Get selectedProcess id ushort selectedProcess = 0; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; if (!JOB_EXTENSIONS.Contains(Path.GetExtension(fileName))) { // Upload to NC libraryError = UploadPartProgram(localPath, fileName, out string newFilePath); if (libraryError.IsError()) return libraryError; // Custom part program management //if(String.IsNullOrEmpty(CMSMainProgramContent)) // Activate directly program return numericalControl.FILES_WSetActiveProgram(selectedProcess, newFilePath, ref programData); //else //{ // // Activate updated program with custom main program // return numericalControl.FILES_WUploadCustomMainProgramAndActivate(selectedProcess, CMSMainProgramContent, ref programData); //} } else { DTOJobModel job = SupportFunctions.UnpackJobAndReadMetadata(localPath + fileName, selectedProcess); return numericalControl.FILES_WUploadJobFilesAndActivate(selectedProcess, JOB_TMP_DIRECTORY, JOB_MAIN_FILENAME); } } public CmsError UploadPartProgramAndAddToQueue(string localPath, string fileName, int reps, out DTOQueueModel queueItem) { queueItem = new DTOQueueModel(); // Get selectedProcess id ushort selectedProcess = 0; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; queueItem = new DTOQueueModel() { PartProgramName = fileName, Reps = reps, RemainingReps = reps, AbsolutePath = localPath + fileName, Status = QUEUE_ITEM_STATUS.NOT_ACTIVE }; // Check if there is already a pp queue if (!PartProgramQueue.ContainsKey(selectedProcess)) PartProgramQueue.Add(selectedProcess, new List()); queueItem.Id = SupportFunctions.GetNextId(PartProgramQueue[selectedProcess].Select(x => x.Id)); // Add new process to PartProgramQueue[selectedProcess].Add(queueItem); using (QueueController queueController = new QueueController()) { queueController.UpdateQueue(); } return libraryError; } public CmsError UpdateQueue() { // Get queue data List queueData = new List(); CmsError libraryError = numericalControl.FILES_RQueueData(ref queueData); foreach (var item in queueData) { if (!QueueRunningIndexes.ContainsKey(item.ProcessId)) QueueRunningIndexes.Add(item.ProcessId, 0); if (item.LoadNextProgram) { // Check if there is already a pp queue for the selected process if (PartProgramQueue.ContainsKey(item.ProcessId)) { // Check if runnig exist if (PartProgramQueue[item.ProcessId].ElementAtOrDefault(QueueRunningIndexes[item.ProcessId]) != null) { var actualItem = PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]]; // Check if there are remaining reps before change part program if (actualItem.RemainingReps > 1) actualItem.RemainingReps -= 1; else { // Set as finished actualItem.RemainingReps = 0; actualItem.Status = QUEUE_ITEM_STATUS.FINISHED; // TODO set next //while(PartProgramQueue[item.ProcessId].ElementAtOrDefault(QueueRunningIndexes[item.ProcessId] + 1) != null && !File.Exists(PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].AbsolutePath)) //{ // QueueRunningIndexes[item.ProcessId] += 1; //} if (PartProgramQueue[item.ProcessId].ElementAtOrDefault(QueueRunningIndexes[item.ProcessId] + 1) != null) // if next part program exists, set next pp as current pp QueueRunningIndexes[item.ProcessId] += 1; // Check if file is a valid job if (SupportFunctions.IsValidJob(PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].AbsolutePath)) { // Unpack job DTOJobModel job = SupportFunctions.UnpackJobAndReadMetadata(PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].AbsolutePath, item.ProcessId); // Load JOB to NC return numericalControl.FILES_WUploadJobFilesAndActivate(item.ProcessId, JOB_TMP_DIRECTORY + "\\" + item.ProcessId + "\\", JOB_MAIN_FILENAME); } else // Upload & activate new part program libraryError = numericalControl .FILES_WLoadNextPartProgram( PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].AbsolutePath, QUEUE_FILE_NAME ); if (libraryError.IsError()) return libraryError; } } } } // Check if queue exists for the process if (PartProgramQueue.ContainsKey(item.ProcessId) && PartProgramQueue[item.ProcessId].ElementAtOrDefault(QueueRunningIndexes[item.ProcessId]) != null) { // Set status based on queue status if (item.Status == QUEUE_STATUS.RUNNING || item.Status == QUEUE_STATUS.CLOSING) PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].Status = QUEUE_ITEM_STATUS.RUNNING; if (item.Status == QUEUE_STATUS.NOT_ACTIVE) PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].Status = QUEUE_ITEM_STATUS.NOT_ACTIVE; if (item.Status == QUEUE_STATUS.WAITING_OPERATOR) PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].Status = QUEUE_ITEM_STATUS.WAITING_OPERATOR; } } return NO_ERROR; } public CmsError GetSelectedProcessQueue(out List queueList) { queueList = new List(); // Get selected process ushort selectedProcess = 0; CmsError libraryError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (libraryError.IsError()) return libraryError; queueList = new List(); // Check if there is already a pp queue if (PartProgramQueue.ContainsKey(selectedProcess)) // return INCORRECT_PARAMETERS_ERROR; queueList = PartProgramQueue[selectedProcess]; return NO_ERROR; } public CmsError MoveQueueItems(int processId, int itemId, int newIndex, out List queue) { itemId = itemId - 1; var a = QueueRunningIndexes[processId]; // Update queue running index after move an item if (itemId < QueueRunningIndexes[processId] && newIndex >= QueueRunningIndexes[processId]) QueueRunningIndexes[processId] -= 1; if (newIndex <= QueueRunningIndexes[processId] && itemId > QueueRunningIndexes[processId]) QueueRunningIndexes[processId] += 1; queue = new List(); // Check if there is a queue if (!PartProgramQueue.ContainsKey(processId)) return INCORRECT_PARAMETERS_ERROR; // Check if items exists if (PartProgramQueue[processId].ElementAtOrDefault(itemId) == null) return INCORRECT_PARAMETERS_ERROR; var item = PartProgramQueue[processId][itemId]; // Remove item in the old positions PartProgramQueue[processId].RemoveAt(itemId); // Add in the new position PartProgramQueue[processId].Insert(newIndex, item); // Fix new ids for (int i = 0; i < PartProgramQueue[processId].Count(); i++) PartProgramQueue[processId][i].Id = i + 1; using (QueueController queueController = new QueueController()) queueController.UpdateQueueIdsAndSave(processId); queue = PartProgramQueue[processId]; return NO_ERROR; } public CmsError EditQueueItemReps(int processId, int itemIndex, int reps, out DTOQueueModel model) { model = new DTOQueueModel(); itemIndex = itemIndex - 1; // Check if there is a queue if (!PartProgramQueue.ContainsKey(processId)) return INCORRECT_PARAMETERS_ERROR; // Check if items exists if (PartProgramQueue[processId].ElementAtOrDefault(itemIndex) == null) return INCORRECT_PARAMETERS_ERROR; // Check if Program is running if (PartProgramQueue[processId][itemIndex].Status == QUEUE_ITEM_STATUS.RUNNING) return INCORRECT_PARAMETERS_ERROR; PartProgramQueue[processId][itemIndex].Reps = reps; PartProgramQueue[processId][itemIndex].RemainingReps = reps; model = PartProgramQueue[processId][itemIndex]; // Update database using (QueueController queueController = new QueueController()) queueController.UpdateReps(processId, itemIndex, reps); return NO_ERROR; } public CmsError RemoveFromQueue(int processId, int id) { // Check if there is a queue if (PartProgramQueue.ContainsKey(processId)) { // Find item by id DTOQueueModel tmpQueueItem = PartProgramQueue[processId] .FirstOrDefault(x => x.Id == id); if (tmpQueueItem != null) { PartProgramQueue[processId].Remove(tmpQueueItem); if (File.Exists(tmpQueueItem.AbsolutePath)) File.Delete(tmpQueueItem.AbsolutePath); } } // Update database data using (QueueController queueController = new QueueController()) queueController.UpdateQueueIdsAndSave(processId); return NO_ERROR; } public CmsError EmptyQueue(int processId) { // Check if there is a queue if (PartProgramQueue.ContainsKey(processId)) PartProgramQueue[processId] = new List(); // Update db using (QueueController queueController = new QueueController()) queueController.UpdateQueue(); // Clean directory SupportFunctions.EmptyFolder(JOB_TMP_DIRECTORY); QueueRunningIndexes[processId] = 0; return NO_ERROR; } public CmsError StartWorkingQueue(int processId) { return numericalControl.FILES_WStartQueue(); } public CmsError StopWorkingQueue(int processId) { return numericalControl.FILES_WStopQueue(); } public CmsError CleanUploadFolder() { return numericalControl.FILES_WCleanUploadFolder(); } #region recipe file persistence /// /// Upsert recipe overview status /// /// /// public static void upsRecipeOverview(RecipeSection section, RecipeCatStatus status) { if (RecipeLiveData.RecipeOverview.ContainsKey(section)) { RecipeLiveData.RecipeOverview[section] = status; } else { RecipeLiveData.RecipeOverview.Add(section, status); } } public static void ReadLastRecipe() { try { ReadLiveData(); } catch (XmlException ex) { ExceptionManager.ManageError(ERROR_LEVEL.FATAL, "Error while reading file: " + ex.SourceUri + "\n Error: " + ex.Message, true ); } catch (Exception ex) { var message = ex.Message; if (ex.InnerException != null) message += "\n" + ex.InnerException.Message; ExceptionManager.ManageError(ERROR_LEVEL.FATAL, message, true); } } /// /// Try to load live data from json persistence file /// public static bool ReadLiveData() { bool answ = false; if (File.Exists(LIVE_RECIPE_PATH)) { // load all text data var rawData = File.ReadAllText(LIVE_RECIPE_PATH); try { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); } catch { } answ = true; } else { // reload from template... var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); try { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); // from template --> reset (if present) overview data... foreach (var item in RecipeLiveData.RecipeOverview) { RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; } } catch { } // salva current SaveRecipeCurrent(); answ = true; } // rendo se fatto return answ; } /// /// Try to load selected recipe to live data (memory and json persistence file) /// public static bool LoadRecipe(string filePath) { bool answ = false; // check file extension string fileName = Path.GetFileName(filePath); if (!fileName.EndsWith(".json")) { fileName += ".json"; filePath += ".json"; } // check filePath... if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) { // aggiungo base path! filePath = RECIPE_DIRECTORY + filePath; } if (File.Exists(filePath)) { answ = true; // load all text data var rawData = File.ReadAllText(filePath); try { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); } catch { } // update current live data! SaveRecipeCurrent(); } // rendo se fatto return answ; } /// /// Try to load template recipe /// public static bool LoadTemplate() { bool answ = false; // check filePath... if (File.Exists(RECIPE_TEMPLATE_PATH)) { answ = true; // load all text data var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); try { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); // from template --> reset (if present) overview data... if (RecipeLiveData.RecipeOverview != null) { foreach (var item in RecipeLiveData.RecipeOverview) { RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; } } // update NAME RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json"; } catch { } // update current live data! SaveRecipeCurrent(); } // rendo se fatto return answ; } /// /// Try to write live data to json persistence file /// public static bool SaveRecipeCurrent() { bool answ = false; try { answ = true; // serialize string rawData = JsonConvert.SerializeObject(RecipeLiveData); // save live! var dir = Path.GetDirectoryName(LIVE_RECIPE_PATH); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } File.WriteAllText(LIVE_RECIPE_PATH, rawData); } catch { } // rendo se fatto return answ; } /// /// Try to save live recipe as NEW template /// public static bool SaveRecipeTemplate() { // duplicate data... LiveData data2save = RecipeLiveData; // template --> reset overview data... data2save.RecipeOverview = new Dictionary(); return SaveRecipe(RECIPE_TEMPLATE_PATH, data2save); } /// /// Try to save live recipe to selected filePath /// public static bool SaveRecipe(string filePath, LiveData currRecipe) { bool answ = false; try { answ = true; string fileName = Path.GetFileName(filePath); if (!fileName.EndsWith(".json")) { fileName += ".json"; filePath += ".json"; } // fix name! currRecipe.RecipeName = fileName; // serialize string rawData = JsonConvert.SerializeObject(currRecipe); // save live! File.WriteAllText(LIVE_RECIPE_PATH, rawData); // check filePath... if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) { // aggiungo base path! filePath = RECIPE_DIRECTORY + filePath; } // save! File.WriteAllText(filePath, rawData); } catch { } // rendo se fatto return answ; } #endregion } }