Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/MECF/Framework/Common/IOCore/IoManager.cs

760 lines
23 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Collections;
2023-04-13 11:51:03 +08:00
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;
2023-04-13 11:51:03 +08:00
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<IoManager>, IIoBuffer
{
private Dictionary<string, DIAccessor> _diMap = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, DOAccessor> _doMap = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, AIAccessor> _aiMap = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, AOAccessor> _aoMap = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<bool[]>> _diBuffer = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<bool[]>> _doBuffer = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<float[]>> _aiBuffer = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<float[]>> _aoBuffer = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<Type>> _aiBufferType = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, IoDataCachePerOffset<Type>> _aoBufferType = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, List<DIAccessor>> _diListPerPlc = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, List<DOAccessor>> _doListPerPlc = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, List<AIAccessor>> _aiListPerPlc = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, List<AOAccessor>> _aoListPerPlc = new();
2023-04-13 11:51:03 +08:00
private Dictionary<string, List<NotifiableIoItem>> _ioItemList = new();
2023-04-13 11:51:03 +08:00
private PeriodicJob _monitorThread;
public void Initialize(string interlockConfigFile, string daemonConfigFile = "")
2023-04-13 11:51:03 +08:00
{
if (!Singleton<InterlockManager>.Instance.Initialize(interlockConfigFile, _doMap, _diMap, _aiMap, _aoMap,
out var reason1))
throw new Exception($"init {nameof(InterlockManager)} error: \r\n{reason1}");
/*if (!Singleton<InterlockDaemonManager>.Instance.Initialize(daemonConfigFile, _doMap, _diMap, _aiMap, _aoMap,
out var reason2))
2023-04-13 11:51:03 +08:00
{
//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);
}
2023-04-13 11:51:03 +08:00
private bool OnTimer()
{
try
{
Singleton<InterlockManager>.Instance.Monitor();
// Singleton<InterlockDaemonManager>.Instance.Monitor();
2023-04-13 11:51:03 +08:00
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
internal List<Tuple<int, int, string>> GetIONameList(string group, IOType ioType)
{
return null;
}
public bool CanSetDo(string doName, bool onOff, out string reason)
{
return Singleton<InterlockManager>.Instance.CanSetDo(doName, onOff, out reason);
}
public List<DIAccessor> GetDIList(string source)
{
return _diListPerPlc.TryGetValue(source, out var value) ? value : null;
}
2023-04-13 11:51:03 +08:00
public List<DOAccessor> GetDOList(string source)
{
return _doListPerPlc.TryGetValue(source, out var value) ? value : null;
2023-04-13 11:51:03 +08:00
}
public List<AIAccessor> GetAIList(string source)
{
return _aiListPerPlc.TryGetValue(source, out var value) ? value : null;
2023-04-13 11:51:03 +08:00
}
public List<AOAccessor> GetAOList(string source)
{
return _aoListPerPlc.TryGetValue(source, out var value) ? value : null;
2023-04-13 11:51:03 +08:00
}
public IoManager()
{
OP.Subscribe("System.SetDoValue", InvokeSetDo);
OP.Subscribe("System.SetAoValue", InvokeSetAo);
OP.Subscribe("System.SetAoValueFloat", InvokeSetAoFloat);
OP.Subscribe("System.SetDoValueWithPrivoder", InvokeSetDoWithProvider);
2023-04-13 11:51:03 +08:00
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];
2023-04-13 11:51:03 +08:00
if (!CanSetDo(text, flag, out var reason))
{
EV.PostWarningLog("System", $"Can not set DO {text} to {flag}, {reason}");
return false;
}
var iO = GetIO<DOAccessor>(text);
2023-04-13 11:51:03 +08:00
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<AOAccessor>(text);
2023-04-13 11:51:03 +08:00
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<AOAccessor>(text);
2023-04-13 11:51:03 +08:00
if (iO == null)
{
EV.PostWarningLog("System", $"Can not set AO {text} to {num}, not defined");
return false;
}
iO.Value = num;
2023-04-13 11:51:03 +08:00
EV.PostInfoLog("System", $"Change AO {text} to {num}");
return true;
}
private bool InvokeSetDoWithProvider(string arg1, object[] args)
2023-04-13 11:51:03 +08:00
{
var text = (string)args[0];
var num = (int)args[1];
var name = (string)args[2];
var flag = (bool)args[3];
2023-04-13 11:51:03 +08:00
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);
2023-04-13 11:51:03 +08:00
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);
2023-04-13 11:51:03 +08:00
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 = (float[])args[2];
2023-04-13 11:51:03 +08:00
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];
2023-04-13 11:51:03 +08:00
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);
2023-04-13 11:51:03 +08:00
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);
2023-04-13 11:51:03 +08:00
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<T>(string name) where T : class
{
if (typeof(T) == typeof(DIAccessor) && _diMap.TryGetValue(name, out var value))
2023-04-13 11:51:03 +08:00
{
return value as T;
2023-04-13 11:51:03 +08:00
}
if (typeof(T) == typeof(DOAccessor) && _doMap.TryGetValue(name, out var value1))
2023-04-13 11:51:03 +08:00
{
return value1 as T;
2023-04-13 11:51:03 +08:00
}
if (typeof(T) == typeof(AIAccessor) && _aiMap.TryGetValue(name, out var value2))
2023-04-13 11:51:03 +08:00
{
return value2 as T;
2023-04-13 11:51:03 +08:00
}
if (typeof(T) == typeof(AOAccessor) && _aoMap.TryGetValue(name, out var value3))
2023-04-13 11:51:03 +08:00
{
return value3 as T;
2023-04-13 11:51:03 +08:00
}
return null;
}
public Dictionary<int, bool[]> GetDiBuffer(string source)
{
if (_diBuffer.TryGetValue(source, out var buffer))
2023-04-13 11:51:03 +08:00
{
return buffer;
2023-04-13 11:51:03 +08:00
}
return null;
}
public Dictionary<int, bool[]> GetDoBuffer(string source)
{
if (_doBuffer.TryGetValue(source, out var buffer))
2023-04-13 11:51:03 +08:00
{
return buffer;
2023-04-13 11:51:03 +08:00
}
return null;
}
public Dictionary<int, float[]> GetAiBuffer(string source)
2023-04-13 11:51:03 +08:00
{
return _aiBuffer.TryGetValue(source, out var f) ? f : null;
2023-04-13 11:51:03 +08:00
}
public Dictionary<int, float[]> GetAoBuffer(string source)
2023-04-13 11:51:03 +08:00
{
return _aoBuffer.TryGetValue(source, out var buffer) ? buffer : null;
2023-04-13 11:51:03 +08:00
}
public void SetDiBuffer(string provider, int offset, bool[] data)
2023-04-13 11:51:03 +08:00
{
if (_diBuffer.ContainsKey(provider) && _diBuffer[provider].ContainsKey(offset))
2023-04-13 11:51:03 +08:00
{
for (var i = 0; i < data.Length && i < _diBuffer[provider][offset].Length; i++)
2023-04-13 11:51:03 +08:00
{
_diBuffer[provider][offset][i] = data[i];
2023-04-13 11:51:03 +08:00
}
}
}
public void SetDoBuffer(string provider, int offset, bool[] data)
2023-04-13 11:51:03 +08:00
{
if (_doBuffer.ContainsKey(provider) && _doBuffer[provider].ContainsKey(offset))
2023-04-13 11:51:03 +08:00
{
for (var i = 0; i < data.Length && i < _doBuffer[provider][offset].Length; i++)
2023-04-13 11:51:03 +08:00
{
_doBuffer[provider][offset][i] = data[i];
2023-04-13 11:51:03 +08:00
}
}
}
public void SetAiBuffer(string provider, int offset, float[] data, int skipSize = 0)
2023-04-13 11:51:03 +08:00
{
if (_aiBuffer.ContainsKey(provider) && _aiBuffer[provider].ContainsKey(offset))
2023-04-13 11:51:03 +08:00
{
for (var i = 0; i < data.Length && i < _aiBuffer[provider][offset].Length; i++)
2023-04-13 11:51:03 +08:00
{
_aiBuffer[provider][offset][i + skipSize] = data[i];
2023-04-13 11:51:03 +08:00
}
}
}
2023-04-13 11:51:03 +08:00
public void SetAoBuffer(string provider, int offset, float[] data, int bufferStartIndex = 0)
2023-04-13 11:51:03 +08:00
{
if (_aoBuffer.ContainsKey(provider) && _aoBuffer[provider].ContainsKey(offset))
2023-04-13 11:51:03 +08:00
{
for (var i = 0; i < data.Length && i < _aoBuffer[provider][offset].Length; i++)
2023-04-13 11:51:03 +08:00
{
_aoBuffer[provider][offset][i] = data[i];
2023-04-13 11:51:03 +08:00
}
}
}
public void SetBufferBlock(string provider, List<IoBlockItem> lstBlocks)
{
foreach (var lstBlock in lstBlocks)
2023-04-13 11:51:03 +08:00
{
switch (lstBlock.Type)
{
case IoType.AI:
if (!_aiBuffer.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_aiBuffer[provider] = new IoDataCachePerOffset<float[]>(provider);
_aiBufferType[provider] = new IoDataCachePerOffset<Type>(provider);
2023-04-13 11:51:03 +08:00
}
if (!_aiBuffer[provider].ContainsKey(lstBlock.Offset))
2023-04-13 11:51:03 +08:00
{
_aiBuffer[provider][lstBlock.Offset] = new float[lstBlock.Size];
2023-04-13 11:51:03 +08:00
_aiBufferType[provider][lstBlock.Offset] = lstBlock.AIOType;
}
break;
case IoType.AO:
if (!_aoBuffer.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_aoBuffer[provider] = new IoDataCachePerOffset<float[]>(provider);
_aoBufferType[provider] = new IoDataCachePerOffset<Type>(provider);
2023-04-13 11:51:03 +08:00
}
if (!_aoBuffer[provider].ContainsKey(lstBlock.Offset))
2023-04-13 11:51:03 +08:00
{
_aoBuffer[provider][lstBlock.Offset] = new float[lstBlock.Size];
2023-04-13 11:51:03 +08:00
_aoBufferType[provider][lstBlock.Offset] = lstBlock.AIOType;
}
break;
case IoType.DI:
if (!_diBuffer.ContainsKey(provider))
{
_diBuffer[provider] = new IoDataCachePerOffset<bool[]>(provider);
2023-04-13 11:51:03 +08:00
}
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 IoDataCachePerOffset<bool[]>(provider);
2023-04-13 11:51:03 +08:00
}
if (!_doBuffer[provider].ContainsKey(lstBlock.Offset))
{
_doBuffer[provider][lstBlock.Offset] = new bool[lstBlock.Size];
}
break;
}
}
}
private List<NotifiableIoItem> SubscribeDiData()
{
var list = new List<NotifiableIoItem>();
foreach (var item2 in _diMap)
2023-04-13 11:51:03 +08:00
{
var item = new NotifiableIoItem
2023-04-13 11:51:03 +08:00
{
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<NotifiableIoItem> SubscribeDoData()
{
var list = new List<NotifiableIoItem>();
foreach (var item2 in _doMap)
2023-04-13 11:51:03 +08:00
{
var item = new NotifiableIoItem
2023-04-13 11:51:03 +08:00
{
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<NotifiableIoItem> SubscribeAiData()
{
var list = new List<NotifiableIoItem>();
foreach (var item2 in _aiMap)
2023-04-13 11:51:03 +08:00
{
var item = new NotifiableIoItem
2023-04-13 11:51:03 +08:00
{
Address = item2.Value.Addr,
Name = item2.Value.Name,
Description = item2.Value.Description,
Index = item2.Value.Index,
ShortValue = (short)item2.Value.Value,
FloatValue = item2.Value.Value,
2023-04-13 11:51:03 +08:00
Provider = item2.Value.Provider,
BlockOffset = item2.Value.BlockOffset,
BlockIndex = item2.Value.Index,
Visible = item2.Value.Visible
};
list.Add(item);
}
return list;
}
private List<NotifiableIoItem> SubscribeAoData()
{
var list = new List<NotifiableIoItem>();
foreach (var item2 in _aoMap)
2023-04-13 11:51:03 +08:00
{
var item = new NotifiableIoItem
2023-04-13 11:51:03 +08:00
{
Address = item2.Value.Addr,
Name = item2.Value.Name,
Description = item2.Value.Description,
Index = item2.Value.Index,
ShortValue = (short)item2.Value.Value,
FloatValue = item2.Value.Value,
2023-04-13 11:51:03 +08:00
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<DIAccessor> ioList)
{
SubscribeIoItemList(provider);
var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false;
foreach (var accessor in ioList)
2023-04-13 11:51:03 +08:00
{
accessor.Provider = provider;
accessor.BlockOffset = blockOffset;
_diMap[accessor.Name] = accessor;
if (!_diListPerPlc.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_diListPerPlc[provider] = new List<DIAccessor>();
2023-04-13 11:51:03 +08:00
}
_diListPerPlc[provider].Add(accessor);
2023-04-13 11:51:03 +08:00
_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<DOAccessor> ioList)
{
SubscribeIoItemList(provider);
var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false;
foreach (var accessor in ioList)
2023-04-13 11:51:03 +08:00
{
accessor.Provider = provider;
accessor.BlockOffset = blockOffset;
_doMap[accessor.Name] = accessor;
if (!_doListPerPlc.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_doListPerPlc[provider] = new List<DOAccessor>();
2023-04-13 11:51:03 +08:00
}
_doListPerPlc[provider].Add(accessor);
2023-04-13 11:51:03 +08:00
_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<AIAccessor> ioList)
{
SubscribeIoItemList(provider);
var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false;
foreach (var accessor in ioList)
2023-04-13 11:51:03 +08:00
{
accessor.Provider = provider;
accessor.BlockOffset = blockOffset;
_aiMap[accessor.Name] = accessor;
if (!_aiListPerPlc.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_aiListPerPlc[provider] = new List<AIAccessor>();
2023-04-13 11:51:03 +08:00
}
_aiListPerPlc[provider].Add(accessor);
2023-04-13 11:51:03 +08:00
_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<AOAccessor> ioList)
{
SubscribeIoItemList(provider);
var flag = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false;
foreach (var accessor in ioList)
2023-04-13 11:51:03 +08:00
{
accessor.Provider = provider;
accessor.BlockOffset = blockOffset;
_aoMap[accessor.Name] = accessor;
if (!_aoListPerPlc.ContainsKey(provider))
2023-04-13 11:51:03 +08:00
{
_aoListPerPlc[provider] = new List<AOAccessor>();
2023-04-13 11:51:03 +08:00
}
_aoListPerPlc[provider].Add(accessor);
2023-04-13 11:51:03 +08:00
_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);
}
}
}
private void LoadIoDefinition<T>(IIoDataCache cache, int blockOffset, XmlNodeList nodeList, IDictionary ioMap, IDictionary dictIoPerPlc, string module = "")
where T: IIOAccessor
{
var isIgnoreSaveDb = SC.GetConfigItem("System.IsIgnoreSaveDB")?.BoolValue ?? false;
foreach (var node in nodeList)
{
if (node is not XmlElement ioNode)
continue;
var ioIndexText = ioNode.GetAttribute("Index");
var ioBuffOffsetText = ioNode.GetAttribute("BufferOffset");
if (string.IsNullOrEmpty(ioBuffOffsetText))
ioBuffOffsetText = ioIndexText;
var ioNameText = ioNode.GetAttribute("Name");
var ioAddrText = ioNode.GetAttribute("Addr");
var ioDescText = ioNode.GetAttribute("Description");
var visible = true;
if (ioNode.HasAttribute("Visible"))
{
if (!bool.TryParse(ioNode.GetAttribute("Visible"), out visible))
visible = true;
}
if (string.IsNullOrEmpty(ioNameText) || string.IsNullOrEmpty(ioIndexText) || string.IsNullOrEmpty(ioBuffOffsetText))
continue;
ioNameText = ioNameText.Trim();
ioIndexText = ioIndexText.Trim();
ioBuffOffsetText = ioBuffOffsetText.Trim();
var ioNameWithModule = (string.IsNullOrEmpty(module) ? ioNameText : (module + "." + ioNameText));
if (!int.TryParse(ioIndexText, out var ioIndex) || !int.TryParse(ioBuffOffsetText, out var ioBuffOffset))
continue;
if (cache == null)
throw new Exception($"Not defined IO Data cache for Accessor {typeof(T)}.");
var provider = cache.ProviderName;
var accessor = (IIOAccessor)Activator.CreateInstance(typeof(T), ioNameWithModule, ioBuffOffset, ioAddrText);
accessor.IoTableIndex = ioIndex;
accessor.Provider = provider;
accessor.BlockOffset = blockOffset;
accessor.Description = ioDescText;
accessor.Visible = visible;
accessor.BindBuffer(cache[blockOffset]);
ioMap.Add(ioNameWithModule, accessor);
if (dictIoPerPlc.Contains(provider) == false)
dictIoPerPlc[provider] = new List<T>();
((IList)dictIoPerPlc[provider]).Add(accessor);
_ioItemList[provider + $".{accessor.Type}ItemList"].Add(new NotifiableIoItem
{
Address = ioAddrText,
Name = ioNameWithModule,
Description = ioDescText,
Index = ioIndex,
Provider = provider,
BlockOffset = blockOffset,
BlockIndex = ioIndex,
Visible = visible
});
if (!isIgnoreSaveDb)
DATA.Subscribe("IO." + ioNameWithModule, () => accessor.NonTypedValue);
}
}
public void SetIoMap(string provider, int blockOffset, string xmlPathFile, string module = "")
{
SubscribeIoItemList(provider);
var xmlDocument = new XmlDocument();
xmlDocument.Load(xmlPathFile);
var xmlNodeDiDefs = xmlDocument.SelectNodes("IO_DEFINE/Dig_In/DI_ITEM");
LoadIoDefinition<DIAccessor>(_diBuffer[provider], blockOffset, xmlNodeDiDefs, _diMap, _diListPerPlc,
module);
var xmlNodeDoDefs = xmlDocument.SelectNodes("IO_DEFINE/Dig_Out/DO_ITEM");
LoadIoDefinition<DOAccessor>(_doBuffer[provider], blockOffset, xmlNodeDoDefs, _doMap, _doListPerPlc,
module);
var xmlNodeAoDefs = xmlDocument.SelectNodes("IO_DEFINE/Ana_Out/AO_ITEM");
LoadIoDefinition<AOAccessor>(_aoBuffer[provider], blockOffset, xmlNodeAoDefs, _aoMap, _aoListPerPlc,
module);
var xmlNodeAiDefs = xmlDocument.SelectNodes("IO_DEFINE/Ana_In/AI_ITEM");
LoadIoDefinition<AIAccessor>(_aiBuffer[provider], blockOffset, xmlNodeAiDefs, _aiMap, _aiListPerPlc,
module);
}
2023-04-13 11:51:03 +08:00
public void SetIoMap(string provider, Dictionary<int, string> ioMappingPathFile)
2023-04-13 11:51:03 +08:00
{
foreach (var item in ioMappingPathFile)
2023-04-13 11:51:03 +08:00
{
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";
2023-04-13 11:51:03 +08:00
if (!_ioItemList.ContainsKey(diKey))
{
_ioItemList[diKey] = [];
2023-04-13 11:51:03 +08:00
DATA.Subscribe(diKey, () => _ioItemList[diKey]);
}
var doKey = provider + ".DOItemList";
2023-04-13 11:51:03 +08:00
if (!_ioItemList.ContainsKey(doKey))
{
_ioItemList[doKey] = [];
2023-04-13 11:51:03 +08:00
DATA.Subscribe(doKey, () => _ioItemList[doKey]);
}
var aiKey = provider + ".AIItemList";
2023-04-13 11:51:03 +08:00
if (!_ioItemList.ContainsKey(aiKey))
{
_ioItemList[aiKey] = [];
2023-04-13 11:51:03 +08:00
DATA.Subscribe(aiKey, () => _ioItemList[aiKey]);
}
var aoKey = provider + ".AOItemList";
2023-04-13 11:51:03 +08:00
if (!_ioItemList.ContainsKey(aoKey))
{
_ioItemList[aoKey] = [];
2023-04-13 11:51:03 +08:00
DATA.Subscribe(aoKey, () => _ioItemList[aoKey]);
}
}
}
}