using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Xml; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.IOCore; namespace MECF.Framework.RT.Core.IoProviders { public class IoProviderManager : Singleton { private List _providers = new List(); private Dictionary _dicProviders = new Dictionary(); public List Providers => _providers; public IIoProvider GetProvider(string name) { if (_dicProviders.ContainsKey(name)) { return _dicProviders[name]; } return null; } public void Initialize(string xmlConfigFile, Dictionary> ioMappingPathFile) { var xmlDocument = new XmlDocument(); try { xmlDocument.Load(xmlConfigFile); var xmlNodeIoProviders = xmlDocument.SelectNodes("IoProviders/IoProvider"); foreach (var node in xmlNodeIoProviders) { if (!(node is XmlElement nodeProvider) || !(nodeProvider.SelectSingleNode("Parameter") is XmlElement nodeParameter)) { continue; } var attrModule = nodeProvider.GetAttribute("module").Trim(); var attrName = nodeProvider.GetAttribute("name").Trim(); var attrClass = nodeProvider.GetAttribute("class").Trim(); var attrAssembly = nodeProvider.GetAttribute("assembly").Trim(); var attrLoadCond = nodeProvider.GetAttribute("load_condition").Trim(); var isSim = SC.GetConfigItem("System.IsSimulatorMode").BoolValue; if ((isSim && attrLoadCond != "0" && attrLoadCond != "2") || (!isSim && attrLoadCond != "1" && attrLoadCond != "2")) { continue; } var ioProviderName = attrModule + "." + attrName; var type = Assembly.Load(attrAssembly).GetType(attrClass); if (type == null) { throw new Exception(string.Format("ioProvider config file class and assembly not valid," + ioProviderName)); } IIoProvider ioProvider; try { ioProvider = (IIoProvider)Activator.CreateInstance(type); _providers.Add(ioProvider); _dicProviders[ioProviderName] = ioProvider; } catch (Exception ex) { LOG.Write(ex); throw new Exception(string.Format("ioProvider can not be created," + ioProviderName)); } var list = new List(); var xmlNodeBlocks = nodeProvider.SelectNodes("Blocks/Block"); foreach (var nodeBlock in xmlNodeBlocks) { if (!(nodeBlock is XmlElement xmlNodeBlock)) { continue; } var ioBlockItem = new IoBlockItem(); var attrType = xmlNodeBlock.GetAttribute("type"); var attrOffset = xmlNodeBlock.GetAttribute("offset"); var attrSize = xmlNodeBlock.GetAttribute("size"); var attrValueType = xmlNodeBlock.GetAttribute("value_type"); if (!int.TryParse(attrOffset, out var result)) { continue; } ioBlockItem.Offset = result; if (int.TryParse(attrSize, out result)) { ioBlockItem.Size = result; switch (attrType.ToLower()) { case "ai": ioBlockItem.Type = IoType.AI; break; case "ao": ioBlockItem.Type = IoType.AO; break; case "di": ioBlockItem.Type = IoType.DI; break; case "do": ioBlockItem.Type = IoType.DO; break; default: continue; } if (ioBlockItem.Type == IoType.AI || ioBlockItem.Type == IoType.AO) { ioBlockItem.AIOType = ((string.IsNullOrEmpty(attrValueType) || attrValueType.ToLower() != "float") ? typeof(short) : typeof(float)); } list.Add(ioBlockItem); } } if (ioMappingPathFile.ContainsKey(ioProviderName)) { ioProvider.Initialize(attrModule, attrName, list, Singleton.Instance, nodeParameter, ioMappingPathFile[ioProviderName]); ioProvider.Start(); continue; } throw new Exception(string.Format("can not find io map config files," + ioProviderName)); } } catch (Exception ex2) { throw new ApplicationException("IoProvider configuration not valid," + ex2.Message); } } public void Initialize(string xmlConfigFile) { var xmlDoc = new XmlDocument(); try { xmlDoc.Load(xmlConfigFile); var xmlNodeList = xmlDoc.SelectNodes("IoProviders/IoProvider"); foreach (var item in xmlNodeList) { if (!(item is XmlElement xmlElement) || !(xmlElement.SelectSingleNode("Parameter") is XmlElement nodeParameter)) { continue; } var moduleName = xmlElement.GetAttribute("module").Trim(); var providerName = xmlElement.GetAttribute("name").Trim(); var typeName = xmlElement.GetAttribute("class").Trim(); var assemblyString = xmlElement.GetAttribute("assembly").Trim(); var loadCond = xmlElement.GetAttribute("load_condition").Trim(); var isSim = SC.GetConfigItem("System.IsSimulatorMode").BoolValue; if ((isSim && loadCond != "0" && loadCond != "2") || (!isSim && loadCond != "1" && loadCond != "2")) { continue; } var ioProviderName = moduleName + "." + providerName; var type = Assembly.Load(assemblyString).GetType(typeName); if (type == null) { throw new Exception(string.Format("ioProvider config file class and assembly not valid," + ioProviderName)); } IIoProvider ioProvider; try { ioProvider = (IIoProvider)Activator.CreateInstance(type); _providers.Add(ioProvider); _dicProviders[ioProviderName] = ioProvider; } catch (Exception ex) { LOG.Write(ex); throw new Exception(string.Format("ioProvider can not be created," + ioProviderName)); } var list = new List(); var nodeBlocks = xmlElement.SelectNodes("Blocks/Block"); foreach (var nodeBlock in nodeBlocks) { if (!(nodeBlock is XmlElement xmlBlock)) { continue; } var ioBlockItem = new IoBlockItem(); var attrType = xmlBlock.GetAttribute("type"); var attrOffset = xmlBlock.GetAttribute("offset"); var attrSize = xmlBlock.GetAttribute("size"); var attrValueType = xmlBlock.GetAttribute("value_type"); if (!int.TryParse(attrOffset, out var result)) { continue; } ioBlockItem.Offset = result; if (int.TryParse(attrSize, out result)) { ioBlockItem.Size = result; switch (attrType.ToLower()) { case "ai": ioBlockItem.Type = IoType.AI; break; case "ao": ioBlockItem.Type = IoType.AO; break; case "di": ioBlockItem.Type = IoType.DI; break; case "do": ioBlockItem.Type = IoType.DO; break; default: continue; } if (ioBlockItem.Type == IoType.AI || ioBlockItem.Type == IoType.AO) { ioBlockItem.AIOType = ((string.IsNullOrEmpty(attrValueType) || attrValueType.ToLower() != "float") ? typeof(short) : typeof(float)); } list.Add(ioBlockItem); } } var ioModule = xmlElement.GetAttribute("map_module").Trim(); var ioMapFileName = xmlElement.GetAttribute("map_file").Trim(); var fileInfo = new FileInfo(xmlConfigFile); var ioMappingPathFile = fileInfo.Directory.FullName + "\\" + ioMapFileName; ioProvider.Initialize(moduleName, providerName, list, Singleton.Instance, nodeParameter, ioMappingPathFile, ioModule); ioProvider.Start(); } } catch (Exception ex2) { throw new ApplicationException("IoProvider configuration not valid," + ex2.Message); } } public void Terminate() { try { foreach (var provider in _providers) { provider.Stop(); } } catch (Exception ex) { LOG.Write(ex); } } public void Reset() { try { foreach (var provider in _providers) { provider.Reset(); } } catch (Exception ex) { LOG.Write(ex); } } } }