diff --git a/Libs/CMS_CORE_Library.dll b/Libs/CMS_CORE_Library.dll index 87242bf9..6b1e6ff6 100644 Binary files a/Libs/CMS_CORE_Library.dll and b/Libs/CMS_CORE_Library.dll differ diff --git a/Step.Config/Config/alarmsConfigValidator.xsd b/Step.Config/Config/alarmsConfigValidator.xsd index b72cb57c..69c18779 100644 --- a/Step.Config/Config/alarmsConfigValidator.xsd +++ b/Step.Config/Config/alarmsConfigValidator.xsd @@ -18,13 +18,13 @@ - + - + diff --git a/Step.Config/Config/headsConfig.xml b/Step.Config/Config/headsConfig.xml new file mode 100644 index 00000000..40ab86d4 --- /dev/null +++ b/Step.Config/Config/headsConfig.xml @@ -0,0 +1,21 @@ + + + + Testa 1 + SPINDLE + 55 + 80 + + + Testa 2 + AWJ + 55 + 80 + + + Testa 3 + WJ + 55 + 80 + + \ No newline at end of file diff --git a/Step.Config/Config/headsConfigValidator.xsd b/Step.Config/Config/headsConfigValidator.xsd new file mode 100644 index 00000000..0eeb57c2 --- /dev/null +++ b/Step.Config/Config/headsConfigValidator.xsd @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Step.Config/Config/maintenancesConfigValidator.xsd b/Step.Config/Config/maintenancesConfigValidator.xsd index 8c263d56..8178ed15 100644 --- a/Step.Config/Config/maintenancesConfigValidator.xsd +++ b/Step.Config/Config/maintenancesConfigValidator.xsd @@ -28,13 +28,13 @@ - + - + @@ -51,9 +51,9 @@ - - - + + + diff --git a/Step.Config/Config/serverConfigValidator.xsd b/Step.Config/Config/serverConfigValidator.xsd index 64bd37d0..6b78d897 100644 --- a/Step.Config/Config/serverConfigValidator.xsd +++ b/Step.Config/Config/serverConfigValidator.xsd @@ -6,7 +6,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/Step.Config/Config/softKeyConfigValidator.xsd b/Step.Config/Config/softKeyConfigValidator.xsd index ef4b64be..f26398dc 100644 --- a/Step.Config/Config/softKeyConfigValidator.xsd +++ b/Step.Config/Config/softKeyConfigValidator.xsd @@ -10,7 +10,7 @@ - + diff --git a/Step.Config/ServerConfig.cs b/Step.Config/ServerConfig.cs index 57a4305b..90f4bc6c 100644 --- a/Step.Config/ServerConfig.cs +++ b/Step.Config/ServerConfig.cs @@ -21,6 +21,7 @@ namespace Step.Config public static List SoftKeysConfig; public static List InitialAlarmsConfig; + public static List HeadsConfig; public static AreasConfigModel ProductionConfig; public static AreasConfigModel ToolingConfig; diff --git a/Step.Config/ServerConfigController.cs b/Step.Config/ServerConfigController.cs index cf4ac24b..b4125b6d 100644 --- a/Step.Config/ServerConfigController.cs +++ b/Step.Config/ServerConfigController.cs @@ -1,5 +1,6 @@ using Step.Model.ConfigModels; using Step.Utils; +using static Step.Utils.SupportFunctions; using System; using System.Globalization; using System.Linq; @@ -16,106 +17,12 @@ namespace Step.Config { try { - // Get server file handler - XDocument xmlConfigFile = GetXmlHandlerWithValidator(SERVER_CONFIG_SCHEMA_PATH, SERVER_CONFIG_PATH); - - // Read nc Config with LINQ - NcConfig = xmlConfigFile - .Descendants(NC_CONFIG_KEY) - .Select(x => new NcConfigModel() - { - NcVendor = x.Element("ncVendor").Value, - showNcHMI = Convert.ToBoolean(x.Element("showNcHMI").Value), - NcIpAddress = x.Element("ncIpAddress").Value, - NcPort = Convert.ToUInt16(x.Element("ncPort").Value), - NcName = x.Element("machineModel").Value - }).FirstOrDefault(); - - // Read server config with LINQ and save into static config - ServerStartupConfig = xmlConfigFile - .Descendants(SERVER_CONFIG_KEY) - .Select(x => new ServerConfigModel() - { // Set server config model data - Language = CultureInfo.CreateSpecificCulture(x.Element("language").Value), - ServerAddress = x.Element("serverAddress").Value, - ServerPort = Convert.ToInt32(x.Element("serverPort").Value), - EnableDirectoryBrowsing = Convert.ToBoolean(x.Element("enableDirectoryBrowsing").Value), - DatabaseAddress = x.Element("databaseAddress").Value - }).FirstOrDefault(); - - // Get Areas file handler - xmlConfigFile = GetXmlHandlerWithValidator(AREAS_CONFIG_SCHEMA_PATH, AREAS_CONFIG_PATH); - - // Read areas config with LINQ - xmlConfigFile - .Descendants(AREAS_CONFIG_KEY) // Get areas config node - .Elements() - .ToList() - .ForEach(x => SetAreaValueByName(x)); // Loop through elements - - // Get Maintenances file handler - xmlConfigFile = GetXmlHandlerWithValidator(MAINTENANCES_CONFIG_SCHEMA_PATH, MAINTENANCES_CONFIG_PATH); - - MaintenancesConfig = xmlConfigFile - .Root - .Elements() - .ToList() - .Select(x => - new MaintenanceConfigModel() - { - Id = Convert.ToInt32(x.Element("id").Value), - LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read names list - y => y.Attribute("langKey").Value, y => y.Value - ), - Intervall = TimeSpan.FromMinutes(Convert.ToDouble(x.Element("interval").Value)), - Deadline = DateTime.Parse(x.Element("deadline").Value), - Type = x.Element("type").Value, - CouterId = Convert.ToInt32(x.Element("counterId").Value) - } - ) - .ToList(); - - // Get SoftKeys - xmlConfigFile = GetXmlHandlerWithValidator(SOFT_KEY_CONFIG_SCHEMA_PATH, SOFT_KEY_CONFIG_PATH); - int id = 1; - - SoftKeysConfig = xmlConfigFile - .Root - .Elements() - .Where(x => Convert.ToBoolean(x.Element("active").Value) == true) // Only active softkey - .Select(x => new SoftKeyConfigModel() - { - Id = id++, - PlcId = Convert.ToInt32(x.Element("plcId")?.Value), // If exists - IsActive = Convert.ToBoolean(x.Element("active").Value), - Category = Convert.ToInt32(x.Element("category").Value), - LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read localized names and convert into a dictionary - y => y.Attribute("langKey").Value, y => y.Value - ), - - SubKeys = x.Element("plcKeys")?.Elements().Select(y => new SubKeysModel() // Populate subkeys if exist - { - Id = id++, - PlcId = Convert.ToInt32(y.Attribute("plcId").Value), - Text = y.Value - }).ToList(), - Type = GetSoftKeyType(x.Name.ToString()), - OperatorConfirmationNeeded = Convert.ToBoolean(x.Element("operatorConfirmationNeeded").Value) - }) - .ToList(); - - xmlConfigFile = GetXmlHandlerWithValidator(ALARM_CONFIG_SCHEMA_PATH, ALARM_CONFIG_PATH); - - InitialAlarmsConfig = xmlConfigFile - .Root - .Elements() - .Select(x => new AlarmsConfigModel() - { - AlarmId = Convert.ToInt32(x.Element("alarmId").Value), - PlcId = Convert.ToInt32(x.Element("plcId").Value), - RestoreIsActive = Convert.ToBoolean(x.Element("restoreIsActive").Value) - }) - .ToList(); + ReadServerConfig(); + ReadAreaConfig(); + ReadMaintenancesConfig(); + ReadSoftkeysConfig(); + ReadAlarmsConfig(); + ReadHeadsConfig(); } catch (Exception ex) { @@ -138,16 +45,6 @@ namespace Step.Config return xmlConfigFile; } - private static SOFTKEY_TYPE GetSoftKeyType(string type) - { - switch (type) - { - case "softkey_procedure": return SOFTKEY_TYPE.PROCEDURE; - case "softkey_group": return SOFTKEY_TYPE.GROUP; - default: return SOFTKEY_TYPE.TOGGLE; - } - } - private static void SetAreaValueByName(XElement element) { // Choose which area to be set @@ -239,5 +136,147 @@ namespace Step.Config return false; } } + + #region Read config from file + + public static void ReadServerConfig() + { + // Get server file handler + XDocument xmlConfigFile = GetXmlHandlerWithValidator(SERVER_CONFIG_SCHEMA_PATH, SERVER_CONFIG_PATH); + + // Read nc Config with LINQ + NcConfig = xmlConfigFile + .Descendants(NC_CONFIG_KEY) + .Select(x => new NcConfigModel() + { + NcVendor = x.Element("ncVendor").Value, + showNcHMI = Convert.ToBoolean(x.Element("showNcHMI").Value), + NcIpAddress = x.Element("ncIpAddress").Value, + NcPort = Convert.ToUInt16(x.Element("ncPort").Value), + NcName = x.Element("machineModel").Value + }).FirstOrDefault(); + + // Read server config with LINQ and save into static config + ServerStartupConfig = xmlConfigFile + .Descendants(SERVER_CONFIG_KEY) + .Select(x => new ServerConfigModel() + { // Set server config model data + Language = CultureInfo.CreateSpecificCulture(x.Element("language").Value), + ServerAddress = x.Element("serverAddress").Value, + ServerPort = Convert.ToInt32(x.Element("serverPort").Value), + EnableDirectoryBrowsing = Convert.ToBoolean(x.Element("enableDirectoryBrowsing").Value), + DatabaseAddress = x.Element("databaseAddress").Value + }).FirstOrDefault(); + } + + private static void ReadAreaConfig() + { + // Get Areas file handler + XDocument xmlConfigFile = GetXmlHandlerWithValidator(AREAS_CONFIG_SCHEMA_PATH, AREAS_CONFIG_PATH); + + // Read areas config with LINQ + xmlConfigFile + .Descendants(AREAS_CONFIG_KEY) // Get areas config node + .Elements() + .ToList() + .ForEach(x => SetAreaValueByName(x)); // Loop through elements + } + + public static void ReadMaintenancesConfig() + { + // Get Maintenances file handler + XDocument xmlConfigFile = GetXmlHandlerWithValidator(MAINTENANCES_CONFIG_SCHEMA_PATH, MAINTENANCES_CONFIG_PATH); + + MaintenancesConfig = xmlConfigFile + .Root + .Elements() + .ToList() + .Select(x => + new MaintenanceConfigModel() + { + Id = Convert.ToInt32(x.Element("id").Value), + LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read names list + y => y.Attribute("langKey").Value, y => y.Value + ), + Intervall = TimeSpan.FromMinutes(Convert.ToDouble(x.Element("interval").Value)), + Deadline = DateTime.Parse(x.Element("deadline").Value), + Type = x.Element("type").Value, + CouterId = Convert.ToInt32(x.Element("counterId").Value) + } + ) + .ToList(); + } + + private static void ReadSoftkeysConfig() + { + // Get Softkeys + XDocument xmlConfigFile = GetXmlHandlerWithValidator(SOFTKEYS_CONFIG_SCHEMA_PATH, SOFTKEYS_CONFIG_PATH); + int id = 1; + // Read softkey configuration from XML with LINQ + SoftKeysConfig = xmlConfigFile + .Root + .Elements() + .Where(x => Convert.ToBoolean(x.Element("active").Value) == true) // Only active softkey + .Select(x => new SoftKeyConfigModel() + { + Id = id++, // autoincrement Id + PlcId = Convert.ToInt32(x.Element("plcId")?.Value), // If exists + IsActive = Convert.ToBoolean(x.Element("active").Value), + Category = Convert.ToInt32(x.Element("category").Value), + LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read localized names and convert into a dictionary + y => y.Attribute("langKey").Value, y => y.Value + ), + + SubKeys = x.Element("plcKeys")?.Elements().Select(y => new SubKeysModel() // Populate subkeys if exist + { + Id = id++, + PlcId = Convert.ToInt32(y.Attribute("plcId").Value), + Text = y.Value + }).ToList(), + Type = GetSoftKeyType(x.Name.ToString()), + OperatorConfirmationNeeded = Convert.ToBoolean(x.Element("operatorConfirmationNeeded").Value) + }) + .ToList(); + } + + private static void ReadAlarmsConfig() + { + XDocument xmlConfigFile = GetXmlHandlerWithValidator(ALARMS_CONFIG_SCHEMA_PATH, ALARMS_CONFIG_PATH); + // Read alarms config from XML file + InitialAlarmsConfig = xmlConfigFile + .Root + .Elements() + .Select(x => new AlarmsConfigModel() + { + AlarmId = Convert.ToInt32(x.Element("alarmId").Value), + PlcId = Convert.ToInt32(x.Element("plcId").Value), + RestoreIsActive = Convert.ToBoolean(x.Element("restoreIsActive").Value) + }) + .ToList(); + } + + private static void ReadHeadsConfig() + { + XDocument xmlConfigFile = GetXmlHandlerWithValidator(HEADS_CONFIG_SCHEMA_PATH, HEADS_CONFIG_PATH); + + int i = 0; + // Read head config from XML file + HeadsConfig = xmlConfigFile + .Root + .Elements() + .Select(x => new HeadsConfigModel() + { + Id = i++, // Autoincrement Id + Name = x.Element("name").Value, + Type = GetHeadType(x.Element("type").Value), + WarningLimit = Convert.ToInt16(x.Element("warningLimit").Value), + AlarmLimit = Convert.ToInt16(x.Element("alarmLimit").Value), + }) + .ToList(); + } + + #endregion Read config from file + + } } \ No newline at end of file diff --git a/Step.Config/Step.Config.csproj b/Step.Config/Step.Config.csproj index ee31c6fd..9ca61a53 100644 --- a/Step.Config/Step.Config.csproj +++ b/Step.Config/Step.Config.csproj @@ -62,6 +62,10 @@ PreserveNewest Designer + + Designer + Always + Designer Always @@ -70,6 +74,9 @@ PreserveNewest Designer + + PreserveNewest + Always Designer diff --git a/Step.Model/ConfigModels/HeadsConfigModel.cs b/Step.Model/ConfigModels/HeadsConfigModel.cs new file mode 100644 index 00000000..b318040d --- /dev/null +++ b/Step.Model/ConfigModels/HeadsConfigModel.cs @@ -0,0 +1,13 @@ +using static Step.Utils.Constants; + +namespace Step.Model.ConfigModels +{ + public class HeadsConfigModel + { + public int Id; + public string Name; + public HEAD_TYPE Type; + public short WarningLimit; + public short AlarmLimit; + } +} diff --git a/Step.Model/Constants.cs b/Step.Model/Constants.cs index 88e7f164..04c3f031 100644 --- a/Step.Model/Constants.cs +++ b/Step.Model/Constants.cs @@ -27,6 +27,14 @@ namespace Step.Utils GROUP = 2 } + public enum HEAD_TYPE + { + SPINDLE = 0, + WJ = 1, + AWJ = 2, + LASER = 3 + } + public static class NC_VENDOR { public const string DEMO = "DEMO"; @@ -67,6 +75,8 @@ namespace Step.Utils } // Filenames + + // Config File Names public static readonly string BASE_PATH = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); public const string CONFIG_DIRECTORY = "Config\\"; public const string SERVER_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "serverConfigValidator.xsd"; @@ -78,11 +88,14 @@ namespace Step.Utils public const string MAINTENANCES_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "maintenancesConfigValidator.xsd"; public const string MAINTENANCES_CONFIG_PATH = CONFIG_DIRECTORY + "maintenancesConfig.xml"; - public const string SOFT_KEY_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "softKeyConfigValidator.xsd"; - public const string SOFT_KEY_CONFIG_PATH = CONFIG_DIRECTORY + "softKeyConfig.xml"; + public const string SOFTKEYS_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "softKeyConfigValidator.xsd"; + public const string SOFTKEYS_CONFIG_PATH = CONFIG_DIRECTORY + "softKeyConfig.xml"; - public const string ALARM_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "alarmsConfigValidator.xsd"; - public const string ALARM_CONFIG_PATH = CONFIG_DIRECTORY + "alarmsConfig.xml"; + public const string ALARMS_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "alarmsConfigValidator.xsd"; + public const string ALARMS_CONFIG_PATH = CONFIG_DIRECTORY + "alarmsConfig.xml"; + + public const string HEADS_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "headsConfigValidator.xsd"; + public const string HEADS_CONFIG_PATH = CONFIG_DIRECTORY + "headsConfig.xml"; public static string WEBSITE_DIRECTORY = Path.Combine(BASE_PATH, "..", "wwwroot"); public static string LANGUAGE_PACK_DIRECTORY = BASE_PATH + "\\languages\\"; @@ -103,7 +116,8 @@ namespace Step.Utils public const string SEND_PROCESSES_DATA = "SEND_PROCESSES_STATUS"; public const string SEND_FUNCTIONALITY_DATA = "SEND_FUNCTION_DATA"; public const string SEND_EXPIRED_MAINTENANCES_DATA = "SEND_EXPIRED_MAINTENANCES_DATA"; - public const string SEND_SOFT_KEYS_DATA = "SEND_SOFT_KEYS_DATA"; + public const string SEND_SOFTKEYS_DATA = "SEND_SOFT_KEYS_DATA"; + public const string SEND_HEADS_DATA = "SEND_HEADS_DATA"; public const string BROADCAST_DATA = "BROADCAST_DATA"; diff --git a/Step.Model/DTOModels/DTOHeadModel.cs b/Step.Model/DTOModels/DTOHeadModel.cs new file mode 100644 index 00000000..9c15046c --- /dev/null +++ b/Step.Model/DTOModels/DTOHeadModel.cs @@ -0,0 +1,90 @@ +namespace Step.Model.DTOModels +{ + public class DTOHeadModel + { + public uint Id; + public string Type; + public bool inWarning; + public bool inAlarm; + public byte Override; + public byte Process; + + public override bool Equals(object obj) + { + var item = obj as DTOHeadModel; + + // Object is not a DTOHeadModel instance or a child + if (item == null) + return false; + + if (Id != item.Id) + return false; + + if (Process != item.Process) + return false; + + if (Override != item.Override) + return false; + + return true; + } + } + + public class DTOSpindleModel : DTOHeadModel + { + public int ActualSpeed; + public ushort Load; + public ushort MountedTool; + + public override bool Equals(object obj) + { + var item = obj as DTOSpindleModel; + + // Object is not a DTOSpindleModel + if (item == null) + return false; + + // Compare the fields + if (ActualSpeed != item.ActualSpeed) + return false; + + if (Load != item.Load) + return false; + + if (MountedTool != item.MountedTool) + return false; + + // Call Parent equals + return base.Equals(item); + } + } + + public class DTOAbrasiveWaterJet : DTOHeadModel + { + public int ActualPressure; + public ushort Abrasive; + public float Vacum; + + public override bool Equals(object obj) + { + var item = obj as DTOAbrasiveWaterJet; + + // Object is not a DTOSpindleModel + if (item == null) + return false; + + // Compare the fields + if (ActualPressure != item.ActualPressure) + return false; + + if (Abrasive != item.Abrasive) + return false; + + if (Vacum != item.Vacum) + return false; + + // Call Parent equals + return base.Equals(item); + } + } +} \ No newline at end of file diff --git a/Step.Model/DTOModels/DTOProcessDataModel.cs b/Step.Model/DTOModels/DTOProcessDataModel.cs index 62ae221c..83e00793 100644 --- a/Step.Model/DTOModels/DTOProcessDataModel.cs +++ b/Step.Model/DTOModels/DTOProcessDataModel.cs @@ -7,7 +7,7 @@ namespace Step.Model.DTOModels public class DTOProcessDataModel { public bool isRunning; - public bool selectedProcess; + public ushort selectedProcess; public List processes; public DTOProcessDataModel() @@ -25,6 +25,9 @@ namespace Step.Model.DTOModels if (isRunning != item.isRunning) return false; + + if (selectedProcess != item.selectedProcess) + return false; // If the numbers of the list's elemets are different, lists are different if (item.processes.Count != processes.Count) return false; diff --git a/Step.Model/Step.Model.csproj b/Step.Model/Step.Model.csproj index ffbd17e0..c72f049f 100644 --- a/Step.Model/Step.Model.csproj +++ b/Step.Model/Step.Model.csproj @@ -61,6 +61,7 @@ + @@ -82,6 +83,7 @@ + DtsGenerator DTOLanguageModel.cs.d.ts diff --git a/Step.NC/NcHandler.cs b/Step.NC/NcHandler.cs index f011ada3..dd5b6a1d 100644 --- a/Step.NC/NcHandler.cs +++ b/Step.NC/NcHandler.cs @@ -9,11 +9,11 @@ using Step.Model.DTOModels; using System; using System.Collections.Generic; using System.Globalization; -using System.Reflection; using static CMS_CORE.Nc; using static CMS_CORE_Library.DataStructures; using static Step.Config.ServerConfig; using static Step.Utils.Constants; +using static Step.Utils.SupportFunctions; namespace Step.NC { @@ -61,6 +61,8 @@ namespace Step.NC return null; } + #region Read Data + public CmsError GetNcGenericData(out DTONcGenericDataModel genericData) { genericData = new DTONcGenericDataModel(MachineConfig.Model); @@ -276,6 +278,7 @@ namespace Step.NC 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++) @@ -300,13 +303,8 @@ namespace Step.NC } } - return cmsError; - } - - public CmsError PutPowerOnData(uint id) - { - // Set to true power on data by id - CmsError cmsError = numericalControl.PLC_WPowerOnData(id, true); + // Read selected process + cmsError = numericalControl.PROC_RSelectedProcess(ref processesData.selectedProcess); return cmsError; } @@ -367,8 +365,8 @@ namespace Step.NC if (performed != null) perfVal = performed.CounterValue; - // MAINTENANCE_INTERVAL <= PLC - LASTPERFORMED - if (currMaintenance.Interval <= counter.Value - perfVal ) + // MAINTENANCE_INTERVAL <= PLC - LASTPERFORMED + if (currMaintenance.Interval <= counter.Value - perfVal) { // Update last expiration date if null if (currMaintenance.LastExpirationDate == null) @@ -386,12 +384,13 @@ namespace Step.NC } } break; + case MAINT_EXPIRATION_DATE_TYPE: { // Already performed if (performed != null) break; - // DEADLINE <= NOW + // DEADLINE <= NOW if (currMaintenance.Deadline <= DateTime.Now) // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() @@ -401,6 +400,7 @@ namespace Step.NC }); } break; + case MAINT_TIME_INTERVAL_TYPE: { // Get last performed, default value is maintenance creation date @@ -414,7 +414,7 @@ namespace Step.NC double minutesPassedFromLastMaint = timePassedFromLastMaint.TotalMinutes; // Interval - passed minutes since last maintenance - if(currMaintenance.Interval <= minutesPassedFromLastMaint) + if (currMaintenance.Interval <= minutesPassedFromLastMaint) { // Update last expiration date if (currMaintenance.LastExpirationDate == null) @@ -455,7 +455,7 @@ namespace Step.NC foreach (var softKey in SoftKeysConfig) { // Check type of the selected softkey - if(softKey.Type == SOFTKEY_TYPE.GROUP) + if (softKey.Type == SOFTKEY_TYPE.GROUP) { // Foreach subkey create a softkey foreach (var subkey in softKey.SubKeys) @@ -473,7 +473,7 @@ namespace Step.NC } } else - { + { // Find plc value var plcSoftKey = plcSoftKeys.Find(x => x.Id == softKey.PlcId); softKeys.Add(new DTOSoftKeyModel() @@ -489,11 +489,99 @@ namespace Step.NC 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(), + ActualSpeed = head.ActualSpeed_Pressure, + inWarning = head.ActualSpeed_Pressure >= configuredHead.WarningLimit, + inAlarm = head.ActualSpeed_Pressure >= configuredHead.AlarmLimit, + Load = head.Load_Abrasive, + MountedTool = head.MountedTool_Vacum, + Override = head.Override, + }); + } + break; + case HEAD_TYPE.AWJ: + { + heads.Add(new DTOAbrasiveWaterJet() + { + Id = head.Id, + Process = head.Process, + Type = configuredHead.Type.ToString(), + ActualPressure = head.ActualSpeed_Pressure, + inWarning = head.MountedTool_Vacum >= configuredHead.WarningLimit, + inAlarm = head.MountedTool_Vacum >= configuredHead.AlarmLimit, + Abrasive = head.Load_Abrasive, + Vacum = head.MountedTool_Vacum, + Override = head.Override + }); + } + break; + case HEAD_TYPE.WJ: + { + heads.Add(new DTOHeadModel() + { + Id = head.Id, + Process = head.Process, + Type = configuredHead.Type.ToString(), + inAlarm = false, + inWarning = false, + Override = head.Override + }); + } + break; + } + } + + return cmsError; + } + + #endregion Read Data + + #region Write data + public CmsError PutSoftKeyValue(uint id) { // Write softkey pression to plc CmsError cmsError = numericalControl.PLC_WSoftKey(id); - + + return cmsError; + } + + public CmsError PutSelectProcess(ushort procNumber) + { + return numericalControl.PROC_WSelectProcess(procNumber); + } + + public CmsError PutPowerOnData(uint id) + { + // Set to true power on data by id + CmsError cmsError = numericalControl.PLC_WPowerOnData(id, true); + return cmsError; } @@ -506,5 +594,7 @@ namespace Step.NC { return new CmsError(0, ""); } + + #endregion Write data } } \ No newline at end of file diff --git a/Step.Tasks/ThreadsFunctions.cs b/Step.Tasks/ThreadsFunctions.cs index 0e8e9c54..2e5704ac 100644 --- a/Step.Tasks/ThreadsFunctions.cs +++ b/Step.Tasks/ThreadsFunctions.cs @@ -267,7 +267,7 @@ public static class ThreadsFunctions ManageLibraryError(libraryError); else // Send through signalR - MessageServices.Current.Publish(SEND_SOFT_KEYS_DATA, null, softKeys); + MessageServices.Current.Publish(SEND_SOFTKEYS_DATA, null, softKeys); } else TryNcConnection(); @@ -287,6 +287,50 @@ public static class ThreadsFunctions } } + public static void ReadHeadsData() + { + NcHandler ncHandler = new NcHandler(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + CmsError libraryError = ncHandler.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncHandler.numericalControl.NC_IsConnected()) + { + // Get Data from config and PLC + libraryError = ncHandler.GetHeadsData(out List heads); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_HEADS_DATA, null, heads); + } + else + TryNcConnection(); + + sw.Stop(); + //Send to the UI the time + ReadSoftKeysTimer += sw.ElapsedMilliseconds; + ReadSoftKeysTimes++; + + // Wait + Thread.Sleep(500); + } + } + catch (ThreadAbortException) + { + ncHandler.Dispose(); + } + } + #endregion Nc Threads #region SupportFunctions diff --git a/Step.Tasks/ThreadsHandler.cs b/Step.Tasks/ThreadsHandler.cs index d8983aec..d1eefc0d 100644 --- a/Step.Tasks/ThreadsHandler.cs +++ b/Step.Tasks/ThreadsHandler.cs @@ -16,7 +16,8 @@ namespace Step.Core ThreadsFunctions.ReadProcessesPPStatus, ThreadsFunctions.ReadEnabledFunctionality, ThreadsFunctions.ReadExpiredMaintenances, - ThreadsFunctions.ReadSoftKeysData + ThreadsFunctions.ReadSoftKeysData, + ThreadsFunctions.ReadHeadsData }; private volatile static List RunningThreadsList = new List(); diff --git a/Step.Utils/Step.Utils.csproj b/Step.Utils/Step.Utils.csproj index 961b94ce..84b9729d 100644 --- a/Step.Utils/Step.Utils.csproj +++ b/Step.Utils/Step.Utils.csproj @@ -59,6 +59,7 @@ + diff --git a/Step.Utils/supportFunctions.cs b/Step.Utils/supportFunctions.cs new file mode 100644 index 00000000..b6b091d3 --- /dev/null +++ b/Step.Utils/supportFunctions.cs @@ -0,0 +1,28 @@ +using static Step.Utils.Constants; + +namespace Step.Utils +{ + public static class SupportFunctions + { + public static SOFTKEY_TYPE GetSoftKeyType(string type) + { + switch (type) + { + case "softkey_procedure": return SOFTKEY_TYPE.PROCEDURE; + case "softkey_group": return SOFTKEY_TYPE.GROUP; + default: return SOFTKEY_TYPE.TOGGLE; + } + } + + public static HEAD_TYPE GetHeadType(string type) + { + switch (type) + { + case "SPINDLE": return HEAD_TYPE.SPINDLE; + case "AWJ": return HEAD_TYPE.AWJ; + default: return HEAD_TYPE.WJ; + + } + } + } +} diff --git a/Step/Controllers/SignalR/NcHub.cs b/Step/Controllers/SignalR/NcHub.cs index f68fdb6c..12c8b287 100644 --- a/Step/Controllers/SignalR/NcHub.cs +++ b/Step/Controllers/SignalR/NcHub.cs @@ -1,28 +1,28 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNet.SignalR; +using Microsoft.AspNet.SignalR; using Step.NC; +using System.Collections.Generic; +using System.Threading.Tasks; using TeamDev.SDK.MVVM; -using static Step.Utils.Constants; +using static CMS_CORE_Library.DataStructures; using static Step.Config.ServerConfig; +using static Step.Utils.Constants; namespace Step.Controllers.SignalR { - // [SignalRAuthorize(FunctionAccess = "functionAccess", Action = ACTIONS.READ)] + // [SignalRAuthorize(FunctionAccess = "functionAccess", Action = ACTIONS.READ)] public class NcHub : Hub { public static List ConnectedClients = new List(); public static bool NewConnectedClients = false; - public override Task OnConnected() { Groups.Add(Context.ConnectionId, "ncData"); NewConnectedClients = true; ConnectedClients.Add(Context.ConnectionId); - var result = base.OnConnected(); + var result = base.OnConnected(); // Resends data to all the clients MessageServices.Current.Publish(BROADCAST_DATA); @@ -58,7 +58,8 @@ namespace Step.Controllers.SignalR ncHandler.PutPowerOnData(id); } } - // [SignalRAuthorize(FunctionAccess = "functionAccess", Action = ACTIONS.READ)] + + // [SignalRAuthorize(FunctionAccess = "functionAccess", Action = ACTIONS.READ)] public void RefreshAllAlarms() { @@ -78,7 +79,6 @@ namespace Step.Controllers.SignalR public void RecoveryProcedure(string id) { MessageServices.Current.Publish(SHOW_MSG_UI, null, "Recovery Alarm. ID: " + id); - } public void UserSoftKeyClicked(int id) @@ -106,7 +106,7 @@ namespace Step.Controllers.SignalR { if (softKey.Id == id) { - // Write click button + // Write click button ncHandler.PutSoftKeyValue((uint)softKey.PlcId); break; } @@ -114,5 +114,19 @@ namespace Step.Controllers.SignalR } } } + + public void SelectProcess(ushort procNumber) + { + using (NcHandler ncHandler = new NcHandler()) + { + CmsError libraryError = ncHandler.Connect(); + if (libraryError.IsError()) + throw new HubException(libraryError.message); + + libraryError = ncHandler.PutSelectProcess(procNumber); + if (libraryError.IsError()) + throw new HubException(libraryError.message); + } + } } -} +} \ No newline at end of file diff --git a/Step/Controllers/WebApi/ConfigurationController.cs b/Step/Controllers/WebApi/ConfigurationController.cs index fdeffa2a..24b79960 100644 --- a/Step/Controllers/WebApi/ConfigurationController.cs +++ b/Step/Controllers/WebApi/ConfigurationController.cs @@ -79,5 +79,11 @@ namespace Step.Controllers.WebApi return Ok(output); } + + [Route("heads"), HttpGet] + public IHttpActionResult GetHeadConfig() + { + return Ok(HeadsConfig); + } } } \ No newline at end of file diff --git a/Step/Controllers/WebApi/LanguageController.cs b/Step/Controllers/WebApi/LanguageController.cs index 8ad98b38..f1b81ed5 100644 --- a/Step/Controllers/WebApi/LanguageController.cs +++ b/Step/Controllers/WebApi/LanguageController.cs @@ -85,22 +85,26 @@ namespace Step.Controllers.WebApi { CmsError cmsError = ncHandler.Connect(); Dictionary returnValue = new Dictionary(); - Dictionary messages = new Dictionary(); + Dictionary messages = new Dictionary(); + // Read data from CN cmsError = ncHandler.numericalControl.NC_GetTranslatedPlcMessages(language, ref messages); for(int i = 0; i < 1024; i++) { + // Get configurated alarms var tmpAlarmConfig = InitialAlarmsConfig.Where(x => x.PlcId == i).FirstOrDefault(); + // Default string string message = "Alarm_id_" + i + ": Message not configurated"; - + // If is configurated if (tmpAlarmConfig != null) { + // Find translated string message = messages.Where(x => x.Key == tmpAlarmConfig.AlarmId).FirstOrDefault().Value; if (message == null) message = "Alarm_id_" + i + ": Message not found"; } - + // Add to dictionary returnValue.Add( ALARM_PREFIX + i, message diff --git a/Step/Listeners/ListenersHandler.cs b/Step/Listeners/ListenersHandler.cs index c1a7e23a..1d8f7c5e 100644 --- a/Step/Listeners/ListenersHandler.cs +++ b/Step/Listeners/ListenersHandler.cs @@ -47,11 +47,14 @@ namespace Step.Listeners { SignalRListener.SendExpMaintenancesData(a); })); - infos.Add(MessageServices.Current.Subscribe(SEND_SOFT_KEYS_DATA, async (a, b) => + infos.Add(MessageServices.Current.Subscribe(SEND_SOFTKEYS_DATA, async (a, b) => { SignalRListener.SendSoftKeysData(a); })); - + infos.Add(MessageServices.Current.Subscribe(SEND_HEADS_DATA, async (a, b) => + { + SignalRListener.SendHeadsData(a); + })); infos.Add(MessageServices.Current.Subscribe(BROADCAST_DATA, async (a, b) => { diff --git a/Step/Listeners/SignalR/SignalRListener.cs b/Step/Listeners/SignalR/SignalRListener.cs index 1b763f5f..019d64b4 100644 --- a/Step/Listeners/SignalR/SignalRListener.cs +++ b/Step/Listeners/SignalR/SignalRListener.cs @@ -18,6 +18,7 @@ namespace Step.Listeners.SignalR private static DTOPowerOnDataModel LastPowerOnData = new DTOPowerOnDataModel(); private static DTOProcessDataModel LastProcessesData = new DTOProcessDataModel(); private static List LastSoftKeysData = new List(); + private static List LastHeadsData = new List(); private static bool LastIsNcConnected = false; @@ -80,7 +81,7 @@ namespace Step.Listeners.SignalR { var context = GlobalHost.ConnectionManager.GetHubContext(); - // Check if the new data and stored object are the same + // Check if collections are equals if (!LastProcessesData.Equals(processesStatus)) { LastProcessesData = processesStatus as DTOProcessDataModel; @@ -94,7 +95,7 @@ namespace Step.Listeners.SignalR var context = GlobalHost.ConnectionManager.GetHubContext(); var newData = functionalityData as List; - // Check if the new data and stored object are the same + // Check if collections are equals if (newData.Count != LastRuntimeFunctionality.Count || !LastRuntimeFunctionality.All(newData.Contains)) { LastRuntimeFunctionality = newData; @@ -107,7 +108,8 @@ namespace Step.Listeners.SignalR { var context = GlobalHost.ConnectionManager.GetHubContext(); var newData = expiredMaintenances as List; - // Check if the new data and stored object are the same + + // Check if collections are equals if (newData.Count != LastExpiredMaintenances.Count || !LastExpiredMaintenances.All(newData.Contains)) { LastExpiredMaintenances = newData; @@ -121,6 +123,7 @@ namespace Step.Listeners.SignalR var context = GlobalHost.ConnectionManager.GetHubContext(); List newData = softKeys as List; + // Check if collections are equals if (newData.Count != LastSoftKeysData.Count || !LastSoftKeysData.All(newData.Contains)) { LastSoftKeysData = newData; @@ -129,6 +132,20 @@ namespace Step.Listeners.SignalR } } + public static void SendHeadsData(object heads) + { + var context = GlobalHost.ConnectionManager.GetHubContext(); + List newData = heads as List; + + // Check if collections are equals + if (newData.Count != LastHeadsData.Count || !LastHeadsData.All(newData.Contains)) + { + LastHeadsData = newData; + // Send data to clients + context.Clients.Group("ncData").heads(heads); + } + } + private volatile static object _broadcastlock = new Object(); public static void BroadcastData() { @@ -159,6 +176,11 @@ namespace Step.Listeners.SignalR { connected = LastIsNcConnected }); + // Send softkeys + context.Clients.Group("ncData").softKeys(LastSoftKeysData); + // Send heads data + context.Clients.Group("ncData").heads(LastHeadsData); + Debug.WriteLine(string.Format("{0} {1} Broadcast..completed", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"), DateTime.Now.Millisecond)); Monitor.Exit(_broadcastlock);