using Step.Model.ConfigModels; using Step.Model.DTOModels.Scada; using Step.Utils; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; using System.Xml.Serialization; using static Step.Config.ServerConfig; using static Step.Model.Constants; using static Step.Utils.SupportFunctions; namespace Step.Config { public static class ServerConfigController { public static void ReadStartupConfig() { try { ReadServerConfig(); ReadAreaConfig(); ReadMaintenancesConfig(); ReadNcSoftKeys(); ReadUserSoftKeysConfig(); ReadAlarmsConfig(); ReadHeadsConfig(); ReadToolManagerConfig(); ReadMacros(); ReadScadaFile(); } catch (XmlException ex) { ExceptionManager.Manage(ERROR_LEVEL.FATAL, "Error while reading file: " + ex.SourceUri + "\n Error: " + ex.Message ); } catch (Exception ex) { var message = ex.Message; if (ex.InnerException != null) message += "\n"+ex.InnerException.Message; ExceptionManager.Manage(ERROR_LEVEL.FATAL, message); } } private static XDocument GetXmlHandlerWithValidator(string configSchemaFilePath, string configFilePath) { // Create new instance XmlSchemaSet readerSettings = new XmlSchemaSet(); // Add Schema from Assembly Assembly myAssembly = Assembly.GetExecutingAssembly(); using (Stream schemaStream = myAssembly.GetManifestResourceStream(configSchemaFilePath)) { using (XmlReader schemaReader = XmlReader.Create(schemaStream)) { readerSettings.Add(null, schemaReader); } } // Open file reader XDocument xmlConfigFile = XDocument.Load(BASE_PATH + "\\" + configFilePath); // Validate file xmlConfigFile.Validate(readerSettings, ValidationHandler); return xmlConfigFile; } private static void SetAreaValueByName(XElement element) { // Choose which area to be set switch (element.Name.ToString()) { case AREAS.PRODUCTION_KEY: SetAreaValue(ref ProductionConfig, element); break; case AREAS.TOOLING_KEY: SetAreaValue(ref ToolingConfig, element); break; case AREAS.REPORT_KEY: SetAreaValue(ref ReportConfig, element); break; case AREAS.ALARMS_KEY: SetAreaValue(ref AlarmsConfig, element); break; case AREAS.MAINTENANCE_KEY: SetAreaValue(ref MaintenanceConfig, element); break; case AREAS.UTILITIES_KEY: SetAreaValue(ref UtilitiesConfig, element); break; case AREAS.SCADA_KEY: SetAreaValue(ref ScadaConfig, element); break; case AREAS.JOBEDITOR_KEY: SetAreaValue(ref JobEditorConfig, element); break; case AREAS.USERS_KEY: SetAreaValue(ref UsersConfig, element); break; } } private static void SetAreaValue(ref AreasConfigModel areasConfig, XElement element) { // Set area model with xml data areasConfig = new AreasConfigModel() { Name = element.Name.ToString(), Enabled = Convert.ToBoolean(element.Element("enabled").Value), AllowExternalBrowser = Convert.ToBoolean(element.Element("allowExternalBrowser").Value), NcNeeded = Convert.ToBoolean(element.Element("ncNeeded").Value) }; } private static void ValidationHandler(object sender, ValidationEventArgs e) { if (e.Severity == XmlSeverityType.Warning) { ExceptionManager.Manage(ERROR_LEVEL.WARNING, e.Message, true); } else if (e.Severity == XmlSeverityType.Error) { ExceptionManager.Manage(ERROR_LEVEL.FATAL, // "Error while reading file: " + e.Exception.SourceUri + "Error while reading configuration file: " + e.Message, true ); } } public static bool CheckAreaStatus(string areaName) { // Get Area status ( enabled field) by name switch (areaName) { case AREAS.PRODUCTION_KEY: return ProductionConfig.Enabled; case AREAS.TOOLING_KEY: return ToolingConfig.Enabled; case AREAS.REPORT_KEY: return ProductionConfig.Enabled; case AREAS.ALARMS_KEY: return AlarmsConfig.Enabled; case AREAS.MAINTENANCE_KEY: return MaintenanceConfig.Enabled; case AREAS.UTILITIES_KEY: return UtilitiesConfig.Enabled; case AREAS.SCADA_KEY: return ScadaConfig.Enabled; case AREAS.JOBEDITOR_KEY: return ScadaConfig.Enabled; case AREAS.GENERAL_KEY: case AREAS.UNDER_HOOD: return true; default: return false; } } private static void ReadScadaFile() { DirectoryInfo d = new DirectoryInfo(SCADA_DIRECTORY); FileInfo[] files = d.GetFiles("*.xml"); int i = 1; // Cycle inside xml files foreach (var file in files) { StreamReader sr = new StreamReader(SCADA_DIRECTORY + file.Name); XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScadaSchemaModel)); ScadaSchemaModel schema = xmlSerializer.Deserialize(sr) as ScadaSchemaModel; // Setup incremental ids schema.Id = i++; var name = Path.GetFileNameWithoutExtension(file.Name); schema.BackgroundImage = GetImageBase64String(SCADA_DIRECTORY + name, schema.BackgroundImage); schema.Layers = schema.Layers.Select(x => new ScadaSchemaLayerModel() { Id = i++, Buttons = x.Buttons.Select(y => { y.Id = i++; return y; }).ToArray(), Images = x.Images.Select(y => { y.Id = i++; y.Name = GetImageBase64String(SCADA_DIRECTORY + name, y.Name); return y; }) .ToArray(), Labels = x.Labels.Select(y => { y.Id = i++; return y; }).ToArray(), ProgressBars = x.ProgressBars.Select(y => { y.Id = i++; return y; }).ToArray(), Inputs = x.Inputs.Select(y => { y.Id = i++; return y; }).ToArray() }) .ToArray(); if (schema.IsInProductionPage == true) ProductionScadaSchema.Add(schema); else ConfiguredScadaSchema.Add(schema); } } #region Read config from file from configuration 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 .Root .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, SharedPath = x.Element("sharedPath").Value, SharedName = x.Element("sharedName").Value, InstallationDate = x.Element("installationDate").Value }).FirstOrDefault(); // Read Prod Software Config with LINQ SoftwareProdConfig = xmlConfigFile .Root .Descendants(PROD_SFT_CONFIG_KEY) .Select(x => new SoftwareProdConfigModel() { Enabled = Convert.ToBoolean(x.Element("enabled").Value), Path = x.Element("path").Value }).FirstOrDefault(); // Read server config with LINQ and save into static config ServerStartupConfig = xmlConfigFile .Root .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, AutoOpenCmsClient = Convert.ToBoolean(x.Element("autoOpenCmsClient").Value), MTCFolderPath = x.Element("MTCFolderPath").Value, MTCApplicationName = x.Element("MTCApplicationName").Value, MaxAlarmsRows = Convert.ToInt32(x.Element("maxAlarmsRows").Value), AlarmToDelete = Convert.ToInt32(x.Element("alarmToDelete").Value), CMSConnectReady = Convert.ToBoolean(x.Element("CMSConnectReady").Value) }).FirstOrDefault(); int softwareId = 0; ExtSoftwaresConfig = xmlConfigFile .Descendants("extSoftwares") .Elements("software") .Select(x => new ExtSoftwareModel() { Path = x.Element("path").Value, Arguments = x.Element("arguments").Value, LongName = x.Element("longName").Value, ShortName = x.Element("shortName").Value, IconBase64 = ExtractBase64ProgIcon(x.Element("path").Value), InMainMenuBar = Convert.ToBoolean(x.Element("inMainMenuBar").Value), Id = softwareId++.ToString() }).ToList(); } private static void ReadAreaConfig() { // Get Areas file handler XDocument xmlConfigFile = GetXmlHandlerWithValidator(AREAS_CONFIG_SCHEMA_PATH, AREAS_CONFIG_PATH); // Read areas config with LINQ xmlConfigFile .Root // 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), LocalizedName = x.Element("localizedName").Elements().ToDictionary( // Read localized names 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), LocalizedDescription = x.Element("localizedDescription").Elements().ToDictionary( // Read localization of description y => y.Attribute("langKey").Value, y => y.Value ), UnitOfMeasure = x.Element("unitOfMeasure").Value }) .ToList(); } private static void ReadNcSoftKeys() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(NC_SOFTKEYS_CONFIG_SCHEMA_PATH, NC_SOFTKEYS_CONFIG_PATH); // Read Nc softkey configuration from XML NcSoftKeysConfig = xmlConfigFile .Root .Elements() .Where(x => Convert.ToBoolean(x.Element("enabled").Value) == true) // Filter for active softkey .Select(x => new NcSoftKeysModel() { Id = GetPlcIdFromNcSoftKey(x.Name.ToString()), Name = x.Name.ToString(), VisualizedName = x.Element("visualizedName").Value, IsActive = Convert.ToBoolean(x.Element("enabled").Value), IsReadOnly = Convert.ToBoolean(x.Element("readOnly").Value) }) .ToList(); } private static void ReadUserSoftKeysConfig() { // Get softkey file content XDocument xmlConfigFile = GetXmlHandlerWithValidator(USER_SOFTKEYS_CONFIG_SCHEMA_PATH, USER_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) // Filter for active softkey .Select(x => new UserSoftKeyConfigModel() { Id = id++, // autoincrement Id PlcId = Convert.ToInt32(x.Element("plcId")?.Value), // If exists IsActive = Convert.ToBoolean(x.Element("active").Value), IsVisible = Convert.ToBoolean(x.Element("visible").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("subKeys")?.Elements().Where(y => Convert.ToBoolean(y.Attribute("active").Value) == true) // Filter for active softkey .Select(y => new SubKeysModel() // Populate subkeys if exist { Id = id++, IsActive = Convert.ToBoolean(y.Attribute("active").Value), 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 = 1; // Read head config from XML file HeadsConfig = xmlConfigFile .Root .Elements() .Select(x => new HeadsConfigModel() { Id = i++, // Autoincrement Id Type = GetHeadType(x.Element("type").Value), WarningLimit = Convert.ToInt16(x.Element("warningLimit").Value), AlarmLimit = Convert.ToInt16(x.Element("alarmLimit").Value), FixedHead = Convert.ToBoolean(x.Element("fixedHead").Value), LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read localized names and convert into a dictionary y => y.Attribute("langKey").Value, y => y.Value ), }) .ToList(); } private static void ReadToolManagerConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(TOOL_MANAGER_CONFIG_SCHEMA_PATH, TOOL_MANAGER_CONFIG_PATH); // Read config from XML file ToolManagerConfig = xmlConfigFile .Root .Descendants("toolManagerConfig") .Select(x => new ToolManagerConfigModel() { ToolMetricType = x.Element("toolMetricType").Value, FamilyOpt = Convert.ToBoolean(x.Element("familyOpt").Value), ShankOpt = Convert.ToBoolean(x.Element("shankOpt").Value), MagPosTypeOpt = Convert.ToBoolean(x.Element("magPositionOpt").Value), OffsetOpt = Convert.ToBoolean(x.Element("offsetOpt").Value), ReviveOpt = Convert.ToBoolean(x.Element("reviveOpt").Value), GammaOpt = Convert.ToBoolean(x.Element("gammaOpt").Value), LifeOpt = Convert.ToBoolean(x.Element("lifeOpt").Value), TcpOpt = Convert.ToBoolean(x.Element("tcpOpt").Value), CoolingOpt = Convert.ToBoolean(x.Element("coolingOpt").Value), MultidimensionalShankOpt = Convert.ToBoolean(x.Element("multidimensionalShankOpt").Value), SelfAdaptivePathOpt = Convert.ToBoolean(x.Element("selfAdaptivePathOpt").Value), DynamicCompensationOpt = Convert.ToBoolean(x.Element("dynamicCompensationOpt").Value), BallufOpt = Convert.ToBoolean(x.Element("ballufOpt").Value) }) .FirstOrDefault(); ToolManagerConfig.CooligsTranslations = xmlConfigFile .Root .Descendants("coolingLocalizedNames") .Select(x => new CooligTranslations() { Cooling = x.Element("cooling").Elements().ToDictionary( // Read localized names of cooling and convert into a dictionary y => y.Attribute("langKey").Value, y => y.Value ), Cooling1 = x.Element("cooling1").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling2 = x.Element("cooling2").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling3 = x.Element("cooling3").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling4 = x.Element("cooling4").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling5 = x.Element("cooling5").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling6 = x.Element("cooling6").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ), Cooling7 = x.Element("cooling7").Elements().ToDictionary( y => y.Attribute("langKey").Value, y => y.Value ) }) .FirstOrDefault(); ToolManagerConfig.MagazineNames = xmlConfigFile .Root .Descendants("magazineNames") .Elements() .Select(x => new MagazineNamesModel() { MagazineId = Convert.ToInt32(x.Element("id").Value), AssistedTooling = Convert.ToBoolean(x.Element("assistedTooling").Value), LocalizedNames = x.Element("localizedNames").Elements().ToDictionary( // Read localized names and convert into a dictionary y => y.Attribute("langKey").Value, y => y.Value ), }) .ToList(); } public static void ReadMacros() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(MACROS_CONFIG_SCHEMA_PATH, MACROS_CONFIG_PATH); // Read config from XML file MacrosConfig = xmlConfigFile .Descendants("macros") .Elements() .Select(x => x.Value) .ToList(); } #endregion Read config from file from configuration } }