using CMS_CORE; using CMS_CORE.Demo; using CMS_CORE.Fanuc; using CMS_CORE.Osai; using CMS_CORE.Siemens; using Step.Database.Controllers; using Step.Model.DatabaseModels; using Step.Model.DTOModels; using Step.Model.DTOModels.MaintenanceModels; using Step.Model.DTOModels.ToolModels; using Step.Utils; using System; using System.Collections.Generic; using System.Data.Entity; using System.Globalization; using System.IO; using System.Linq; using static CMS_CORE_Library.DataStructures; using static Step.Config.ServerConfig; using static Step.Model.Constants; using static Step.Database.Controllers.QueueController; namespace Step.NC { public class NcHandler : IDisposable { public Nc numericalControl; public NcHandler() { // Choose NC numericalControl = SetNumericalControl(); } public void Dispose() { if (NcConfig.NcVendor != NC_VENDOR.SIEMENS) numericalControl.NC_Disconnect(); } public CmsError Connect() { // Connect NC if (!numericalControl.NC_IsConnected()) return numericalControl.NC_Connect(); return null; } public Nc SetNumericalControl() { // Return new Numerical control instance choosed from the configuration switch (NcConfig.NcVendor) { case NC_VENDOR.DEMO: return new Nc_Demo(NcConfig.NcIpAddress, NcConfig.NcPort); case NC_VENDOR.FANUC: return new Nc_Fanuc(NcConfig.NcIpAddress, NcConfig.NcPort, 2000); case NC_VENDOR.SIEMENS: return new Nc_Siemens(2000); case NC_VENDOR.OSAI: return new Nc_Osai(NcConfig.NcIpAddress, NcConfig.NcPort, 2000); } return null; } #region File manager 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 (File.Exists(path)) return GetQueueFileInfo(path, out fileInfo); else return numericalControl.FILES_RGetFileInfo(path, ref fileInfo); } public CmsError GetQueueFileInfo(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 }; fileInfo.Content = new List(); while ((line = fileRead.ReadLine()) != null && count < 10) { fileInfo.Content.Add(line); count++; } fileRead.Close(); foreach (string ext in VALID_IMAGE_EXTENSIONS) { string imagePath = IMAGES_PATH + "/" + 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 cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; ActiveProgramDataModel data = new ActiveProgramDataModel(); cmsError = numericalControl.FILES_RActiveProgramData(selectedProcess, ref data); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return cmsError; } public CmsError SetActiveProgramInfo(string path, out DTOActiveProgramDataModel dtoData) { dtoData = new DTOActiveProgramDataModel(); // Get selectedProcess process id ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; ActiveProgramDataModel data = new ActiveProgramDataModel(); cmsError = numericalControl.FILES_WSetActiveProgram(selectedProcess, path, ref data); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return cmsError; } public CmsError DeactivateProgram(out DTOActiveProgramDataModel dtoData) { dtoData = new DTOActiveProgramDataModel(); // Get selectedProcess process id ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; ActiveProgramDataModel data = new ActiveProgramDataModel(); cmsError = numericalControl.FILES_WDeactivateProgram(selectedProcess); dtoData = new DTOActiveProgramDataModel() { IsoLines = data.IsoLines, Path = data.Path, TimeLeft = data.TimeLeft }; return cmsError; } public CmsError UploadPartProgram(string localPath, string fileName, out string newFilePath) { // Upload to NC newFilePath = ""; CmsError cmsError = numericalControl.FILES_UploadPartProgram(localPath, fileName, ref newFilePath); if (cmsError.IsError()) return cmsError; // Delete local file File.Delete(localPath + "\\" + fileName); return cmsError; } public CmsError UploadPartProgramAndActivate(string localPath, string fileName, out ActiveProgramDataModel programData) { programData = new ActiveProgramDataModel(); // Upload to NC CmsError cmsError = UploadPartProgram(localPath, fileName, out string newFilePath); if (cmsError.IsError()) return cmsError; // Get selectedProcess id ushort selectedProcess = 0; cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; // Activate updated program return numericalControl.FILES_WSetActiveProgram(selectedProcess, newFilePath, ref programData); } public CmsError UploadPartProgramAndAddToQueue(string localPath, string fileName, int reps, out DTOQueueModel queueItem) { queueItem = new DTOQueueModel(); // Get selectedProcess id ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; 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 cmsError; } public CmsError UpdateQueue() { // Get selectedProcess id List queueData = new List(); CmsError cmsError = 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; 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; // Change part program cmsError = numericalControl .FILES_WLoadNextPartProgram( PartProgramQueue[item.ProcessId][QueueRunningIndexes[item.ProcessId]].AbsolutePath, QUEUE_FILE_NAME ); if (cmsError.IsError()) return cmsError; } } } } // 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; } } // Update data //using (QueueController queueController = new QueueController()) //{ // queueController.UpdateQueue(); //} return NO_ERROR; } public CmsError GetSelectedProcessQueue(out List queueList) { queueList = new List(); // Get selected process ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; queueList = new List(); // Check if there is already a pp queue if (!PartProgramQueue.ContainsKey(selectedProcess)) return INCORRECT_PARAMETERS_ERROR; // Add new process to queueList = PartProgramQueue[selectedProcess]; return NO_ERROR; } //public CmsError SwapQueueItems(int processId, int item1Index, int item2Index) //{ // item1Index = item1Index - 1; // item2Index = item2Index - 1; // // Check if there is a queue // if (!PartProgramQueue.ContainsKey(processId)) // return INCORRECT_PARAMETERS_ERROR; // // Check if items exists // if (PartProgramQueue[processId].ElementAtOrDefault(item1Index) == null || PartProgramQueue[processId].ElementAtOrDefault(item2Index) == null) // return INCORRECT_PARAMETERS_ERROR; // // Create a item // DTOQueueModel tmp = PartProgramQueue[processId][item1Index]; // // Swap item 1 with 2 // PartProgramQueue[processId][item1Index] = PartProgramQueue[processId][item2Index]; // // Swap 2 with tmp // PartProgramQueue[processId][item2Index] = tmp; // // Swap ids // PartProgramQueue[processId][item2Index].Id = item2Index + 1; // // Swap 2 with tmp // PartProgramQueue[processId][item1Index].Id = item1Index + 1; // 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] .Where(x => x.Id == id) .FirstOrDefault(); if (tmpQueueItem != null) PartProgramQueue[processId].Remove(tmpQueueItem); } // 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(); return NO_ERROR; } public CmsError StartWorkingQueue(int processId) { return numericalControl.FILES_WStartQueue(); } public CmsError StopWorkingQueue(int processId) { return numericalControl.FILES_WStopQueue(); } #endregion File manager #region Read Data public CmsError GetNcGenericData(out DTONcGenericDataModel genericData) { genericData = new DTONcGenericDataModel(MachineConfig.Model); // Get date time DateTime dateTime = new DateTime(); CmsError cmsError = numericalControl.NC_RDateTime(ref dateTime); if (cmsError.errorCode != 0) return cmsError; genericData.DateTime = dateTime; // Get language CultureInfo lang = new CultureInfo("en"); cmsError = numericalControl.NC_RLanguage(ref lang); if (cmsError.errorCode != 0) return cmsError; genericData.Language = lang.TwoLetterISOLanguageName; string tmpInfo = ""; // Get serial number cmsError = numericalControl.NC_RSerialNumber(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.SerialNumber = tmpInfo; // Get software version numericalControl.NC_RSoftwareVersion(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.NcSoftwareVersion = tmpInfo; // Get model name numericalControl.NC_RModelName(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.NcModel = tmpInfo; // Get machine number numericalControl.NC_RMachineNumber(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.CmsMachineIdNumber = tmpInfo; // Get max process number ushort procNum = 0; numericalControl.NC_RProcessesNum(ref procNum); if (cmsError.errorCode != 0) return cmsError; // Max process number genericData.ProcessNumber = procNum; // Get Installation Date genericData.InstallationDate = DateTime.Now; // Get PLC version genericData.PlcVersion = "1.0.0"; // Get PLC version genericData.UnitOfMeasurement = "mm"; return cmsError; } public CmsError GetNcAlarms(out DTOAlarmsModel alarms) { alarms = new DTOAlarmsModel(); List tmpAlarms = new List(); // Read NC active alarms CmsError cmsError = numericalControl.NC_RActiveAlarms(ref tmpAlarms); if (cmsError.errorCode != 0) return cmsError; // Create response list from NC data foreach (AlarmModel ncAlarm in tmpAlarms) { alarms.NcAlarms.Add(new GenericAlarmModel() { Id = ncAlarm.Id, Message = ncAlarm.Message, DateTime = DateTime.Now, RestorationIsEnabled = false }); } // Select distints //alarms.NcAlarms = alarms.NcAlarms?.GroupBy(x => x.Id).Select(x => x.First()).ToList(); // Get NC max process number ushort maxProcNumber = 0; cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; // For each process for (ushort i = 1; i <= maxProcNumber; i++) { // Get process active alarms numericalControl.PROC_RActiveAlarms(i, ref tmpAlarms); // Create response list from NC data foreach (AlarmModel processAlarm in tmpAlarms) { alarms.ProcessAlarms.Add(new ProcessAlarmModel() { Id = processAlarm.Id, Message = processAlarm.Message, Process = processAlarm.Process, DateTime = DateTime.Now, RestorationIsEnabled = false }); } } List plcAlarms = new List(); // Read PLC Active Messages cmsError = numericalControl.PLC_RActiveMessages(ref plcAlarms); bool restorationIsEnabled = false; foreach (PlcAlarmModel plcAlarm in plcAlarms) { var configuredAlarm = InitialAlarmsConfig.Where(x => x.PlcId == plcAlarm.Id).FirstOrDefault(); if (configuredAlarm == null) restorationIsEnabled = false; else restorationIsEnabled = configuredAlarm.RestoreIsActive; // Create response list from plc data alarms.PlcAlarms.Add(new DTOPlcAlarmModel() { Id = plcAlarm.Id, IsWarning = plcAlarm.IsWarning, Process = plcAlarm.Process, RestorationIsActive = plcAlarm.RestorationIsActive, DateTime = DateTime.Now, RestorationIsEnabled = restorationIsEnabled }); } if (cmsError.errorCode != 0) return cmsError; return cmsError; } public CmsError GetAxesPositions(out List axes) { axes = new List(); // Get NC max process number ushort maxProcNumber = 0; CmsError cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; // For each process for (ushort i = 1; i <= maxProcNumber; i++) { cmsError = GetAxesPositionsByProcess(i, out DTOAxesModel axis); if (cmsError.errorCode != 0) return cmsError; axes.Add(axis); } return cmsError; } public CmsError GetAxesPositionsBySelectedProcess(out DTOAxesModel axes) { axes = new DTOAxesModel(); // Get selectedProcess process number ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; if (selectedProcess > 0) cmsError = GetAxesPositionsByProcess(selectedProcess, out axes); return cmsError; } public CmsError GetAxesPositionsByProcess(ushort processNum, out DTOAxesModel axes) { axes = new DTOAxesModel(); CmsError cmsError = numericalControl.AXES_RInterpPosition(processNum, ref axes.interpolated); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RMachinePosition(processNum, ref axes.machine); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RProgrPosition(processNum, ref axes.programmePos); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RDistanceToGo(processNum, ref axes.toGo); if (cmsError.errorCode != 0) return cmsError; //numericalControl.AXES_RFollowingError(1, ref axes.followingErr); return cmsError; } public CmsError GetPowerOnData(out DTOPowerOnDataModel resultPowerOnData) { resultPowerOnData = new DTOPowerOnDataModel(); // Init object PreAndPostPowerOnModel prePostPowerOn = new PreAndPostPowerOnModel { PostPowerOn = new PostPowerOnModel(), PrePowerOn = new PrePowerOnModel() }; // Read pre and post power on data CmsError cmsError = numericalControl.PLC_RPowerOnData(ref prePostPowerOn); if (cmsError.IsError()) return cmsError; // Set return object resultPowerOnData.PrePowerOn = prePostPowerOn.PrePowerOn; resultPowerOnData.PostPowerOn = prePostPowerOn.PostPowerOn; // Read axes procedure data from cmsError = numericalControl.PLC_RAxesResetData(ref resultPowerOnData.AxisReset); return cmsError; } public CmsError GetProcessesData(out DTOProcessesDataModel processesData) { processesData = new DTOProcessesDataModel(); // Get NC max process number ushort maxProcNumber = 0; CmsError cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; PROC_STATUS status = PROC_STATUS.IDLE; // For each process get info for (ushort i = 1; i <= maxProcNumber; i++) { ProcessDataModel tmpProcPP = new ProcessDataModel(); // Get process status cmsError = numericalControl.PROC_RStatusAndData(i, ref tmpProcPP); // if at least one process is in run, NC is running // Add to list processesData.processes.Add(new ProcessModel() { Id = tmpProcPP.Id, IsInAlarm = tmpProcPP.IsInAlarm, PartProgramName = tmpProcPP.PartProgramName, Reps = tmpProcPP.Reps, Status = tmpProcPP.Status, Type = tmpProcPP.Type, Visible = tmpProcPP.Visible }); if (tmpProcPP.IsSelected && processesData.SelectedProcess == 0) // TODO remove with multi-process processesData.SelectedProcess = (ushort)tmpProcPP.Id; // Check if there are running process if (!processesData.IsRunning) { // Get process status cmsError = numericalControl.PROC_RStatus(i, ref status); if (status == PROC_STATUS.RUN || status == PROC_STATUS.HOLD) processesData.IsRunning = true; else status = PROC_STATUS.IDLE; } } // Read selected axes cmsError = numericalControl.AXES_RSelectedAxis(ref processesData.SelectedAxis); if (cmsError.IsError()) return cmsError; QueueStatusModel queueStatus = new QueueStatusModel(); // Get queue data cmsError = numericalControl.FILES_RQueueDataByProcess(ref queueStatus, processesData.SelectedProcess); if (cmsError.IsError()) return cmsError; // Set data processesData.QueueStatus = queueStatus.Status; processesData.StartStopQueueEnabled = queueStatus.StartStopQueueEnabled; return cmsError; } public CmsError GetFunctionsMappedWithNC(out List functionsAccessList) { functionsAccessList = new List(); // Read plc functionality List functionalityList = null; CmsError cmsError = numericalControl.PLC_RFunctionAccess(ref functionalityList); // If empty return if (functionalityList == null || functionalityList.Count == 0) return cmsError; using (FunctionsAccessController functionsAccessController = new FunctionsAccessController()) { // Map plc and database data functionsAccessList = functionsAccessController.GetFunctionsMappedWithPlc(functionalityList); } return cmsError; } public CmsError GetMainenancesCounter(out List counters) { // List of PLC counters counters = new List(); // Get counters values from PLC CmsError cmsError = numericalControl.PLC_RMachineCounters(ref counters); return cmsError; } public CmsError GetMaintenanceData(out DTOMaintenanceModel dTOMaintenance, int maintenanceId, int userId) { dTOMaintenance = null; CmsError cmsError = GetMaintenances(out List maintenance, userId); if (cmsError.IsError()) return cmsError; dTOMaintenance = maintenance.Where(x => x.Id == maintenanceId).FirstOrDefault(); return cmsError; } public CmsError GetMaintenances(out List dtoMaintenancesModel, int userId) { // Return value dtoMaintenancesModel = new List(); // Get counters values from PLC CmsError cmsError = GetMainenancesCounter(out List counters); if (cmsError.IsError()) return cmsError; using (MaintenancesController maintenancesController = new MaintenancesController()) { // Get the last performed maintenance for each maintenance List performedMaintenances = maintenancesController.FindLastPerformedMaintenances(); // Get all the active maintenances List maintenances = maintenancesController.FindAll(); // TODO db or config file? double percentage = 0; TimeSpan missingDays = new TimeSpan(); CounterModel counter = new CounterModel(); bool canEdit = false; bool canPerform = false; foreach (var currMaintenance in maintenances) { // Get matching last performed maintenance for current maintenance PerformedMaintenanceModel performed = performedMaintenances.Find(x => x.MaintenanceId == currMaintenance.MaintenanceId); switch (currMaintenance.Type) { case MAINTENANCE_TYPE.MACHINE_INTERVAL: { // Get matching counter for the current maintenance counter = counters.Find(x => x.Id == currMaintenance.CounterId); int perfVal = 0; if (performed != null) perfVal = performed.CounterValue; // Calc percentage = PLC - PERFORMED VALUE * 100 / interval percentage = ((counter.Value - perfVal) * 100) / SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value); missingDays = TimeSpan.FromMinutes(-1 * (counter.Value - perfVal - SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value))); } break; case MAINTENANCE_TYPE.EXP_DATE: { // Already performed if (performed != null) { percentage = 100; missingDays = TimeSpan.Zero; } else { percentage = ((DateTime.Now - currMaintenance.CreationDate).TotalMinutes * 100) / (currMaintenance.Deadline - currMaintenance.CreationDate).TotalMinutes; // TimeSpan.FromTicks((currMaintenance.Deadline.Ticks)).TotalMinutes missingDays = currMaintenance.Deadline - DateTime.Now; counter = new CounterModel(); } } break; case MAINTENANCE_TYPE.TIME_INTERVAL: { // Get last performed, default value is maintenance creation date DateTime perfDate = currMaintenance.CreationDate; if (performed != null) perfDate = performed.Date; // Now - last performed = elapsed interval since last maintenance TimeSpan timePassedFromLastMaint = DateTime.Now.Subtract(perfDate); // Convert in minutes double minutesPassedFromLastMaint = timePassedFromLastMaint.TotalMinutes; // percentage = Passed minutes since last maintenance * 100 / Interval percentage = (minutesPassedFromLastMaint * 100) / SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value); missingDays = TimeSpan.FromMinutes(-1 * (minutesPassedFromLastMaint - SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value))); counter = new CounterModel(); } break; } canEdit = false; using (MachinesUsersController machineUsersController = new MachinesUsersController()) { if (currMaintenance.UserId != null) { // Check if user can edit the maintenance -> caller id - maintenance user id int comparision = machineUsersController.CompareUsersRole(userId, currMaintenance.UserId.Value, MachineConfig.MachineId); if (comparision >= 0) canPerform = canEdit = true; } else { canEdit = false; canPerform = machineUsersController.UserIsCmsAdmin(MachineConfig.MachineId, userId); } } dtoMaintenancesModel.Add(new DTOMaintenanceModel() { Id = currMaintenance.MaintenanceId, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, CreationDate = currMaintenance.CreationDate, Deadline = currMaintenance.Deadline, Description = currMaintenance.Description, Interval = currMaintenance.Interval, LastExpirationDate = currMaintenance.LastExpirationDate, LastPerformedDate = performed?.Date, Type = currMaintenance.Type.ToString(), UnitOfMeasure = currMaintenance.UnitOfMeasure.ToString(), PercentageOfCompletion = percentage >= 0 && percentage < 100 ? Convert.ToInt32(percentage) : 100, MissingDays = missingDays, PlcCounter = counter.Value, CreatedByCms = currMaintenance.UserId == null, CanEdit = canEdit, CanPerform = canPerform }); } } return cmsError; } public CmsError GetExpiredMaintenances(out List expiredMaintenance) { // Return value expiredMaintenance = new List(); // Get counters values from PLC CmsError cmsError = GetMainenancesCounter(out List counters); if (cmsError.IsError()) return cmsError; using (MaintenancesController maintenancesController = new MaintenancesController()) { // Get the last performed maintenance for each maintenance List performedMaintenances = maintenancesController.FindLastPerformedMaintenances(); // Get all the active maintenances List maintenances = maintenancesController.FindAll(); // TODO db or config file? foreach (var currMaintenance in maintenances) { // Get matching last performed maintenance for current maintenance var performed = performedMaintenances.Find(x => x.MaintenanceId == currMaintenance.MaintenanceId); switch (currMaintenance.Type) { case MAINTENANCE_TYPE.MACHINE_INTERVAL: { // Get matching counter for the current maintenance var counter = counters.Find(x => x.Id == currMaintenance.CounterId); int perfVal = 0; if (performed != null) perfVal = performed.CounterValue; // MAINTENANCE_INTERVAL <= PLC - LASTPERFORMED if (SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value) <= counter.Value - perfVal) { // Update last expiration date if null if (currMaintenance.LastExpirationDate == null) { maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, DateTime.Now); currMaintenance.LastExpirationDate = DateTime.Now; } // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = (DateTime)currMaintenance.LastExpirationDate, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title }); } } break; case MAINTENANCE_TYPE.EXP_DATE: { // Already performed if (performed != null) break; // DEADLINE <= NOW if (currMaintenance.Deadline <= DateTime.Now) { maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, currMaintenance.Deadline); currMaintenance.LastExpirationDate = currMaintenance.Deadline; // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = currMaintenance.Deadline, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, }); } } break; case MAINTENANCE_TYPE.TIME_INTERVAL: { // Get last performed, default value is maintenance creation date DateTime perfDate = currMaintenance.CreationDate; if (performed != null) perfDate = performed.Date; // Now - last performed = elapsed interval since last maintenance TimeSpan timePassedFromLastMaint = DateTime.Now.Subtract(perfDate); // Convert in minutes double minutesPassedFromLastMaint = timePassedFromLastMaint.TotalMinutes; // Interval - passed minutes since last maintenance if (SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value) <= minutesPassedFromLastMaint) { // Update last expiration date if (currMaintenance.LastExpirationDate == null) { // Exp date = now - ( expiration intervall) DateTime expirationDate = DateTime.Now.Subtract(TimeSpan.FromMinutes(minutesPassedFromLastMaint - currMaintenance.Interval.Value)); maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, expirationDate); currMaintenance.LastExpirationDate = expirationDate; } // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = (DateTime)currMaintenance.LastExpirationDate, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, }); } } break; } } } return cmsError; } public CmsError GetUserSoftKeys(out List softKeys) { softKeys = new List(); List plcSoftKeys = new List(); // Get softkeys data from PLC CmsError cmsError = numericalControl.PLC_RUserSoftKeys(ref plcSoftKeys); if (cmsError.IsError() || plcSoftKeys.Count == 0) return cmsError; foreach (var softKey in SoftKeysConfig) { // Check type of the selected softkey if (softKey.Type == SOFTKEY_TYPE.GROUP) { // Foreach subkey create a softkey foreach (var subkey in softKey.SubKeys) { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == subkey.PlcId); // Create and add new user softkey model softKeys.Add(new DTOUserSoftKeyModel() { Id = subkey.Id, Active = plcSoftKey.Active, Category = softKey.Category, Value = plcSoftKey.Value }); } } else { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == softKey.PlcId); softKeys.Add(new DTOUserSoftKeyModel() { Id = softKey.Id, Active = plcSoftKey.Active, Category = softKey.Category, Value = plcSoftKey.Value }); } } return cmsError; } public CmsError GetNcSoftKeys(out List ncSoftKeys) { ncSoftKeys = new List(); List plcSoftKeys = new List(); // Get Nc softkeys data from PLC CmsError cmsError = numericalControl.PLC_RNcSoftKeys(ref plcSoftKeys); if (cmsError.IsError() || plcSoftKeys.Count == 0) return cmsError; foreach (var softKey in NcSoftKeysConfig) { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == softKey.Id); // Create and add Nc softkey model ncSoftKeys.Add(new DTONcSoftKeyModel() { Id = softKey.Id, Active = plcSoftKey.Active, Value = plcSoftKey.Value }); } return cmsError; } public CmsError GetHeadsData(out List heads) { // Returned value heads = new List(); // Number of configured heads int headsNumber = HeadsConfig.Count; List plcHeads = new List(); // Read value from PLC CmsError cmsError = numericalControl.PLC_RHeadsData(plcHeads, headsNumber); if (cmsError.IsError()) return cmsError; foreach (var head in plcHeads) { // Get current head config var configuredHead = HeadsConfig.Find(x => x.Id == head.Id); // Create different model according on type switch (configuredHead.Type) { case HEAD_TYPE.SPINDLE: { heads.Add(new DTOSpindleModel() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), inWarning = head.Load_Abrasive >= configuredHead.WarningLimit, inAlarm = head.Load_Abrasive >= configuredHead.AlarmLimit, OverrideEditable = head.OverrideEditable, ActualSpeed = head.ActualSpeed_Pressure, Load = head.Load_Abrasive, MountedTool = (ushort)head.MountedTool_Vacum, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive }); } break; case HEAD_TYPE.AWJ: { float vacumValue = (float)head.MountedTool_Vacum / 100; heads.Add(new DTOAbrasiveWaterJet() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), inWarning = vacumValue >= configuredHead.WarningLimit, inAlarm = vacumValue >= configuredHead.AlarmLimit, OverrideEditable = head.OverrideEditable, ActualPressure = head.ActualSpeed_Pressure, Abrasive = head.Load_Abrasive, Vacum = vacumValue, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive }); } break; case HEAD_TYPE.WJ: { heads.Add(new DTOWaterJet() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), inAlarm = false, inWarning = false, ActualPressure = head.ActualSpeed_Pressure, OverrideEditable = head.OverrideEditable, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive }); } break; } } return cmsError; } public CmsError ReadAxisData(out List axesNames) { axesNames = new List(); List plcAxes = new List(); // Read selected process ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; if (selectedProcess != 0) { // Read axes names cmsError = numericalControl.AXES_RAxesNames(selectedProcess, ref plcAxes); axesNames = plcAxes.Select(x => new DTOAxisNameModel() { Id = x.Id, Name = x.Name }).ToList(); } return cmsError; } public CmsError GetToolTableConfiguration(out ToolTableConfiguration config) { config = new ToolTableConfiguration(); CmsError cmsError = numericalControl.TOOLS_RConfiguration(ref config); if (NcConfig.NcVendor != NC_VENDOR.SIEMENS) { config.FamilyOptionActive = true; config.MultitoolOptionActive = true; config.OffsetOptionActive = true; List categories = new List(); if (!ToolManagerConfig.ShankOpt) { config.MultitoolOptionActive = false; categories.Add("shankType"); config.ToolsConfiguration = config.ToolsConfiguration.Where(x => !(x.Name == "shankId")).ToList(); } if (!ToolManagerConfig.FamilyOpt) { config.FamilyOptionActive = false; categories.Add("family"); config.ToolsConfiguration = config.ToolsConfiguration.Where(x => !(x.Name == "familyId")).ToList(); config.ToolsConfiguration = config.FamiliesConfiguration.FamilyConfiguration.Concat(config.ToolsConfiguration).ToList(); } else { config.ToolsConfiguration = config.ToolsConfiguration.Concat(config.FamiliesConfiguration.FamilyReadOnlyConfiguration).ToList(); } if(!ToolManagerConfig.OffsetOpt) config.OffsetOptionActive = false; if (!ToolManagerConfig.OffsetOpt) categories.Add("offset"); if (!ToolManagerConfig.TcpOpt) categories.Add("tcp"); if (!ToolManagerConfig.CoolingOpt) categories.Add("cooling"); if (!ToolManagerConfig.DynamicCompensationOpt) categories.Add("dynamicCompensation"); if (!ToolManagerConfig.GammaOpt) categories.Add("gamma"); if (!ToolManagerConfig.LifeOpt) categories.Add("life"); if (!ToolManagerConfig.MagPosTypeOpt) categories.Add("magPos"); if (!ToolManagerConfig.MultidimensionalShankOpt) categories.Add("shankOpt"); if (!ToolManagerConfig.SelfAdaptivePathOpt) categories.Add("selfAdaptive"); if (!ToolManagerConfig.BallufOpt) categories.Add("balluf"); config.ToolsConfiguration = config.ToolsConfiguration.Where(x => !categories.Contains(x.Category)).ToList(); config.FamiliesConfiguration.FamilyConfiguration = config.FamiliesConfiguration.FamilyConfiguration.Where(x => !categories.Contains(x.Category)).ToList(); config.ShanksConfiguration.ShankConfiguration = config.ShanksConfiguration.ShankConfiguration.Where(x => !categories.Contains(x.Category)).ToList(); config.MagazinePosConfiguration = config.MagazinePosConfiguration.Where(x => !categories.Contains(x.Category)).ToList(); } return cmsError; } public CmsError GetToolTableData(out List config) { config = new List(); return numericalControl.TOOLS_RToolsData(ref config); } public CmsError GetShanksData(out List shanks) { shanks = new List(); return numericalControl.TOOLS_RShanksData(ref shanks); } public CmsError GetFamiliesData(out List families) { families = new List(); return numericalControl.TOOLS_RFamilyData(ref families); } public CmsError GetMagazinesPositionsData(out List magazinesPositions) { magazinesPositions = new List(); return numericalControl.TOOLS_RMagazinePositions(ref magazinesPositions); } public CmsError GetMagazineStatus(out DTOMagazineActionModel magazineStatus) { // Set up models magazineStatus = new DTOMagazineActionModel(); MagazineActionModel libModel = new MagazineActionModel(); // Read status from NC CmsError cmsError = numericalControl.TOOLS_GetMagazinesStatus(ref libModel); if (cmsError.IsError()) return cmsError; magazineStatus = (DTOMagazineActionModel)libModel; return cmsError; } #endregion Read Data #region Write data public CmsError PutNcSoftKeyClick(uint id) { // Write Nc softkey press to plc CmsError cmsError = numericalControl.PLC_WNcSoftKey(id); return cmsError; } public CmsError PutUserSoftKeyClick(uint id) { // Write user softkey press to plc return numericalControl.PLC_WUserSoftKey(id); } public CmsError RefreshAlarm(uint id) { // Write in memory the request to refresh the alarm return numericalControl.PLC_WRefreshMessage(id); } public CmsError RestoreAlarm(uint id) { // Write in memory the request to restore the alarm return numericalControl.PLC_WRestoreMessage(id); } public CmsError RefreshAllAlarms() { return numericalControl.PLC_WRefreshAllMessages(); } public CmsError PutSelectProcess(ushort procNumber) { return numericalControl.PROC_WSelectProcess(procNumber); } public CmsError PutSelectAxis(byte axisId) { return numericalControl.AXES_WSelectAxis(axisId); } public CmsError PutOverride(uint id, string action) { HEAD_OVERRIDE_SIGN sign = HEAD_OVERRIDE_SIGN.MINUS; if (action == "plus") sign = HEAD_OVERRIDE_SIGN.PLUS; CmsError cmsError = numericalControl.PLC_WHeadOverride(id, sign); return cmsError; } public CmsError PutPowerOnData(uint id) { // Set to true power on data by id return numericalControl.PLC_WPowerOnData(id, true); } public CmsError SetActiveLanguage(CultureInfo language) { // Set to true power on data by id return numericalControl.NC_WLanguage(language); } public CmsError SetActiveScreen(short screen) { // Set to true power on data by id return numericalControl.NC_SetScreenVisible((Nc.SCREEN_PAGE) screen); } #endregion Write data #region Siemens Tools public CmsError AddTool(ref SiemensToolModel tool) { return numericalControl.TOOLS_WAddTool(ref tool); } public CmsError UpdateTool(ref SiemensToolModel tool) { return numericalControl.TOOLS_WUpdateTool(ref tool); } public CmsError AddFamily(string name, out FamilyModel family) { family = new FamilyModel() { Name = name }; return numericalControl.TOOLS_WAddFamily(ref family); } public CmsError AddShank(ref ShankModel shank) { return numericalControl.TOOLS_WAddShank(ref shank); } public CmsError UpdateShank(ref ShankModel shank) { return numericalControl.TOOLS_WUpdateShank(ref shank); } public CmsError UpdateFamilyName(string oldName, string newName) { return numericalControl.TOOLS_WUpdateFamilyData(oldName, newName); } public CmsError UpdateMagazinePosition(PositionModel magazinePosition) { return numericalControl.TOOLS_WUpdatePosition(magazinePosition); } public CmsError DeleteTool(int id) { return numericalControl.TOOLS_WDeleteTool(id); } public CmsError DeleteShank(int id) { return numericalControl.TOOLS_WDeleteShank(id); } public CmsError DeleteFamily(string name) { return numericalControl.TOOLS_WDeleteFamily(name); } public CmsError AddEdge(int toolId, ref EdgeModel edge) { return numericalControl.TOOLS_WAddEdge(toolId, ref edge); } public CmsError UpdateEdge(int toolId, ref EdgeModel edge) { return numericalControl.TOOLS_WUpdateEdge(toolId, ref edge); } public CmsError DeleteEdge(int toolId, int edgeId) { return numericalControl.TOOLS_WDeleteEdge(toolId, edgeId); } public CmsError GetMagazinePositionsAndTools(int magazineId, out List magazinePos) { magazinePos = new List(); return numericalControl.TOOLS_RMagazineTools(magazineId, ref magazinePos); } public CmsError GetNotInMagazinesTools(out List multiTools, out List tools) { multiTools = new List(); tools = new List(); return numericalControl.TOOLS_RAvailableTools(ref multiTools, ref tools); } public CmsError LoadToolInMagazine(int magazineId, NewToolInMagazineModel newMag) { return numericalControl.TOOLS_WLoadToolInMagazine(magazineId, newMag); } public CmsError UnloadToolInMagazine(int magazineId, int positionId) { return numericalControl.TOOLS_WUnloadToolFromMagazine(magazineId, positionId); } public CmsError LoadTooolIntoShank(int shankId, int positionId, int toolId) { return numericalControl.TOOLS_WLoadToolIntoShank(shankId, positionId, toolId); } public CmsError UnloadTooolFromShank(int shankId, int positionId) { return numericalControl.TOOLS_WUnloadToolFromShank(shankId, positionId); } #endregion Siemens Tools // OSAI FANUC #region Osai/Fanuc Tools public CmsError GetToolsData(out List dtoTools) { dtoTools = new List(); CmsError cmsError = NO_ERROR; using (NcToolManagerController toolsManager = new NcToolManagerController()) { List tools = toolsManager.FindToolsWithDependencies(); foreach (DbNcToolModel tool in tools) { DTONcToolModel dtoTool = (DTONcToolModel)tool; cmsError = GetToolData(tool, ref dtoTool); dtoTools.Add(dtoTool); } return cmsError; } } public CmsError GetToolData(DbNcToolModel tool, ref DTONcToolModel dtoTool) { dtoTool = (DTONcToolModel)tool; OffsetModel offset = new OffsetModel(); CmsError cmsError = NO_ERROR; if (tool.OffsetId1 != null && tool.OffsetId1 != 0) { // Read first offset data cmsError = numericalControl.TOOLS_ROffset((short)tool.OffsetId1, ref offset); if (cmsError.IsError()) return cmsError; dtoTool.Offset1 = offset; } if (tool.OffsetId2 != null && tool.OffsetId2 != 0) { // Read second offset data cmsError = numericalControl.TOOLS_ROffset((short)tool.OffsetId2, ref offset); if (cmsError.IsError()) return cmsError; dtoTool.Offset2 = offset; } if (tool.OffsetId3 != null && tool.OffsetId3 != 0) { // Read third offset data cmsError = numericalControl.TOOLS_ROffset((short)tool.OffsetId3, ref offset); if (cmsError.IsError()) return cmsError; dtoTool.Offset3 = offset; } return cmsError; } public CmsError AddTool(DTONewNcToolModel tool, out DTONcToolModel dtoTool) { dtoTool = new DTONcToolModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { DbNcToolModel ncTool = toolsManager.AddTool(tool); if (!ToolManagerConfig.OffsetOpt) { CmsError cmsError = UpdateToolOffsetId(ncTool.ToolId, 1, ncTool.ToolId, out DTONcToolModel toolWithOffset); if (cmsError.IsError()) return cmsError; ncTool.OffsetId1 = ncTool.ToolId; } GetToolData(ncTool, ref dtoTool); return NO_ERROR; } } public CmsError UpdateTool(int toolId, DTONewNcToolModel newTool, out DTONcToolModel toolWithOffsets) { toolWithOffsets = new DTONcToolModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Update database tool Tool DbNcToolModel dbTool = toolsManager.UpdateTool(toolId, newTool); // Populate updated tool with offset data CmsError cmsError = GetToolData(dbTool, ref toolWithOffsets); if (cmsError.IsError()) { dbContextTransaction.Rollback(); return cmsError; } bool startIsActive = false; // Check if tool is loaded into a shank if (dbTool.ShankId != null) { // Check if shank is loaded into magazine DbNcShankModel shank = toolsManager.FindShankWithTools(dbTool.ShankId.Value); if (shank.MagazineId != null) { startIsActive = true; // Create backup of data stored on the NC and block file accesses cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } // Update tool cmsError = UpdateNcTools(toolsManager); } } ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return NO_ERROR; } } } public CmsError UpdateNcTools(NcToolManagerController toolsManager = null) { if (toolsManager == null) toolsManager = new NcToolManagerController(); List shanks = toolsManager .FindShanks() .Where(x => x.MagazineId != null) .Select(x => (NcShankModel)x) .ToList(); // Get tools List tools = toolsManager .FindTools() .Select(x => (NcToolModel)x) .Where(x => shanks.Any(y => y.ShankId == x.ShankId)) // Find only mounted tools .ToList(); // Update tools return numericalControl.TOOLS_WUpdateTools(tools); } public CmsError UpdateOffset(short offsetId, OffsetModel offsetData) { return numericalControl.TOOLS_WOffset(offsetId, offsetData); } public CmsError UpdateToolOffsetId(int toolId, int positionId, int offsetId, out DTONcToolModel toolWithOffsets) { toolWithOffsets = new DTONcToolModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Update database tool Tool DbNcToolModel dbTool = toolsManager.UpdateToolOffset(toolId, positionId, offsetId); // Populate updated tool with offset data CmsError cmsError = GetToolData(dbTool, ref toolWithOffsets); if (cmsError.IsError()) { dbContextTransaction.Rollback(); return cmsError; } bool startIsActive = false; // Check if tool is loaded into a shank if (dbTool.ShankId != null) { // Check if shank is loaded into magazine DbNcShankModel shank = toolsManager.FindShankWithTools(dbTool.ShankId.Value); if (shank.MagazineId != null) { startIsActive = true; // Create backup of data stored on the NC and block file accesses cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } // R tool cmsError = UpdateNcTools(toolsManager); } } ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return NO_ERROR; } } } public CmsError DeleteNcTool(DbNcToolModel tool) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Delete db tool toolsManager.DeleteTool(tool.ToolId); bool startIsActive = false; CmsError cmsError = NO_ERROR; if (tool.ShankId != null) { // If tool is mounted than update Nc data DbNcShankModel shank = toolsManager.FindShankWithTools(tool.ShankId.Value); if (shank.MagazineId != null) { startIsActive = true; // Create backup of data stored on the NC and block file accesses cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } // Update Nc data cmsError = UpdateNcTools(toolsManager); } } ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } } } public CmsError UpdateShank(int shankId, DTONewNcShankModel dtoShank, out DTONcShankModel shank) { shank = new DTONcShankModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { bool startIsActive = false; CmsError cmsError = NO_ERROR; // Update db data shank = (DTONcShankModel)toolsManager.UpdateShank(shankId, dtoShank); if (shank.MagazineId != null) { startIsActive = true; // Create backup of data stored on the NC and block file accesses cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } // Update nc data cmsError = UpdateNcShank(toolsManager); } ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } } } public CmsError DeleteNcShank(int shankId) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Create backup of data stored on the NC and block file accesses CmsError cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) return cmsError; // Delete database shank DbNcShankModel deletedShank = toolsManager.DeleteShank(shankId); bool startIsActive = false; if (deletedShank.MagazineId != null) { startIsActive = true; // Create backup of data stored on the NC and block file accesses cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } // Update nc data cmsError = UpdateNcShank(toolsManager); } ManageErrorAndTransaction(cmsError, dbContextTransaction, startIsActive); return cmsError; } } } private CmsError UpdateNcShank(NcToolManagerController toolsManager) { // Get mounted shanks List shanks = toolsManager .FindShanks() .Where(x => x.MagazineId != null) .Select(x => (NcShankModel)x) .ToList(); // Update nc data return numericalControl.TOOLS_WUpdateShanks(shanks); } public DTONcFamilyModel AddFamily(DTONewNcFamilyModel family) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { return (DTONcFamilyModel)toolsManager.AddFamily(family); } } public CmsError UpdateFamily(int familyId, DTONewNcFamilyModel family, out DTONcFamilyModel newFamily) { newFamily = new DTONcFamilyModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Update db family newFamily = (DTONcFamilyModel)toolsManager.UpdateFamily(familyId, family); // Create backup of data stored on the NC and block file accesses CmsError cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, true); return cmsError; } // Update Nc families cmsError = UpdateNcFamily(toolsManager); ManageErrorAndTransaction(cmsError, dbContextTransaction, true); return cmsError; } } } public CmsError DeleteNcFamily(int famId) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (var dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Create backup of data stored on the NC and block file accesses CmsError cmsError = numericalControl.TOOLS_WStartEditData(); if (cmsError.IsError()) return cmsError; toolsManager.DeleteFamily(famId); // Update Nc families cmsError = UpdateNcFamily(toolsManager); ManageErrorAndTransaction(cmsError, dbContextTransaction, true); return cmsError; } } } private CmsError UpdateNcFamily(NcToolManagerController toolsManager) { // Get mounted shanks List shanks = toolsManager .FindShanks() .Where(x => x.MagazineId != null) .Select(x => (NcShankModel)x) .ToList(); // Get tools List tools = toolsManager .FindTools() .Select(x => (NcToolModel)x) .Where(x => shanks.Any(y => y.ShankId == x.ShankId)) // Find only mounted tools .ToList(); List families = toolsManager .FindFamilies() .Select(x => (NcFamilyModel)x) .Where(x => tools.Any(y => y.FamilyId == x.FamilyId)) // Find only families of mounted tools .ToList(); // Update nc families return numericalControl.TOOLS_WUpdateFamilies(families); } public CmsError UpdateMagazinePosition(DbNcMagazinePositionModel dbPos, DTONcMagazinePositionModel dtoPos, out DTONcMagazinePositionModel magPos) { magPos = new DTONcMagazinePositionModel(); using (NcToolManagerController toolsManager = new NcToolManagerController()) { using (DbContextTransaction dbContextTransaction = toolsManager.dbCtx.Database.BeginTransaction()) { // Create backup of data stored on the NC and block file accesses CmsError cmsError = StartEditData(); if (cmsError.IsError()) { ManageErrorAndTransaction(cmsError, dbContextTransaction, true); return cmsError; } // Update database data magPos = (DTONcMagazinePositionModel)toolsManager.UpdatePosition(dbPos, dtoPos); // Get magazines positions List positions = toolsManager.FindMagazinesPositions() .Select(x => (NcMagazinePositionModel)x) .ToList(); // Update Nc data cmsError = numericalControl.TOOLS_WUpdateMagazinePositions(positions); ManageErrorAndTransaction(cmsError, dbContextTransaction, true); return cmsError; } } } private void ManageErrorAndTransaction(CmsError cmsError, DbContextTransaction dbContextTransaction, bool ncStartIsActive) { // Check cmsError, manage transaction and if startIsActive = true manage Nc backup created with TOOLS_WStartEditData() if (cmsError.IsError()) { // Close transaction dbContextTransaction.Rollback(); // Restore backup if (ncStartIsActive) numericalControl.TOOLS_WRestoreBackup(); } else { // Close transaction dbContextTransaction.Commit(); // Stop editing ncData if (ncStartIsActive) numericalControl.TOOLS_WStopEditData(); } } public DTONcShankModel LoadIntoShank(DbNcToolModel tool, int shankId) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { return toolsManager.LoadToolIntoShank(tool, shankId); } } public DTONcShankModel UnloadFromShank(DbNcToolModel tool) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { return toolsManager.UnloadToolFromShank(tool); } } public CmsError SetupNcToolManager() { if (NcConfig.NcVendor != NC_VENDOR.SIEMENS) { CmsError cmsError = UpdateMagazinePositionConf(); if (cmsError.IsError()) return cmsError; cmsError = WriteOption(); if (cmsError.IsError()) return cmsError; } return NO_ERROR; } public CmsError UpdateMagazinePositionConf() { using (NcToolManagerController toolsManager = new NcToolManagerController()) { // Get database configured positions List dbPositions = toolsManager.FindMagazinesPositions(); if (dbPositions.Count <= 0) { CmsError cmsError = GetMagazineConfiguration(out List config); if (cmsError.IsError()) return cmsError; // Setup new positions list in order to be saved in the database List fromConfigPosition = new List(); foreach (var conf in config) { for (byte i = 1; i <= conf.MaxPositions; i++) { // Create new position fromConfigPosition.Add(new DbNcMagazinePositionModel() { MagazineId = conf.Id, PositionId = i, Disabled = false, Type = 0 }); } } // Update database toolsManager.SetupMagazinePositions(fromConfigPosition); return cmsError; } return NO_ERROR; } } public CmsError WriteOption() { ToolManagerOptionsModel options = new ToolManagerOptionsModel(); SupportFunctions.CopyProperties(ToolManagerConfig, options); return numericalControl.TOOLS_WOptions(options); } public CmsError GetMagazineConfiguration(out List config) { config = new List(); // Read configuration return numericalControl.TOOLS_RMagazineConfig(ref config); } public CmsError StartEditData() { return numericalControl.TOOLS_WStartEditData(); } public CmsError StopEditData() { return numericalControl.TOOLS_WStopEditData(); } public CmsError StartEditTooling(int magazineId) { return numericalControl.TOOLS_WStartEditTooling(magazineId); } public CmsError StopEditTooling(int magazineId) { using (NcToolManagerController toolsManager = new NcToolManagerController()) { // Get mounted shanks List shanks = toolsManager .FindShanks() .Where(x => x.MagazineId != null) .Select(x => (NcShankModel)x) .ToList(); CmsError cmsError = numericalControl.TOOLS_WUpdateShanks(shanks); if (cmsError.IsError()) return cmsError; // Get magazine positions List positions = toolsManager.FindMagazinesPositions() .Select(x => (NcMagazinePositionModel)x) .ToList(); cmsError = numericalControl.TOOLS_WUpdateMagazinePositions(positions); if (cmsError.IsError()) return cmsError; // Get tools List tools = toolsManager .FindTools() .Select(x => (NcToolModel)x) .Where(x => shanks.Any(y => y.ShankId == x.ShankId)) // Find only mounted tools .ToList(); // Update tools cmsError = numericalControl.TOOLS_WUpdateTools(tools); if (cmsError.IsError()) return cmsError; List families = toolsManager .FindFamilies() .Select(x => (NcFamilyModel)x) .Where(x => tools.Any(y => y.FamilyId == x.FamilyId)) // Find only families of mounted tools .ToList(); // Update families cmsError = numericalControl.TOOLS_WUpdateFamilies(families); if (cmsError.IsError()) return cmsError; } return numericalControl.TOOLS_WStopEditTooling(magazineId); } public CmsError GetUpdatedToolsData(out Dictionary updatedStatus, out Dictionary updatedLives) { updatedStatus = new Dictionary(); updatedLives = new Dictionary(); return numericalControl.TOOLS_RUpdatedToolsData(ref updatedStatus, ref updatedLives); } public CmsError CheckIfShankCanFit(int magazineId, int positionId, DbNcShankModel shankToBeLoaded) { CmsError cmsError = GetMagazineConfiguration(out List magazinesConfig); if (cmsError.IsError()) return cmsError; NcMagazineConfigModel magConfig = magazinesConfig.Where(x => x.Id == magazineId).FirstOrDefault();// Get only current magazine config using (NcToolManagerController toolsManager = new NcToolManagerController()) { List magazineMountedTools = toolsManager.GetMountedTools(); // Check if there is a tool already mounted in magazineId and positionId var toolAlreadyMounted = magazineMountedTools.Where(x => x.Shank.MagazineId == magazineId && x.Shank.PositionId == positionId).FirstOrDefault(); if (toolAlreadyMounted != null) return MAGAZINE_POSITION_OCCUPIED_ERROR; List families = toolsManager.FindFamiliesByShankId(shankToBeLoaded.ShankId); int maxRight = families.Max(x => x.RightSize); int maxLeft = families.Max(x => x.LeftSize); // Check if tool can fit in the position considering other tools foreach (var mountedTool in magazineMountedTools) { // Check if is not the same position && if is different check if the position is on the same magazine if (mountedTool.Shank.PositionId != positionId && mountedTool.Shank.MagazineId == magazineId) { int decPosition, incPosition; decPosition = incPosition = mountedTool.Shank.PositionId.Value; // if it is a circular magazine move position before ( for left case ) or after ( right case ) the location you want to mount the tool if (magConfig.Type != NC_MAGAZINE_TYPE.BOX_MAGAZINE) { decPosition = decPosition < positionId ? decPosition + magConfig.MaxPositions : decPosition; incPosition = incPosition > positionId ? incPosition - magConfig.MaxPositions : incPosition; } if (!(magConfig.Type == NC_MAGAZINE_TYPE.BOX_MAGAZINE && mountedTool.Shank.PositionId == 1)) { // Right check // Calculate left space occupied (with mounted shank) double leftMounted = decPosition - (mountedTool.Family.LeftSize / 2.0); // Calculate right space needed (with shank to be loaded) double rightToBeMount = positionId + (maxRight / 2.0); if (leftMounted < rightToBeMount) return MAGAZINE_POSITION_OCCUPIED_ERROR; } if (!(magConfig.Type == NC_MAGAZINE_TYPE.BOX_MAGAZINE && mountedTool.Shank.PositionId == magConfig.MaxPositions)) { // Left check // Calculate right space occupied (with mounted shank) double rightMounted = incPosition + (mountedTool.Family.RightSize / 2.0); // Calculate left space needed (with shank to be loaded) double leftToBeMounted = positionId - (maxLeft / 2.0); if (rightMounted > leftToBeMounted) return MAGAZINE_POSITION_OCCUPIED_ERROR; } } } } return NO_ERROR; } public CmsError GetNcMagazineStatus(out Dictionary status) { status = new Dictionary(); return numericalControl.TOOLS_RMagazineStatus(ref status); } #endregion Osai/Fanuc Tools } }