using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; using System.Xml.Serialization; using Thermo.Active.Model.ConfigModels; using Thermo.Active.Model.DTOModels.Scada; using Thermo.Active.Model.DTOModels.ThWarmers; using Thermo.Active.Utils; using static Thermo.Active.Config.ServerConfig; using static Thermo.Active.Model.Constants; using static Thermo.Active.Utils.SupportFunctions; namespace Thermo.Active.Config { public static class ServerConfigController { #region Private Fields private static string actualFileName; #endregion Private Fields #region Private Methods private static void ElaborateDataModel(XElement el, string Parent, ref Dictionary Paths) { List intEl = el.Elements().ToList(); foreach (XElement elem in intEl) { if (elem.Name.LocalName == "Component") ElaborateDataModel(elem, Parent + ":" + elem.Attribute("Name").Value, ref Paths); else if (elem.Name.LocalName == "Property") Paths.Add(Parent + ":" + elem.Attribute("SymbolicName").Value, elem.Attribute("Value").Value); else { if (elem.Attribute("SymbolicName") != null && elem.Attribute("SymbolicName").Value == "Condition") Paths.Add(Parent + ":" + elem.Attribute("SymbolicName").Value, ""); else Paths.Add(Parent + ":" + elem.Attribute("SymbolicName").Value, "UNAVAILABLE"); } } } private static XDocument GetXmlHandler(string configFilePath, bool isFullPath = false) { // Open file reader XDocument xmlConfigFile = XDocument.Load((!isFullPath ? BASE_PATH + "\\" : "") + configFilePath); return xmlConfigFile; } private static XDocument GetXmlHandlerWithValidator(string configSchemaFilePath, string configFilePath, bool isFullPath = false) { // 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); } } actualFileName = configFilePath; // Open file reader XDocument xmlConfigFile = XDocument.Load((!isFullPath ? BASE_PATH + "\\" : "") + configFilePath); // Validate file xmlConfigFile.Validate(readerSettings, ValidationHandler); return xmlConfigFile; } 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 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 } /// /// Axes config setup from file /// private static void ReadAxesConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(AXES_CONFIG_SCHEMA_PATH, AXES_CONFIG_PATH); // Read head config from XML file AxesConfig = xmlConfigFile .Root .Elements() .Select(x => new AxesConfigModel() { Id = Convert.ToInt16(x.Attribute("id").Value), Name = x.Attribute("name").Value, MasterId = Convert.ToInt16(x.Attribute("master").Value), EnabledWord = Convert.ToInt16(x.Attribute("enabledWord").Value), Type = GetTActAxes_Type(x.Attribute("type").Value), IsVisible = Convert.ToBoolean(x.Attribute("enabled").Value) }) .ToList(); } private static void ReadCMSConnectConfig() { String _tempUSR, _tempPSW; XDocument xmlConfigFile = GetXmlHandlerWithValidator(CMS_CONNECT_CONFIG_SCHEMA_PATH, CMS_CONNECT_CONFIG_PATH); XElement l = xmlConfigFile .Root .Descendants("cmsConnectConfig") .FirstOrDefault(); // Read config from XML file CmsConnectConfig = xmlConfigFile .Root .Descendants("cmsConnectConfig") .Select(x => new CmsConnectConfigModel() { Enabled = Convert.ToBoolean(x.Element("enabled").Value) }) .FirstOrDefault(); // Read config from XML file for Gateway GatewayConfigModel tempGatewayConfigModel = xmlConfigFile .Root .Descendants("gateway") .Select(x => new GatewayConfigModel() { Address = x.Element("address").Value, Token = x.Element("token").Value }) .FirstOrDefault(); if (DecodeCMSConnectGatewayLogin(tempGatewayConfigModel.Token, out _tempUSR, out _tempPSW)) { tempGatewayConfigModel.Username = _tempUSR; tempGatewayConfigModel.Password = _tempPSW; } else throw new Exception("Error while reading \"" + CMS_CONNECT_CONFIG_PATH + "\": Gateway Token not valid"); CmsConnectConfig.Gateway = tempGatewayConfigModel; } private static void ReadDataModel() { XDocument xmlConfigFile = GetXmlHandler(CONNECT_DATAMODEL_CONFIG_PATH); XElement el = xmlConfigFile.Descendants("Machine").First(); CMSConnectEntry = new Dictionary(); ElaborateDataModel(el, el.Name.LocalName, ref CMSConnectEntry); CMSConnectDataModel = File.ReadAllText(CONNECT_DATAMODEL_CONFIG_PATH); } 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(); } /// /// IO config setup from file /// private static void ReadIOConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(IO_CONFIG_SCHEMA_PATH, IO_CONFIG_PATH); // Read head config from XML file IOConfig = xmlConfigFile .Root .Elements() .Select(x => new IOConfigModel() { Id = Convert.ToInt16(x.Element("id").Value), Category = GetTActIO_Type(x.Element("category").Value), Bank = x.Element("bank") != null ? x.Element("bank").Value : "0", Position = x.Element("position") != null ? x.Element("position").Value : "0", Page = x.Element("page") != null ? x.Element("page").Value : "", Wire = x.Element("wire") != null ? x.Element("wire").Value : "", Profinet = x.Element("profinet") != null ? x.Element("profinet").Value : "", DisableForce = x.Element("disableForce") != null ? Convert.ToBoolean(x.Element("disableForce").Value) : false }) .ToList(); } private static void ReadM156() { // Get Areas file handler XDocument xmlConfigFile = GetXmlHandlerWithValidator(M156_CONFIG_SCHEMA_PATH, M156_CONFIG_PATH); InputsOperatorConfig = xmlConfigFile .Descendants("inputsOperator") .Elements() .Select(x => new InputOperatorConfigModel() { Id = Convert.ToInt32(x.Element("id").Value), Messages = x.Element("title").Elements().ToDictionary( // Read localized names and convert into a dictionary y => y.Attribute("langKey").Value, y => y.Value ), Buttons = x.Element("buttons")?.Elements().ToDictionary( // Read buttons data and convert into a dictionary y => Convert.ToByte(y.Element("value").Value), y => y.Element("title").Elements().ToDictionary( // Read localized names and convert into a dictionary z => z.Attribute("langKey").Value, z => z.Value ) ), Type = GetInputOperatoType(x.Name.ToString()) }) .ToList(); } /// /// Module config setup from file /// private static void ReadModBlockConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(MODBLOCK_CONFIG_SCHEMA_PATH, MODBLOCK_CONFIG_PATH); // Read head config from XML file ModBlockConfig = xmlConfigFile .Root .Elements() .Select(x => new ModBlockConfigModel() { Id = Convert.ToInt16(x.Element("id").Value), Label = x.Element("label").Value, Type = GetTActMB_Type(x.Element("type").Value), Section = GetTActMB_Section(x.Element("section").Value), IdParam = Convert.ToInt16(x.Element("idParam").Value), ShowDelay = Convert.ToBoolean(x.Element("showDelay").Value), Priority = Convert.ToInt16(x.Element("priority").Value), // attributi presi da default se NON presenti... ScaleFactor = x.Element("scaleFactor") != null ? Convert.ToInt16(x.Element("scaleFactor").Value) : 1000, NumDec = x.Element("numDec") != null ? Convert.ToInt16(x.Element("numDec").Value) : 1, Category = x.Element("category") != null ? x.Element("category").Value : "", SubCategory_1 = x.Element("subCategory_1") != null ? x.Element("subCategory_1").Value : "", SubCategory_2 = x.Element("subCategory_2") != null ? x.Element("subCategory_2").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(); } /// /// Recipe Config setup from file /// private static void ReadRecipeConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(RECIPE_CONFIG_SCHEMA_PATH, RECIPE_CONFIG_PATH); // Read Recipe config from XML file RecipeConfig = xmlConfigFile .Root .Elements() .Select(x => new RecipeConfigModel() { Id = Convert.ToInt16(x.Element("id").Value), Category = GetTActParamType(x.Element("category").Value), SubCategory_1 = x.Element("subCategory_1").Value, SubCategory_2 = x.Element("subCategory_2").Value, Name = x.Element("name").Value, Description = x.Element("description").Value, Format = x.Element("format").Value, ScaleFactor = Convert.ToInt16(x.Element("scaleFactor").Value), NumDec = Convert.ToInt16(x.Element("numDec").Value), //EnumVal = new Dictionary() EnumVal = x.Element("enumList") != null ? x.Element("enumList").Elements().ToDictionary( y => y.Element("value").Value, y => new EnumDetail(y.Element("label").Value, y.Element("anim") != null ? y.Element("anim").Value : "") ) : new Dictionary() }) .ToList(); } /// /// Warmers config setup from file /// private static void ReadRiskConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(RISK_CONFIG_SCHEMA_PATH, RISK_CONFIG_PATH); int i = 0; List Riflettori = new List(); List Resistenze = new List(); List Riferimenti = new List(); // carico gli oggetti "nativi" Riferimenti = xmlConfigFile .Root .Elements("riferimenti") .Select(x => new RiskRiferimenti() { Id = Convert.ToInt16(x.Value), Dimensione = Convert.ToInt16(x.Attribute("dimensione").Value), Potenza = Convert.ToInt16(x.Attribute("potenza").Value), Modello = x.Attribute("modello").Value }) .ToList(); Riflettori = xmlConfigFile .Root .Elements("riflettore") .Select(x => new RiskRiflettore() { Tipo = Convert.ToInt16(x.Attribute("tipo").Value), Resistenze = x.Elements("resistenza") .Select(y => new RiskResistenza() { Canale = Convert.ToInt16(y.Attribute("canale").Value), Riga = Convert.ToInt16(y.Attribute("riga").Value), Tipo = Convert.ToInt16(y.Attribute("tipo").Value), IdGruppo = Convert.ToInt16(y.Attribute("idGruppo").Value), } ) .ToList() }) .ToList(); // conversione da modelli RISK a modello Thermo... int numCol = -1; int ResistId = 0; int oldRow = 0; int currIdBoard = 0; int maxCol = 0; int maxRow = 0; RiskBoardConfig = new List(); RiskResistConfig = new List(); RiskChannelConfig = new List(); // inizializzo le 64 schede a 0 canali... for (int idxBoard = 0; idxBoard < 64; idxBoard++) { RiskBoardConfig.Add(new RiskBoardModel() { IdBoard = idxBoard, NumChannels = 0 }); } // ciclo x calcolare i canali foreach (var riflettore in Riflettori) { // ciclo sulle resistenze foreach (var resistenza in riflettore.Resistenze) { // cerco la scheda dato il canale... 16 ch x ogni scheda currIdBoard = (resistenza.Canale - 1) / 16; // cerco se ho già la scheda var boardFound = RiskBoardConfig.Find(item => item.IdBoard == currIdBoard); if (boardFound == null) { RiskBoardConfig.Add(new RiskBoardModel() { IdBoard = currIdBoard, NumChannels = 1 }); } else { boardFound.NumChannels += 1; } // cerco se ho già il canale var chanFound = RiskChannelConfig.Find(item => item.IdChannel == resistenza.Canale); if (chanFound == null) { // cerco il TIPO... var riferimento = Riferimenti.Find(x => x.Id == resistenza.Tipo); if (riferimento != null) { RiskChannelConfig.Add(new RiskChannelModel() { IdChannel = resistenza.Canale, IdReflector = riflettore.Tipo, SetpointRecipe = 0, SetpointThermo = 0, MaxPower = riferimento.Potenza, NumResist = 1, refPosDistance = 999999, refPos = new ThermoPoint(), // imposto default a 0 // 2020.07.27 applicato x tutti CalcIchMin = true //riferimento.Modello.Contains("Quarzo") || riferimento.Modello.Contains("Alogena") }); } } else { chanFound.NumResist += 1; } } } // ciclo sui riflettori x recuperare le resistenze... foreach (var riflettore in Riflettori) { // ciclo sulle resistente foreach (var resistenza in riflettore.Resistenze) { if (oldRow != resistenza.Riga) { numCol = 0; oldRow = resistenza.Riga; } else { numCol++; maxCol = numCol > maxCol ? numCol : maxCol; } // cerco il TIPO... var riferimento = Riferimenti.Find(x => x.Id == resistenza.Tipo); RiskResistConfig.Add(new RiskResistModel() { Id = ResistId++, Row = resistenza.Riga, Column = numCol, IdChannel = resistenza.Canale, Dimension = riferimento.Dimensione, IdReflector = riflettore.Tipo, IdGroup = resistenza.IdGruppo, }); ; maxRow = resistenza.Riga > maxRow ? resistenza.Riga : maxRow; } } // recupero parametri plate e dim resistenze int warmerPlanSizeX = 0; int warmerPlanSizeY = 0; int resistSizeX = 0; int resistSizeY = 0; int flirImgX = 0; int flirImgY = 0; int.TryParse(AdditionalParametersConfig["warmerPlanSizeX"], out warmerPlanSizeX); int.TryParse(AdditionalParametersConfig["warmerPlanSizeY"], out warmerPlanSizeY); int.TryParse(AdditionalParametersConfig["resistSizeX"], out resistSizeX); int.TryParse(AdditionalParametersConfig["resistSizeY"], out resistSizeY); int.TryParse(AdditionalParametersConfig["flirImgX"], out flirImgX); int.TryParse(AdditionalParametersConfig["flirImgY"], out flirImgY); // calcolo punti! ThermoPoint centro = new ThermoPoint() { X = warmerPlanSizeX / 2, Y = warmerPlanSizeY / 2 }; ThermoPoint punto = new ThermoPoint(); ThermoPoint puntoFlirImg = new ThermoPoint(); double actDist = warmerPlanSizeX + warmerPlanSizeY; double minDist = warmerPlanSizeX + warmerPlanSizeY; // ciclo ora per calcolare TUTTE le posizioni di riferimento dei canali (prendendo il centro delle resistenze) Dictionary newPos = new Dictionary(); var listChSup = RiskChannelConfig.Where(x => x.IdReflector == 0); // spazzo riga x riga da elenco resistenze... var listResist = RiskResistConfig.Where(x => x.IdReflector == 0); int currRow = -1; double currX = 0; for (int rigaCorr = 0; rigaCorr <= maxRow; rigaCorr++) { for (int colCorr = 0; colCorr <= maxCol; colCorr++) { var currResist = listResist.FirstOrDefault(x => x.Row == rigaCorr && x.Column == colCorr); if (currResist != null) { // se cambio riga --> mi metto a metà della prima cella if (currResist.Row != currRow) { currX = (currResist.Dimension * resistSizeX) / 2; currRow = currResist.Row; } else { // calcolo coordinata X CumSum currX += (currResist.Dimension * resistSizeX); } //// reset distanza //actDist = warmerPlanSizeX + warmerPlanSizeY; //minDist = warmerPlanSizeX + warmerPlanSizeY; // tutti i calcoli in coordinate mm del riscaldo punto = new ThermoPoint() { X = (int)currX, Y = currResist.Row * resistSizeY + resistSizeY / 2 }; puntoFlirImg = new ThermoPoint(); actDist = ThermoPoint.distance(punto, centro); // cerco i dati del canale attuale... var currChannel = RiskChannelConfig.FirstOrDefault(x => x.IdChannel == currResist.IdChannel); if (currChannel.refPosDistance > actDist) { // riscalo il punto per la dimensione della FLIR puntoFlirImg.X = punto.X * flirImgX / warmerPlanSizeX; puntoFlirImg.Y = punto.Y * flirImgY / warmerPlanSizeY; currChannel.refPos = puntoFlirImg; currChannel.refPosDistance = actDist; } } } } } 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) { validateScada(SCADA_PAGES_SCHEMA_PATH, SCADA_DIRECTORY + file.Name); 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); } } /// /// ThermoProd setup from file /// private static void ReadThermoProdConfig() { XDocument xmlConfigFile = GetXmlHandlerWithValidator(THERMO_PROD_SCHEMA_PATH, THERMO_PROD_PATH); // Read Recipe config from XML file ThermoProdConfig = xmlConfigFile .Root .Elements() .Select(x => new ThermoProdConfigModel() { Category = GetTActProdCategory(x.Element("category").Value), Name = x.Element("name").Value, Label = x.Element("label").Value, UM = x.Element("um").Value, ScaleFactor = Convert.ToInt32(x.Element("scaleFactor").Value), NumDec = Convert.ToInt32(x.Element("numDec").Value), MinVal = Convert.ToInt32(x.Element("minVal").Value), MaxVal = Convert.ToInt32(x.Element("maxVal").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), IsStarred = x.Element("starred") != null ? Convert.ToBoolean(x.Element("starred").Value) : false, RefCallLabel = x.Element("refCallLabel") != null ? x.Element("refCallLabel").Value : "", RefCallParam = x.Element("refCallParam") != null ? x.Element("refCallParam").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 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 SetAreaValueByName(XElement element) { // Choose which area to be set switch (element.Name.ToString()) { case AREAS.PRODUCTION_KEY: SetAreaValue(ref ProductionConfig, 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; case AREAS.THERMO_HOOD_KEY: SetAreaValue(ref ThermoHoodConfig, element); break; } } private static void validateScada(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); } } actualFileName = Path.GetFileName(configFilePath); // Open file reader XDocument xmlConfigFile = XDocument.Load(configFilePath); // Validate file xmlConfigFile.Validate(readerSettings, ValidationHandler); } private static void ValidationHandler(object sender, ValidationEventArgs e) { if (e.Severity == XmlSeverityType.Warning) { ExceptionManager.ManageError(ERROR_LEVEL.WARNING, e.Message, true); } else if (e.Severity == XmlSeverityType.Error) { ExceptionManager.ManageError(ERROR_LEVEL.FATAL, // "Error while reading file: " + e.Exception.SourceUri + "Error while reading XML file \"" + actualFileName + "\" \n\n" + e.Message, true ); } } #endregion Private Methods #region Public Methods public static string CalculateHash(string filename) { using (var sha = SHA1.Create()) { using (var stream = File.OpenRead(filename)) { var hash = sha.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } } } public static bool CheckAreaStatus(string areaName) { // Get Area status ( enabled field) by name switch (areaName) { case AREAS.PRODUCTION_KEY: return ProductionConfig.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; } } public static string GetInputOperatoType(string tagName) { switch (tagName) { case "modalValue": return "REAL"; case "buttonsListModal": return "MULTIPLE_BUTTONS"; case "showValModal": return "SHOW_VAL"; case "simpleModal": return "MODAL"; default: return "REAL"; } } public static void ReadAssistanceConfig() { //Read Standard CMS Configuration XDocument xmlConfigFile = GetXmlHandlerWithValidator(MAINTENANCES_CONFIG_SCHEMA_PATH, MAINTENANCES_CONFIG_PATH); ReadAssistanceConfigFromXml( xmlConfigFile.Root.Descendants("cmsContacts").FirstOrDefault(), out CmsContactConfig, out CmsAuxContact1, out CmsAuxContact2 ); xmlConfigFile = GetXmlHandlerWithValidator(MAINTENANCES_CONFIG_SCHEMA_PATH, MAINTENANCES_CONFIG_PATH); ReadAssistanceConfigFromXml( xmlConfigFile.Root.Descendants("scmContacts").FirstOrDefault(), out ScmContactConfig, out ScmAuxContact1, out ScmAuxContact2 ); } public static void ReadAssistanceConfigFromXml(XElement xmlRoot, out ContactModel MainContact, out ContactModel AuxContact1, out ContactModel AuxContact2) { MainContact = xmlRoot .Descendants("MainOffice") .Select(x => new ContactModel() { Company = x.Element("company").Value, Email = x.Element("email").Value, PhoneNumber = x.Element("phoneNumber").Value, WebSite = x.Element("moreInfoUrl").Value, }) .FirstOrDefault(); AuxContact1 = xmlRoot .Descendants("AuxOffice1") .Select(x => new ContactModel() { Visible = Convert.ToBoolean(x.Element("visible").Value), Name = x.Element("name").Value, Email = x.Element("email").Value, PhoneNumber = x.Element("phoneNumber").Value }) .FirstOrDefault(); AuxContact2 = xmlRoot .Descendants("AuxOffice2") .Select(x => new ContactModel() { Visible = Convert.ToBoolean(x.Element("visible").Value), Name = x.Element("name").Value, Email = x.Element("email").Value, PhoneNumber = x.Element("phoneNumber").Value }) .FirstOrDefault(); } public static bool ReadAssistanceCustomConfig() { DealerContactConfig = null; DealerAuxContact1 = null; DealerAuxContact2 = null; //Read Dealer Configuration if (File.Exists(CUSTOMER_CONTACTS)) { // Open file reader XmlDocument xmlContactFile = new XmlDocument(); xmlContactFile.Load(CUSTOMER_CONTACTS); // Create new instance XmlSchemaSet readerSettings = new XmlSchemaSet(); // Add Schema from Assembly Assembly myAssembly = Assembly.GetExecutingAssembly(); using (Stream schemaStream = myAssembly.GetManifestResourceStream(CUSTOMER_CONTACTS_CONFIG_SCHEMA_PATH)) { using (XmlReader schemaReader = XmlReader.Create(schemaStream)) { readerSettings.Add(null, schemaReader); } } xmlContactFile.Schemas.Add(readerSettings); // Validate file try { xmlContactFile.Validate(null); } catch (XmlSchemaValidationException) { ReadAssistanceConfig(); return false; } ReadAssistanceConfigFromXml( XDocument.Parse(xmlContactFile.OuterXml).Root, out DealerContactConfig, out DealerAuxContact1, out DealerAuxContact2 ); } return true; } 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(); } public static void ReadMaintenancesConfig() { // Get Maintenances file handler XDocument xmlConfigFile = GetXmlHandlerWithValidator(MAINTENANCES_CONFIG_SCHEMA_PATH, MAINTENANCES_CONFIG_PATH); ReadAssistanceConfig(); MaintenancesConfig = xmlConfigFile .Descendants("maintenances") .Elements("maintenance") .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.ParseExact(x.Element("deadline").Value, DATE_TIME_FORMATS, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal), 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(); } 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, MgiOption = Convert.ToBoolean(x.Element("mgiOption").Value), SiemensKeyboardOption = Convert.ToBoolean(x.Element("siemensKeyboardOption").Value), MachineNumberHasLetters = Convert.ToBoolean(x.Element("machineNumberHasLetters").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), TextEditorPath = x.Element("textEditorPath").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), MaxSheetHistoryRows = Convert.ToInt32(x.Element("maxSheetHistoryRows").Value), SheetHistoryToDelete = Convert.ToInt32(x.Element("sheetHistoryToDelete").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(); // carico additionals parameters AdditionalParametersConfig = xmlConfigFile .Descendants("additionalParameters") .Elements("entry") .Select(x => new KeyValuePair(x.Element("key").Value, x.Element("value").Value)) .ToDictionary(x => x.Key, x => x.Value); // carico unità di misura... UnitMeasuresConfig = xmlConfigFile .Descendants("unitOfMeasures") .Elements("unitOfMeasure") .Select(x => new KeyValuePair(Convert.ToInt32(x.Attribute("id").Value), x.Attribute("value").Value)) .ToDictionary(x => x.Key, x => x.Value); // carico conf periodi thread... ThreadSamplingConfig = xmlConfigFile .Descendants("sampling") .Elements("thread") .Select(x => new KeyValuePair(x.Attribute("name").Value, Convert.ToInt32(x.Attribute("value").Value))) .ToDictionary(x => x.Key, x => x.Value); } public static void ReadStartupConfig() { try { ReadServerConfig(); ReadAreaConfig(); ReadMaintenancesConfig(); ReadNcSoftKeys(); ReadUserSoftKeysConfig(); ReadAlarmsConfig(); ReadHeadsConfig(); ReadThermoProdConfig(); ReadRecipeConfig(); ReadModBlockConfig(); ReadIOConfig(); ReadRiskConfig(); ReadAxesConfig(); ReadCMSConnectConfig(); ReadMacros(); ReadScadaFile(); ReadM156(); ReadDataModel(); } catch (XmlException ex) { ExceptionManager.ManageError(ERROR_LEVEL.FATAL, "Error while reading file: " + ex.SourceUri + "\n Error: " + ex.Message, true ); } catch (Exception ex) { var message = ex.Message; if (ex.InnerException != null) message += "\n" + ex.InnerException.Message; ExceptionManager.ManageError(ERROR_LEVEL.FATAL, message, true); } } #endregion Public Methods } }