using System; using System.Collections.Generic; using System.Linq; using System.Xml; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.RT.Core.IoProviders; namespace MECF.Framework.Common.IOCore { public class IoManager : Singleton, IIoBuffer { private Dictionary _diMap = new Dictionary(); private Dictionary _doMap = new Dictionary(); private Dictionary _aiMap = new Dictionary(); private Dictionary _aoMap = new Dictionary(); private Dictionary> _diBuffer = new Dictionary>(); private Dictionary> _doBuffer = new Dictionary>(); private Dictionary> _aiBufferShort = new Dictionary>(); private Dictionary> _aoBufferShort = new Dictionary>(); private Dictionary> _aiBufferFloat = new Dictionary>(); private Dictionary> _aoBufferFloat = new Dictionary>(); private Dictionary> _aiBufferType = new Dictionary>(); private Dictionary> _aoBufferType = new Dictionary>(); private Dictionary> _diList = new Dictionary>(); private Dictionary> _doList = new Dictionary>(); private Dictionary> _aiList = new Dictionary>(); private Dictionary> _aoList = new Dictionary>(); private Dictionary> _ioItemList = new Dictionary>(); private PeriodicJob _monitorThread; public void Initialize(string interlockConfigFile, string daemonConfigFile) { if (!InterlockManager.Instance.Initialize(interlockConfigFile, _doMap, _diMap, _aiMap, _aoMap, out var reason1)) throw new Exception($"init {nameof(InterlockManager)} error: \r\n {reason1}"); if (!InterlockDaemonManager.Instance.Initialize(daemonConfigFile, _doMap, _diMap, _aiMap, _aoMap, out var reason2)) { //TODO 暂时允许不定义Daemon配置文件 // throw new Exception($"init {nameof(InterlockDaemonManager)} error: \r\n {reason2}"); LOG.Error($"init {nameof(InterlockDaemonManager)} error: \r\n {reason2}"); } } private bool OnTimer() { try { Singleton.Instance.Monitor(); Singleton.Instance.Monitor(); } catch (Exception ex) { LOG.Write(ex); } return true; } internal List> GetIONameList(string group, IOType ioType) { return null; } public bool CanSetDo(string doName, bool onOff, out string reason) { return Singleton.Instance.CanSetDo(doName, onOff, out reason); } public List GetDIList(string source) { return _diList.ContainsKey(source) ? _diList[source] : null; } public List GetDOList(string source) { return _doList.ContainsKey(source) ? _doList[source] : null; } public List GetAIList(string source) { return _aiList.ContainsKey(source) ? _aiList[source] : null; } public List GetAOList(string source) { return _aoList.ContainsKey(source) ? _aoList[source] : null; } public IoManager() { OP.Subscribe("System.SetDoValue", InvokeSetDo); OP.Subscribe("System.SetAoValue", InvokeSetAo); OP.Subscribe("System.SetAoValueFloat", InvokeSetAoFloat); OP.Subscribe("System.SetDoValueWithPrivoder", InvokeSetDoWithPrivoder); OP.Subscribe("System.SetAoValueWithPrivoder", InvokeSetAoWithPrivoder); OP.Subscribe("System.SetAiBuffer", InvokeSetAiBuffer); OP.Subscribe("System.SetDiBuffer", InvokeSetDiBuffer); _monitorThread = new PeriodicJob(200, OnTimer, "IO Monitor Thread", isStartNow: true); } private bool InvokeSetDo(string arg1, object[] args) { string text = (string)args[0]; bool flag = (bool)args[1]; if (!CanSetDo(text, flag, out var reason)) { EV.PostWarningLog("System", $"Can not set DO {text} to {flag}, {reason}"); return false; } DOAccessor iO = GetIO(text); if (iO == null) { EV.PostWarningLog("System", $"Can not set DO {text} to {flag}, not defined do"); return false; } if (!iO.SetValue(flag, out reason)) { EV.PostWarningLog("System", $"Can not set DO {text} to {flag}, {reason}"); return false; } EV.PostInfoLog("System", $"Change DO {text} to {flag}"); return true; } private bool InvokeSetAo(string arg1, object[] args) { string text = (string)args[0]; short num = (short)args[1]; AOAccessor iO = GetIO(text); if (iO == null) { EV.PostWarningLog("System", $"Can not set AO {text} to {num}, not defined do"); return false; } iO.Value = num; EV.PostInfoLog("System", $"Change AO {text} to {num}"); return true; } private bool InvokeSetAoFloat(string arg1, object[] args) { string text = (string)args[0]; float num = (float)args[1]; AOAccessor iO = GetIO(text); if (iO == null) { EV.PostWarningLog("System", $"Can not set AO {text} to {num}, not defined"); return false; } iO.FloatValue = num; EV.PostInfoLog("System", $"Change AO {text} to {num}"); return true; } private bool InvokeSetDoWithPrivoder(string arg1, object[] args) { string text = (string)args[0]; int num = (int)args[1]; string name = (string)args[2]; bool flag = (bool)args[3]; if (!CanSetDo(name, flag, out var reason)) { EV.PostWarningLog("System", $"Can not set DO {text}.{name} to {flag}, {reason}"); return false; } List dOList = GetDOList(text); if (dOList == null) { EV.PostWarningLog("System", $"Can not set DO {text}.{name} to {flag}, {reason}"); return false; } DOAccessor dOAccessor = dOList.FirstOrDefault((DOAccessor x) => x.Name == name); if (dOAccessor == null) { EV.PostWarningLog("System", $"Can not set DO {text}.{name} to {flag}, {reason}"); return false; } if (!dOAccessor.SetValue(flag, out reason)) { EV.PostWarningLog("System", $"Can not set DO {text}.{name} to {flag}, {reason}"); return false; } EV.PostInfoLog("System", $"Change DO {text}.{name} to {flag}"); return true; } private bool InvokeSetAiBuffer(string arg1, object[] args) { string source = (string)args[0]; int offset = (int)args[1]; short[] buffer = (short[])args[2]; SetAiBuffer(source, offset, buffer); return true; } private bool InvokeSetDiBuffer(string arg1, object[] args) { string source = (string)args[0]; int offset = (int)args[1]; bool[] buffer = (bool[])args[2]; SetDiBuffer(source, offset, buffer); return true; } private bool InvokeSetAoWithPrivoder(string arg1, object[] args) { string text = (string)args[0]; int num = (int)args[1]; string name = (string)args[2]; float num2 = (float)args[3]; string text2 = ""; List aOList = GetAOList(text); if (aOList == null) { EV.PostWarningLog("System", $"Can not set AO {text}.{name} to {num2}, {text2}"); return false; } AOAccessor aOAccessor = aOList.FirstOrDefault((AOAccessor x) => x.Name == name); if (aOAccessor == null) { EV.PostWarningLog("System", $"Can not set AO {text}.{name} to {num2}, {text2}"); return false; } aOAccessor.Value = (short)num2; EV.PostInfoLog("System", $"Change DO {text}.{name} to {num2}"); return true; } public T GetIO(string name) where T : class { if (typeof(T) == typeof(DIAccessor) && _diMap.ContainsKey(name)) { return _diMap[name] as T; } if (typeof(T) == typeof(DOAccessor) && _doMap.ContainsKey(name)) { return _doMap[name] as T; } if (typeof(T) == typeof(AIAccessor) && _aiMap.ContainsKey(name)) { return _aiMap[name] as T; } if (typeof(T) == typeof(AOAccessor) && _aoMap.ContainsKey(name)) { return _aoMap[name] as T; } return null; } public Dictionary GetDiBuffer(string source) { if (_diBuffer.ContainsKey(source)) { return _diBuffer[source]; } return null; } public Dictionary GetDoBuffer(string source) { if (_doBuffer.ContainsKey(source)) { return _doBuffer[source]; } return null; } public Dictionary GetAiBuffer(string source) { if (_aiBufferShort.ContainsKey(source)) { return _aiBufferShort[source]; } return null; } public Dictionary GetAoBufferFloat(string source) { if (_aoBufferFloat.ContainsKey(source)) { return _aoBufferFloat[source]; } return null; } public Dictionary GetAiBufferFloat(string source) { if (_aiBufferFloat.ContainsKey(source)) { return _aiBufferFloat[source]; } return null; } public Dictionary GetAoBuffer(string source) { if (_aoBufferShort.ContainsKey(source)) { return _aoBufferShort[source]; } return null; } public void SetDiBuffer(string source, int offset, bool[] buffer) { if (_diBuffer.ContainsKey(source) && _diBuffer[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _diBuffer[source][offset].Length; i++) { _diBuffer[source][offset][i] = buffer[i]; } } } public void SetAiBuffer(string source, int offset, short[] buffer, int skipSize = 0) { if (_aiBufferShort.ContainsKey(source) && _aiBufferShort[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _aiBufferShort[source][offset].Length; i++) { _aiBufferShort[source][offset][i + skipSize] = buffer[i]; } } } public void SetAiBufferFloat(string source, int offset, float[] buffer, int skipSize = 0) { if (_aiBufferFloat.ContainsKey(source) && _aiBufferFloat[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _aiBufferFloat[source][offset].Length; i++) { _aiBufferFloat[source][offset][i + skipSize] = buffer[i]; } } } public void SetDoBuffer(string source, int offset, bool[] buffer) { if (_doBuffer.ContainsKey(source) && _doBuffer[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _doBuffer[source][offset].Length; i++) { _doBuffer[source][offset][i] = buffer[i]; } } } public void SetAoBuffer(string source, int offset, short[] buffer) { if (_aoBufferShort.ContainsKey(source) && _aoBufferShort[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _aoBufferShort[source][offset].Length; i++) { _aoBufferShort[source][offset][i] = buffer[i]; } } } public void SetAoBufferFloat(string source, int offset, float[] buffer, int bufferStartIndex = 0) { if (_aoBufferFloat.ContainsKey(source) && _aoBufferFloat[source].ContainsKey(offset)) { for (int i = 0; i < buffer.Length && i < _aoBufferFloat[source][offset].Length; i++) { _aoBufferFloat[source][offset][i] = buffer[i]; } } } public void SetAoBuffer(string source, int offset, short[] buffer, int bufferStartIndex) { if (_aoBufferShort.ContainsKey(source) && _aoBufferShort[source].ContainsKey(offset) && _aoBufferShort[source][offset].Length > bufferStartIndex) { for (int i = 0; i < buffer.Length && bufferStartIndex + i < _aoBufferShort[source][offset].Length; i++) { _aoBufferShort[source][offset][bufferStartIndex + i] = buffer[i]; } } } public void SetBufferBlock(string provider, List lstBlocks) { foreach (IoBlockItem lstBlock in lstBlocks) { switch (lstBlock.Type) { case IoType.AI: if (!_aiBufferShort.ContainsKey(provider)) { _aiBufferShort[provider] = new Dictionary(); _aiBufferFloat[provider] = new Dictionary(); _aiBufferType[provider] = new Dictionary(); } if (!_aiBufferShort[provider].ContainsKey(lstBlock.Offset)) { _aiBufferShort[provider][lstBlock.Offset] = new short[lstBlock.Size]; _aiBufferFloat[provider][lstBlock.Offset] = new float[lstBlock.Size]; _aiBufferType[provider][lstBlock.Offset] = lstBlock.AIOType; } break; case IoType.AO: if (!_aoBufferShort.ContainsKey(provider)) { _aoBufferShort[provider] = new Dictionary(); _aoBufferFloat[provider] = new Dictionary(); _aoBufferType[provider] = new Dictionary(); } if (!_aoBufferShort[provider].ContainsKey(lstBlock.Offset)) { _aoBufferShort[provider][lstBlock.Offset] = new short[lstBlock.Size]; _aoBufferFloat[provider][lstBlock.Offset] = new float[lstBlock.Size]; _aoBufferType[provider][lstBlock.Offset] = lstBlock.AIOType; } break; case IoType.DI: if (!_diBuffer.ContainsKey(provider)) { _diBuffer[provider] = new Dictionary(); } if (!_diBuffer[provider].ContainsKey(lstBlock.Offset)) { _diBuffer[provider][lstBlock.Offset] = new bool[lstBlock.Size]; } break; case IoType.DO: if (!_doBuffer.ContainsKey(provider)) { _doBuffer[provider] = new Dictionary(); } if (!_doBuffer[provider].ContainsKey(lstBlock.Offset)) { _doBuffer[provider][lstBlock.Offset] = new bool[lstBlock.Size]; } break; } } } private List SubscribeDiData() { List list = new List(); foreach (KeyValuePair item2 in _diMap) { NotifiableIoItem item = new NotifiableIoItem { Address = item2.Value.Addr, Name = item2.Value.Name, Description = item2.Value.Description, Index = item2.Value.Index, BoolValue = item2.Value.Value, Provider = item2.Value.Provider, BlockOffset = item2.Value.BlockOffset, BlockIndex = item2.Value.Index, Visible = item2.Value.Visible }; list.Add(item); } return list; } private List SubscribeDoData() { List list = new List(); foreach (KeyValuePair item2 in _doMap) { NotifiableIoItem item = new NotifiableIoItem { Address = item2.Value.Addr, Name = item2.Value.Name, Description = item2.Value.Description, Index = item2.Value.Index, BoolValue = item2.Value.Value, Provider = item2.Value.Provider, BlockOffset = item2.Value.BlockOffset, BlockIndex = item2.Value.Index, Visible = item2.Value.Visible }; list.Add(item); } return list; } private List SubscribeAiData() { List list = new List(); foreach (KeyValuePair item2 in _aiMap) { NotifiableIoItem item = new NotifiableIoItem { Address = item2.Value.Addr, Name = item2.Value.Name, Description = item2.Value.Description, Index = item2.Value.Index, ShortValue = item2.Value.Value, FloatValue = item2.Value.FloatValue, Provider = item2.Value.Provider, BlockOffset = item2.Value.BlockOffset, BlockIndex = item2.Value.Index, Visible = item2.Value.Visible }; list.Add(item); } return list; } private List SubscribeAoData() { List list = new List(); foreach (KeyValuePair item2 in _aoMap) { NotifiableIoItem item = new NotifiableIoItem { Address = item2.Value.Addr, Name = item2.Value.Name, Description = item2.Value.Description, Index = item2.Value.Index, ShortValue = item2.Value.Value, FloatValue = item2.Value.FloatValue, Provider = item2.Value.Provider, BlockOffset = item2.Value.BlockOffset, BlockIndex = item2.Value.Index, Visible = item2.Value.Visible }; list.Add(item); } return list; } public void SetIoMap(string provider, int blockOffset, List ioList) { SubscribeIoItemList(provider); bool flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (DIAccessor accessor in ioList) { accessor.Provider = provider; accessor.BlockOffset = blockOffset; _diMap[accessor.Name] = accessor; if (!_diList.ContainsKey(provider)) { _diList[provider] = new List(); } _diList[provider].Add(accessor); _ioItemList[provider + ".DIItemList"].Add(new NotifiableIoItem { Address = accessor.Addr, Name = accessor.Name, Description = accessor.Description, Index = accessor.Index, Provider = provider, BlockOffset = blockOffset, BlockIndex = accessor.BlockOffset, Visible = accessor.Visible }); if (!flag) { DATA.Subscribe("IO." + accessor.Name, () => accessor.Value); } } } public void SetIoMap(string provider, int blockOffset, List ioList) { SubscribeIoItemList(provider); bool flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (DOAccessor accessor in ioList) { accessor.Provider = provider; accessor.BlockOffset = blockOffset; _doMap[accessor.Name] = accessor; if (!_doList.ContainsKey(provider)) { _doList[provider] = new List(); } _doList[provider].Add(accessor); _ioItemList[provider + ".DOItemList"].Add(new NotifiableIoItem { Address = accessor.Addr, Name = accessor.Name, Description = accessor.Description, Index = accessor.Index, Provider = provider, BlockOffset = blockOffset, BlockIndex = accessor.BlockOffset, Visible = accessor.Visible }); if (!flag) { DATA.Subscribe("IO." + accessor.Name, () => accessor.Value); } } } public void SetIoMap(string provider, int blockOffset, List ioList) { SubscribeIoItemList(provider); bool flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (AIAccessor accessor in ioList) { accessor.Provider = provider; accessor.BlockOffset = blockOffset; _aiMap[accessor.Name] = accessor; if (!_aiList.ContainsKey(provider)) { _aiList[provider] = new List(); } _aiList[provider].Add(accessor); _ioItemList[provider + ".AIItemList"].Add(new NotifiableIoItem { Address = accessor.Addr, Name = accessor.Name, Description = accessor.Description, Index = accessor.Index, Provider = provider, BlockOffset = blockOffset, BlockIndex = accessor.BlockOffset, Visible = accessor.Visible }); if (!flag) { DATA.Subscribe("IO." + accessor.Name, () => accessor.Value); } } } public void SetIoMap(string provider, int blockOffset, List ioList) { SubscribeIoItemList(provider); bool flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (AOAccessor accessor in ioList) { accessor.Provider = provider; accessor.BlockOffset = blockOffset; _aoMap[accessor.Name] = accessor; if (!_aoList.ContainsKey(provider)) { _aoList[provider] = new List(); } _aoList[provider].Add(accessor); _ioItemList[provider + ".AOItemList"].Add(new NotifiableIoItem { Address = accessor.Addr, Name = accessor.Name, Description = accessor.Description, Index = accessor.Index, Provider = provider, BlockOffset = blockOffset, BlockIndex = accessor.BlockOffset, Visible = accessor.Visible }); if (!flag) { DATA.Subscribe("IO." + accessor.Name, () => accessor.Value); } } } public void SetIoMap(string provider, int blockOffset, string xmlPathFile, string module = "") { SubscribeIoItemList(provider); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(xmlPathFile); XmlNodeList xmlNodeList = xmlDocument.SelectNodes("IO_DEFINE/Dig_In/DI_ITEM"); bool flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; List list = new List(); foreach (object item in xmlNodeList) { if (!(item is XmlElement xmlElement)) { continue; } string attribute = xmlElement.GetAttribute("Index"); string text = xmlElement.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text)) { text = attribute; } string attribute2 = xmlElement.GetAttribute("Name"); string attribute3 = xmlElement.GetAttribute("Addr"); string attribute4 = xmlElement.GetAttribute("Description"); bool visible = true; if (xmlElement.HasAttribute("Visible")) { visible = Convert.ToBoolean(xmlElement.GetAttribute("Visible")); } if (string.IsNullOrEmpty(attribute2) || string.IsNullOrEmpty(attribute) || string.IsNullOrEmpty(text)) { continue; } attribute2 = attribute2.Trim(); attribute = attribute.Trim(); text = text.Trim(); string text2 = (string.IsNullOrEmpty(module) ? attribute2 : (module + "." + attribute2)); if (!int.TryParse(attribute, out var result) || !int.TryParse(text, out var result2)) { continue; } if (!_diBuffer.ContainsKey(provider)) { throw new Exception("Not defined DI buffer from IO provider, " + provider); } if (!_diBuffer[provider].ContainsKey(blockOffset)) { throw new Exception("Not defined DI buffer from IO provider, " + provider); } DIAccessor diAccessor = new DIAccessor(text2, result2, _diBuffer[provider][blockOffset], _diBuffer[provider][blockOffset]); diAccessor.IoTableIndex = result; diAccessor.Addr = attribute3; diAccessor.Provider = provider; diAccessor.BlockOffset = blockOffset; diAccessor.Description = attribute4; diAccessor.Visible = visible; list.Add(diAccessor); _diMap[text2] = diAccessor; if (!_diList.ContainsKey(provider)) { _diList[provider] = new List(); } _diList[provider].Add(diAccessor); _ioItemList[provider + ".DIItemList"].Add(new NotifiableIoItem { Address = attribute3, Name = text2, Description = attribute4, Index = result, Provider = provider, BlockOffset = blockOffset, BlockIndex = result, Visible = visible }); if (!flag) { DATA.Subscribe("IO." + text2, () => diAccessor.Value); } } XmlNodeList xmlNodeList2 = xmlDocument.SelectNodes("IO_DEFINE/Dig_Out/DO_ITEM"); foreach (object item2 in xmlNodeList2) { if (!(item2 is XmlElement xmlElement2)) { continue; } string attribute5 = xmlElement2.GetAttribute("Index"); string text3 = xmlElement2.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text3)) { text3 = attribute5; } string attribute6 = xmlElement2.GetAttribute("Name"); string attribute7 = xmlElement2.GetAttribute("Addr"); string attribute8 = xmlElement2.GetAttribute("Description"); bool visible2 = true; if (xmlElement2.HasAttribute("Visible")) { visible2 = Convert.ToBoolean(xmlElement2.GetAttribute("Visible")); } if (string.IsNullOrEmpty(attribute6) || string.IsNullOrEmpty(attribute5) || string.IsNullOrEmpty(text3)) { continue; } attribute6 = attribute6.Trim(); attribute5 = attribute5.Trim(); text3 = text3.Trim(); string text4 = (string.IsNullOrEmpty(module) ? attribute6 : (module + "." + attribute6)); if (!int.TryParse(attribute5, out var result3) || !int.TryParse(text3, out var result4)) { continue; } if (!_doBuffer.ContainsKey(provider) || !_doBuffer[provider].ContainsKey(blockOffset)) { throw new Exception("Not defined DO buffer from IO provider, " + provider); } DOAccessor doAccessor = new DOAccessor(text4, result4, _doBuffer[provider][blockOffset]); _doMap[text4] = doAccessor; doAccessor.IoTableIndex = result3; doAccessor.Addr = attribute7; doAccessor.Provider = provider; doAccessor.BlockOffset = blockOffset; doAccessor.Description = attribute8; doAccessor.Visible = visible2; if (!_doList.ContainsKey(provider)) { _doList[provider] = new List(); } _doList[provider].Add(doAccessor); _ioItemList[provider + ".DOItemList"].Add(new NotifiableIoItem { Address = attribute7, Name = text4, Description = attribute8, Index = result3, Provider = provider, BlockOffset = blockOffset, BlockIndex = result3, Visible = visible2 }); if (!flag) { DATA.Subscribe("IO." + text4, () => doAccessor.Value); } } XmlNodeList xmlNodeList3 = xmlDocument.SelectNodes("IO_DEFINE/Ana_Out/AO_ITEM"); foreach (object item3 in xmlNodeList3) { if (!(item3 is XmlElement xmlElement3)) { continue; } string attribute9 = xmlElement3.GetAttribute("Index"); string text5 = xmlElement3.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text5)) { text5 = attribute9; } string attribute10 = xmlElement3.GetAttribute("Name"); string attribute11 = xmlElement3.GetAttribute("Addr"); string attribute12 = xmlElement3.GetAttribute("Description"); bool visible3 = true; if (xmlElement3.HasAttribute("Visible")) { visible3 = Convert.ToBoolean(xmlElement3.GetAttribute("Visible")); } if (string.IsNullOrEmpty(attribute10) || string.IsNullOrEmpty(attribute9) || string.IsNullOrEmpty(text5)) { continue; } attribute10 = attribute10.Trim(); attribute9 = attribute9.Trim(); text5 = text5.Trim(); string text6 = (string.IsNullOrEmpty(module) ? attribute10 : (module + "." + attribute10)); if (!int.TryParse(attribute9, out var result5) || !int.TryParse(text5, out var result6)) { continue; } if (!_aoBufferShort.ContainsKey(provider) || !_aoBufferShort[provider].ContainsKey(blockOffset)) { throw new Exception("Not defined AO buffer from IO provider, " + provider); } AOAccessor aoAccessor = new AOAccessor(text6, result6, _aoBufferShort[provider][blockOffset], _aoBufferFloat[provider][blockOffset]); _aoMap[text6] = aoAccessor; aoAccessor.IoTableIndex = result5; aoAccessor.Addr = attribute11; aoAccessor.Provider = provider; aoAccessor.BlockOffset = blockOffset; aoAccessor.Description = attribute12; aoAccessor.Visible = visible3; if (!_aoList.ContainsKey(provider)) { _aoList[provider] = new List(); } _aoList[provider].Add(aoAccessor); _ioItemList[provider + ".AOItemList"].Add(new NotifiableIoItem { Address = attribute11, Name = text6, Description = attribute12, Index = result5, Provider = provider, BlockOffset = blockOffset, BlockIndex = result5, Visible = visible3 }); if (flag) { continue; } if (_aoBufferType.ContainsKey(provider) && _aoBufferType[provider].ContainsKey(blockOffset) && _aoBufferType[provider][blockOffset] == typeof(float)) { DATA.Subscribe("IO." + text6, () => aoAccessor.FloatValue); } else { DATA.Subscribe("IO." + text6, () => aoAccessor.Value); } } XmlNodeList xmlNodeList4 = xmlDocument.SelectNodes("IO_DEFINE/Ana_In/AI_ITEM"); foreach (object item4 in xmlNodeList4) { if (!(item4 is XmlElement xmlElement4)) { continue; } string attribute13 = xmlElement4.GetAttribute("Index"); string text7 = xmlElement4.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text7)) { text7 = attribute13; } string attribute14 = xmlElement4.GetAttribute("Name"); string attribute15 = xmlElement4.GetAttribute("Addr"); string attribute16 = xmlElement4.GetAttribute("Description"); bool visible4 = true; if (xmlElement4.HasAttribute("Visible")) { visible4 = Convert.ToBoolean(xmlElement4.GetAttribute("Visible")); } if (string.IsNullOrEmpty(attribute14) || string.IsNullOrEmpty(attribute13) || string.IsNullOrEmpty(text7)) { continue; } attribute14 = attribute14.Trim(); attribute13 = attribute13.Trim(); text7 = text7.Trim(); string text8 = (string.IsNullOrEmpty(module) ? attribute14 : (module + "." + attribute14)); if (!int.TryParse(attribute13, out var result7) || !int.TryParse(text7, out var result8)) { continue; } if (!_aiBufferShort.ContainsKey(provider) || !_aiBufferShort[provider].ContainsKey(blockOffset)) { throw new Exception("Not defined AI buffer from IO provider, " + provider); } AIAccessor aiAccessor = new AIAccessor(text8, result8, _aiBufferShort[provider][blockOffset], _aiBufferFloat[provider][blockOffset]); _aiMap[text8] = aiAccessor; aiAccessor.IoTableIndex = result7; aiAccessor.Addr = attribute15; aiAccessor.Provider = provider; aiAccessor.BlockOffset = blockOffset; aiAccessor.Description = attribute16; aiAccessor.Visible = visible4; if (!_aiList.ContainsKey(provider)) { _aiList[provider] = new List(); } _aiList[provider].Add(aiAccessor); _ioItemList[provider + ".AIItemList"].Add(new NotifiableIoItem { Address = attribute15, Name = text8, Description = attribute16, Index = result7, Provider = provider, BlockOffset = blockOffset, BlockIndex = result7, Visible = visible4 }); if (flag) { continue; } if (_aiBufferType.ContainsKey(provider) && _aiBufferType[provider].ContainsKey(blockOffset) && _aiBufferType[provider][blockOffset] == typeof(float)) { DATA.Subscribe("IO." + text8, () => aiAccessor.FloatValue); } else { DATA.Subscribe("IO." + text8, () => aiAccessor.Value); } } } public void SetIoMap(string provider, Dictionary ioMappingPathFile) { foreach (KeyValuePair item in ioMappingPathFile) { SetIoMap(provider, item.Key, item.Value); } DATA.Subscribe(provider, "DIList", SubscribeDiData); DATA.Subscribe(provider, "DOList", SubscribeDoData); DATA.Subscribe(provider, "AIList", SubscribeAiData); DATA.Subscribe(provider, "AOList", SubscribeAoData); } public void SetIoMapByModule(string provider, int offset, string ioMappingPathFile, string module) { SetIoMap(provider, offset, ioMappingPathFile, module); DATA.Subscribe(provider, "DIList", SubscribeDiData); DATA.Subscribe(provider, "DOList", SubscribeDoData); DATA.Subscribe(provider, "AIList", SubscribeAiData); DATA.Subscribe(provider, "AOList", SubscribeAoData); } private void SubscribeIoItemList(string provider) { string diKey = provider + ".DIItemList"; if (!_ioItemList.ContainsKey(diKey)) { _ioItemList[diKey] = new List(); DATA.Subscribe(diKey, () => _ioItemList[diKey]); } string doKey = provider + ".DOItemList"; if (!_ioItemList.ContainsKey(doKey)) { _ioItemList[doKey] = new List(); DATA.Subscribe(doKey, () => _ioItemList[doKey]); } string aiKey = provider + ".AIItemList"; if (!_ioItemList.ContainsKey(aiKey)) { _ioItemList[aiKey] = new List(); DATA.Subscribe(aiKey, () => _ioItemList[aiKey]); } string aoKey = provider + ".AOItemList"; if (!_ioItemList.ContainsKey(aoKey)) { _ioItemList[aoKey] = new List(); DATA.Subscribe(aoKey, () => _ioItemList[aoKey]); } } } }