diff --git a/Libs/CMS_CORE_Library.dll b/Libs/CMS_CORE_Library.dll index 3f1cc357..5e1e366f 100644 Binary files a/Libs/CMS_CORE_Library.dll and b/Libs/CMS_CORE_Library.dll differ diff --git a/Step.Core/ThreadsFunctions.cs b/Step.Core/ThreadsFunctions.cs index e9387132..5866733c 100644 --- a/Step.Core/ThreadsFunctions.cs +++ b/Step.Core/ThreadsFunctions.cs @@ -641,7 +641,11 @@ public static class ThreadsFunctions if (ncHandler.numericalControl.NC_IsConnected()) { // Read data - libraryError = ncHandler.UpdateAndGetPPQueue(out List queue); + libraryError = ncHandler.UpdateQueue(); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + libraryError = ncHandler.GetSelectedProcessQueue(out List queue); if (libraryError.IsError()) ManageLibraryError(libraryError); diff --git a/Step.Database/Controllers/QueueController.cs b/Step.Database/Controllers/QueueController.cs new file mode 100644 index 00000000..fc201d93 --- /dev/null +++ b/Step.Database/Controllers/QueueController.cs @@ -0,0 +1,78 @@ +using Step.Model.DatabaseModels; +using Step.Model.DTOModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Step.Model.Constants; + +namespace Step.Database.Controllers +{ + public class QueueController : IDisposable + { + private DatabaseContext dbCtx; + public static Dictionary> PartProgramQueue = new Dictionary>(); + public static Dictionary QueueRunningIndexes = new Dictionary(); + + public QueueController() + { + // Initialize database context + dbCtx = new DatabaseContext(); + } + + public void Dispose() + { + // Clear database context + dbCtx.Dispose(); + } + + public void UpdateQueue() + { + dbCtx.Queue.RemoveRange(dbCtx.Queue); + + foreach(var item in PartProgramQueue) + { + // Create database model + var dbRows = item.Value.Select(x => new QueueItemsModel() + { + Id = x.Id, + AbsolutePath = x.AbsolutePath, + PartProgramName = x.PartProgramName, + Process = item.Key, // Process + Reps = x.Reps, + RemainingReps = x.RemainingReps, + Status = (int)x.Status + }).ToList(); + + // Add to db + dbCtx.Queue.AddRange(dbRows); + } + + dbCtx.SaveChanges(); + } + + public void ReadAndPopulateQueue() + { + var dbQueue = dbCtx.Queue.ToList(); + + foreach(var entity in dbQueue) + { + // Check if process queue exists + if (!PartProgramQueue.ContainsKey(entity.Process)) + PartProgramQueue.Add(entity.Process, new List()); + + // Add db row to queue + PartProgramQueue[entity.Process].Add(new DTOQueueModel() + { + Id = entity.Id, + AbsolutePath = entity.AbsolutePath, + PartProgramName = entity.PartProgramName, + Reps = entity.Reps, + RemainingReps = entity.RemainingReps, + Status = (QUEUE_ITEM_STATUS)entity.Status + }); + } + } + } +} diff --git a/Step.Database/DatabaseContext.cs b/Step.Database/DatabaseContext.cs index 1f45c133..1595aad1 100644 --- a/Step.Database/DatabaseContext.cs +++ b/Step.Database/DatabaseContext.cs @@ -34,6 +34,7 @@ namespace Step.Database public DbSet Shanks { get; set; } public DbSet Tools { get; set; } public DbSet MagazinePositions { get; set; } + public DbSet Queue { get; set; } // Create migration string public static string CONNECTION_STRING = "Server = " + "localhost" + "; Database=" + DATABASE_NAME + ";Uid=" + DATABASE_USER + ";Pwd=" + DATABASE_PWD + ";"; @@ -76,12 +77,16 @@ namespace Step.Database { maintenancesController.CheckDifferencesFromDbAndXml(); } + // Get functionality and PLC default false functionality using (FunctionsAccessController functionsAccess = new FunctionsAccessController()) { FunctionsAccessConfig = functionsAccess.FindAll(); AllFunctionalityDisabled = functionsAccess.FindAllFunctionsAndDisableAll(); } + + using (QueueController queueController = new QueueController()) + queueController.ReadAndPopulateQueue(); } catch (Exception ex) { @@ -133,6 +138,7 @@ namespace Step.Database } } } + // Set machine info into static server config using (MachinesController machinesController = new MachinesController()) { diff --git a/Step.Model/DatabaseModels/QueueItemsModel.cs b/Step.Model/DatabaseModels/QueueItemsModel.cs new file mode 100644 index 00000000..62b7a529 --- /dev/null +++ b/Step.Model/DatabaseModels/QueueItemsModel.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model.DatabaseModels +{ + [Table("queue")] + public class QueueItemsModel + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Column("id", Order = 0)] + public int Id { get; set; } + + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Column("process", Order = 1)] + public int Process { get; set; } + + [Column("part_program_name")] + public string PartProgramName { get; set; } + + [Column("reps")] + public int Reps { get; set; } + + [Column("remaining_reps")] + public int RemainingReps { get; set; } + + [Column("absolute_path")] + public string AbsolutePath { get; set; } + + [Column("status")] + public int Status { get; set; } + } +} diff --git a/Step.Model/Step.Model.csproj b/Step.Model/Step.Model.csproj index c222adf1..7f1db5d4 100644 --- a/Step.Model/Step.Model.csproj +++ b/Step.Model/Step.Model.csproj @@ -82,6 +82,7 @@ + DtsGenerator RoleModel.cs.d.ts diff --git a/Step.NC/NcHandler.cs b/Step.NC/NcHandler.cs index 738a6241..db06a64d 100644 --- a/Step.NC/NcHandler.cs +++ b/Step.NC/NcHandler.cs @@ -18,16 +18,14 @@ 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 static Dictionary> PartProgramQueue = new Dictionary>(); - private static int QueueRunningIndex = 0; - + public NcHandler() { // Choose NC @@ -250,78 +248,96 @@ namespace Step.NC // Add new process to PartProgramQueue[selectedProcess].Add(queueItem); + + using (QueueController queueController = new QueueController()) + { + queueController.UpdateQueue(); + } + return cmsError; } - public CmsError UpdateAndGetPPQueue(out List queueList) + 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 + 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 selectedProcess id + // Get selected process ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; - QueueStatusModel queueData = new QueueStatusModel() { LoadNextProgram = true }; - - cmsError = numericalControl.FILES_RQueueData(ref queueData); - - if (queueData.LoadNextProgram) - { - // Check if there is already a pp queue for the selected process - if (PartProgramQueue.ContainsKey(selectedProcess)) - { - // Check if runnig exist - if (PartProgramQueue[selectedProcess].ElementAtOrDefault(QueueRunningIndex) != null) - { - var actualItem = PartProgramQueue[selectedProcess][QueueRunningIndex]; - // 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[selectedProcess].ElementAtOrDefault(QueueRunningIndex + 1) != null) - // if next part program exists, set next pp as current pp - QueueRunningIndex += 1; - - // Change part program - cmsError = numericalControl.FILES_WLoadNextPartProgram(PartProgramQueue[selectedProcess][QueueRunningIndex].AbsolutePath, QUEUE_FILE_NAME); - if (cmsError.IsError()) - return cmsError; - } - } - } - } - - // Set status - if (PartProgramQueue.ContainsKey(selectedProcess) && PartProgramQueue[selectedProcess].ElementAtOrDefault(QueueRunningIndex) != null) - { - if (queueData.Status == QUEUE_STATUS.RUNNING || queueData.Status == QUEUE_STATUS.CLOSING) - PartProgramQueue[selectedProcess][QueueRunningIndex].Status = QUEUE_ITEM_STATUS.RUNNING; - - if (queueData.Status == QUEUE_STATUS.NOT_ACTIVE) - PartProgramQueue[selectedProcess][QueueRunningIndex].Status = QUEUE_ITEM_STATUS.NOT_ACTIVE; - - if (queueData.Status == QUEUE_STATUS.WAITING_OPERATOR) - PartProgramQueue[selectedProcess][QueueRunningIndex].Status = QUEUE_ITEM_STATUS.WAITING_OPERATOR; - - } - - return GetProcessQueue(selectedProcess, out queueList); - } - - public CmsError GetProcessQueue(int processId, out List queueList) - { queueList = new List(); // Check if there is already a pp queue - if (!PartProgramQueue.ContainsKey(processId)) + if (!PartProgramQueue.ContainsKey(selectedProcess)) return INCORRECT_PARAMETERS_ERROR; // Add new process to - queueList = PartProgramQueue[processId]; + queueList = PartProgramQueue[selectedProcess]; return NO_ERROR; } @@ -359,10 +375,10 @@ namespace Step.NC itemId = itemId - 1; // Update queue running index - if (itemId < QueueRunningIndex && newIndex > QueueRunningIndex) - QueueRunningIndex -= 1; - if (newIndex < QueueRunningIndex && itemId > QueueRunningIndex) - QueueRunningIndex += 1; + if (itemId < QueueRunningIndexes[processId] && newIndex > QueueRunningIndexes[processId]) + QueueRunningIndexes[processId] -= 1; + if (newIndex < QueueRunningIndexes[processId] && itemId > QueueRunningIndexes[processId]) + QueueRunningIndexes[processId] += 1; queue = new List(); @@ -385,6 +401,11 @@ namespace Step.NC queue = PartProgramQueue[processId]; + using (QueueController queueController = new QueueController()) + { + queueController.UpdateQueue(); + } + return NO_ERROR; } @@ -737,7 +758,7 @@ namespace Step.NC QueueStatusModel queueStatus = new QueueStatusModel(); // Get queue data - cmsError = numericalControl.FILES_RQueueData(ref queueStatus); + cmsError = numericalControl.FILES_RQueueDataByProcess(ref queueStatus, processesData.SelectedProcess); if (cmsError.IsError()) return cmsError; diff --git a/Step/Controllers/WebApi/NcApiController.cs b/Step/Controllers/WebApi/NcApiController.cs index b89f2f99..35d8f189 100644 --- a/Step/Controllers/WebApi/NcApiController.cs +++ b/Step/Controllers/WebApi/NcApiController.cs @@ -1,64 +1,63 @@ -using Step.Model.DTOModels; -using Step.NC; -using System; +using Step.Model.DTOModels; +using Step.NC; using System.Globalization; -using System.Web.Http; -using static CMS_CORE_Library.DataStructures; -using static Step.Model.Constants; - -namespace Step.Controllers.WebApi -{ - [RoutePrefix("api/nc")] - public class NcApiController : ApiController - { - [Route("generic_data"), HttpGet] - [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.NC_DATA, Action = ACTIONS.READ)] - public IHttpActionResult GetNcGenericData() - { - using (NcHandler ncHandler = new NcHandler()) - { - ncHandler.Connect(); - CmsError libraryError = ncHandler.GetNcGenericData(out DTONcGenericDataModel genericData); - if (libraryError.IsError()) - if (libraryError.errorCode == CMS_ERROR_CODES.NOT_CONNECTED) - return Ok(genericData); - else - return BadRequest(libraryError.localizationKey); - - return Ok(genericData); - } - } - - [Route("active_language/{language}"), HttpPut] - [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.USER_FUNCTIONS, Action = ACTIONS.WRITE)] - public IHttpActionResult SetActiveLanguage(string language) +using System.Web.Http; +using static CMS_CORE_Library.DataStructures; +using static Step.Model.Constants; + +namespace Step.Controllers.WebApi +{ + [RoutePrefix("api/nc")] + public class NcApiController : ApiController + { + [Route("generic_data"), HttpGet] + [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.NC_DATA, Action = ACTIONS.READ)] + public IHttpActionResult GetNcGenericData() { - using (NcHandler ncHandler = new NcHandler()) - { - ncHandler.Connect(); + using (NcHandler ncHandler = new NcHandler()) + { + ncHandler.Connect(); + CmsError libraryError = ncHandler.GetNcGenericData(out DTONcGenericDataModel genericData); + if (libraryError.IsError()) + if (libraryError.errorCode == CMS_ERROR_CODES.NOT_CONNECTED) + return Ok(genericData); + else + return BadRequest(libraryError.localizationKey); + + return Ok(genericData); + } + } + + [Route("active_language/{language}"), HttpPut] + [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.USER_FUNCTIONS, Action = ACTIONS.WRITE)] + public IHttpActionResult SetActiveLanguage(string language) + { + using (NcHandler ncHandler = new NcHandler()) + { + ncHandler.Connect(); CmsError libraryError = ncHandler.SetActiveLanguage(CultureInfo.CreateSpecificCulture(language)); if (libraryError.errorCode == CMS_ERROR_CODES.NOT_CONNECTED) - return BadRequest(); - else - return Ok(); + return BadRequest(); + else + return Ok(); } - } - - [Route("active_screen/{screen:int}"), HttpPut] - //[WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.USER_FUNCTIONS, Action = ACTIONS.WRITE)] - public IHttpActionResult SetActiveScreen(int screen) + } + + [Route("active_screen/{screen:int}"), HttpPut] + //[WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.USER_FUNCTIONS, Action = ACTIONS.WRITE)] + public IHttpActionResult SetActiveScreen(int screen) { - using (NcHandler ncHandler = new NcHandler()) - { - ncHandler.Connect(); - CmsError libraryError = ncHandler.SetActiveScreen((short) screen); + using (NcHandler ncHandler = new NcHandler()) + { + ncHandler.Connect(); + CmsError libraryError = ncHandler.SetActiveScreen((short)screen); if (libraryError.errorCode == CMS_ERROR_CODES.NOT_CONNECTED) - return BadRequest(); - else - return Ok(); + return BadRequest(); + else + return Ok(); } - } - } + } + } } \ No newline at end of file