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.IOCore.Interlock; 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(); private Dictionary _doMap = new(); private Dictionary _aiMap = new(); private Dictionary _aoMap = new(); private Dictionary> _diBuffer = new(); private Dictionary> _doBuffer = new(); private Dictionary> _aiBufferShort = new(); private Dictionary> _aoBufferShort = new(); private Dictionary> _aiBufferFloat = new(); private Dictionary> _aoBufferFloat = new(); private Dictionary> _aiBufferType = new(); private Dictionary> _aoBufferType = new(); private Dictionary> _diList = new(); private Dictionary> _doList = new(); private Dictionary> _aiList = new(); private Dictionary> _aoList = new(); private Dictionary> _ioItemList = new(); private PeriodicJob _monitorThread; public void Initialize(string interlockConfigFile, string daemonConfigFile = "") { if (!Singleton.Instance.Initialize(interlockConfigFile, _doMap, _diMap, _aiMap, _aoMap, out var reason1)) throw new Exception($"init {nameof(InterlockManager)} error: \r\n{reason1}"); /*if (!Singleton.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}"); }*/ if(_monitorThread == null) _monitorThread = new PeriodicJob(200, OnTimer, "IOManager Monitor Thread", isStartNow: true); } 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.TryGetValue(source, out var value) ? value : null; } public List GetDOList(string source) { return _doList.TryGetValue(source, out var value) ? value : null; } public List GetAIList(string source) { return _aiList.TryGetValue(source, out var value) ? value : null; } public List GetAOList(string source) { return _aoList.TryGetValue(source, out var value) ? value : null; } public IoManager() { OP.Subscribe("System.SetDoValue", InvokeSetDo); OP.Subscribe("System.SetAoValue", InvokeSetAo); OP.Subscribe("System.SetAoValueFloat", InvokeSetAoFloat); OP.Subscribe("System.SetDoValueWithPrivoder", InvokeSetDoWithProvider); OP.Subscribe("System.SetAoValueWithPrivoder", InvokeSetAoWithPrivoder); OP.Subscribe("System.SetAiBuffer", InvokeSetAiBuffer); OP.Subscribe("System.SetDiBuffer", InvokeSetDiBuffer); } private bool InvokeSetDo(string arg1, object[] args) { var text = (string)args[0]; var flag = (bool)args[1]; if (!CanSetDo(text, flag, out var reason)) { EV.PostWarningLog("System", $"Can not set DO {text} to {flag}, {reason}"); return false; } var 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) { var text = (string)args[0]; var num = (short)args[1]; var 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) { var text = (string)args[0]; var num = (float)args[1]; var 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 InvokeSetDoWithProvider(string arg1, object[] args) { var text = (string)args[0]; var num = (int)args[1]; var name = (string)args[2]; var 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; } var dOList = GetDOList(text); if (dOList == null) { EV.PostWarningLog("System", $"Can not set DO {text}.{name} to {flag}, {reason}"); return false; } var 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) { var source = (string)args[0]; var offset = (int)args[1]; var buffer = (short[])args[2]; SetAiBuffer(source, offset, buffer); return true; } private bool InvokeSetDiBuffer(string arg1, object[] args) { var source = (string)args[0]; var offset = (int)args[1]; var buffer = (bool[])args[2]; SetDiBuffer(source, offset, buffer); return true; } private bool InvokeSetAoWithPrivoder(string arg1, object[] args) { var text = (string)args[0]; var num = (int)args[1]; var name = (string)args[2]; var num2 = (float)args[3]; var text2 = ""; var aOList = GetAOList(text); if (aOList == null) { EV.PostWarningLog("System", $"Can not set AO {text}.{name} to {num2}, {text2}"); return false; } var 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.TryGetValue(name, out var value)) { return value as T; } if (typeof(T) == typeof(DOAccessor) && _doMap.TryGetValue(name, out var value1)) { return value1 as T; } if (typeof(T) == typeof(AIAccessor) && _aiMap.TryGetValue(name, out var value2)) { return value2 as T; } if (typeof(T) == typeof(AOAccessor) && _aoMap.TryGetValue(name, out var value3)) { return value3 as T; } return null; } public Dictionary GetDiBuffer(string source) { if (_diBuffer.TryGetValue(source, out var buffer)) { return buffer; } return null; } public Dictionary GetDoBuffer(string source) { if (_doBuffer.TryGetValue(source, out var buffer)) { return buffer; } return null; } public Dictionary GetAiBuffer(string source) { if (_aiBufferShort.TryGetValue(source, out var buffer)) { return buffer; } return null; } public Dictionary GetAoBufferFloat(string source) { if (_aoBufferFloat.TryGetValue(source, out var f)) { return f; } return null; } public Dictionary GetAiBufferFloat(string source) { if (_aiBufferFloat.TryGetValue(source, out var f)) { return f; } return null; } public Dictionary GetAoBuffer(string source) { if (_aoBufferShort.TryGetValue(source, out var buffer)) { return buffer; } return null; } public void SetDiBuffer(string source, int offset, bool[] buffer) { if (_diBuffer.ContainsKey(source) && _diBuffer[source].ContainsKey(offset)) { for (var 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 (var 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 (var 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 (var 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 (var 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 (var 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 (var 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 (var 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() { var list = new List(); foreach (var item2 in _diMap) { var 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() { var list = new List(); foreach (var item2 in _doMap) { var 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() { var list = new List(); foreach (var item2 in _aiMap) { var 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() { var list = new List(); foreach (var item2 in _aoMap) { var 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); var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (var 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); var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (var 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); var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (var 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); var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; foreach (var 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); var xmlDocument = new XmlDocument(); xmlDocument.Load(xmlPathFile); var xmlNodeList = xmlDocument.SelectNodes("IO_DEFINE/Dig_In/DI_ITEM"); var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false; var list = new List(); foreach (var item in xmlNodeList) { if (!(item is XmlElement xmlElement)) { continue; } var attribute = xmlElement.GetAttribute("Index"); var text = xmlElement.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text)) { text = attribute; } var attribute2 = xmlElement.GetAttribute("Name"); var attribute3 = xmlElement.GetAttribute("Addr"); var attribute4 = xmlElement.GetAttribute("Description"); var 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(); var 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); } var 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); } } var xmlNodeList2 = xmlDocument.SelectNodes("IO_DEFINE/Dig_Out/DO_ITEM"); foreach (var item2 in xmlNodeList2) { if (!(item2 is XmlElement xmlElement2)) { continue; } var attribute5 = xmlElement2.GetAttribute("Index"); var text3 = xmlElement2.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text3)) { text3 = attribute5; } var attribute6 = xmlElement2.GetAttribute("Name"); var attribute7 = xmlElement2.GetAttribute("Addr"); var attribute8 = xmlElement2.GetAttribute("Description"); var 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(); var 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); } var 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); } } var xmlNodeList3 = xmlDocument.SelectNodes("IO_DEFINE/Ana_Out/AO_ITEM"); foreach (var item3 in xmlNodeList3) { if (!(item3 is XmlElement xmlElement3)) { continue; } var attribute9 = xmlElement3.GetAttribute("Index"); var text5 = xmlElement3.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text5)) { text5 = attribute9; } var attribute10 = xmlElement3.GetAttribute("Name"); var attribute11 = xmlElement3.GetAttribute("Addr"); var attribute12 = xmlElement3.GetAttribute("Description"); var 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(); var 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); } var 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); } } var xmlNodeList4 = xmlDocument.SelectNodes("IO_DEFINE/Ana_In/AI_ITEM"); foreach (var item4 in xmlNodeList4) { if (!(item4 is XmlElement xmlElement4)) { continue; } var attribute13 = xmlElement4.GetAttribute("Index"); var text7 = xmlElement4.GetAttribute("BufferOffset"); if (string.IsNullOrEmpty(text7)) { text7 = attribute13; } var attribute14 = xmlElement4.GetAttribute("Name"); var attribute15 = xmlElement4.GetAttribute("Addr"); var attribute16 = xmlElement4.GetAttribute("Description"); var 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(); var 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); } var 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 (var 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) { var diKey = provider + ".DIItemList"; if (!_ioItemList.ContainsKey(diKey)) { _ioItemList[diKey] = new List(); DATA.Subscribe(diKey, () => _ioItemList[diKey]); } var doKey = provider + ".DOItemList"; if (!_ioItemList.ContainsKey(doKey)) { _ioItemList[doKey] = new List(); DATA.Subscribe(doKey, () => _ioItemList[doKey]); } var aiKey = provider + ".AIItemList"; if (!_ioItemList.ContainsKey(aiKey)) { _ioItemList[aiKey] = new List(); DATA.Subscribe(aiKey, () => _ioItemList[aiKey]); } var aoKey = provider + ".AOItemList"; if (!_ioItemList.ContainsKey(aoKey)) { _ioItemList[aoKey] = new List(); DATA.Subscribe(aoKey, () => _ioItemList[aoKey]); } } } }