using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.IOAxis; using MECF.Framework.Common.Beckhoff.ModuleIO; using MECF.Framework.Common.IOCore; using MECF.Framework.Common.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace MECF.Framework.Common.TwinCat { public class BeckhoffIOManager : Singleton { #region 内部常量 private const string DI_ITEMLIST = "System.DIItemList"; private const string DO_ITEMLIST = "System.DOItemList"; private const string AI_ITEMLIST = "System.AIItemList"; private const string AO_ITEMLIST = "System.AOItemList"; private const string DIGITAL = "Digital"; private const string ANALOG = "Analog"; #endregion #region 内部变量 private Dictionary _diMap = new Dictionary(); private Dictionary _doMap = new Dictionary(); private Dictionary _aiMap = new Dictionary(); private Dictionary _aoMap = new Dictionary(); private Dictionary> _ioItemList = new Dictionary>(); private int _size = 0; /// /// do对应地址(多个do对应同一址) /// private List _doAddress = new List(); #endregion #region 属性 /// /// IO数据长度 /// public int Size { get { return _size; } } #endregion /// /// 初始化 /// /// public void Initialize(BeckhoffCfg cfg) { SubscribeIoItemList(); SubscribeOP(); InitialAccessors(cfg); } /// /// 初始化 /// /// private void InitialAccessors(BeckhoffCfg cfg) { foreach (BeckhoffInput item in cfg.Controller.Inputs) { string key = $"{item.Name}"; if (item.Type == DIGITAL) { if (!_diMap.ContainsKey(key)) { BeckhoffDIAccessor accessor = new BeckhoffDIAccessor(key, item.Address, item.Scaling); _diMap[key] = accessor; _ioItemList[DI_ITEMLIST].Add(new NotifiableIoItem() { Address = accessor.Address, Name = key }); DATA.Subscribe(key, () => accessor.Value, SubscriptionAttribute.FLAG.IgnoreSaveDB); //BeckhoffModuleIOManager.Instance.SubscribeModuleIoValue(key, accessor.Value); BeckhoffItemManager.Instance.InitBeckhoffItem(key,item.Address, item.DataType, "di", 1,false,0,item.Invert); _size++; } } else if (item.Type == ANALOG) { if (!_aiMap.ContainsKey(key)) { BeckhoffAIAccessor accessor = new BeckhoffAIAccessor(key, item.Address, item.Scaling, item.DataType); _aiMap[key] = accessor; _ioItemList[AI_ITEMLIST].Add(new NotifiableIoItem() { Address = accessor.Address, Name = key }); DATA.Subscribe(key, () => accessor.Value, SubscriptionAttribute.FLAG.IgnoreSaveDB); //BeckhoffModuleIOManager.Instance.SubscribeModuleIoValue(key, accessor.Value); int dataSize = DataTypeUtil.GetDataTypeSize(item.DataType); BeckhoffItemManager.Instance.InitBeckhoffItem(key,item.Address, item.DataType,item.Scaling, "ai", dataSize,false,0,item.Invert); _size += dataSize; } } } foreach (BeckhoffOutput item in cfg.Controller.Outputs) { string key = $"{item.Name}"; if (item.Type == DIGITAL) { if (!_doMap.ContainsKey(key)) { BeckhoffDOAccessor accessor = new BeckhoffDOAccessor(key, item.Address, item.Scaling,item.BitOperated,item.Bit); _doMap[key] = accessor; _ioItemList[DO_ITEMLIST].Add(new NotifiableIoItem() { Address = accessor.Address, Name = key }); DATA.Subscribe(key, () => accessor.Value, SubscriptionAttribute.FLAG.IgnoreSaveDB); //BeckhoffModuleIOManager.Instance.SubscribeModuleIoValue(key, accessor.Value); BeckhoffItemManager.Instance.InitBeckhoffItem(key,item.Address, item.DataType, "do", 1,item.BitOperated,item.Bit,item.Invert); BeckhoffItemManager.Instance.InitWriteBeckoffItem(key, item.Address, item.DataType, "do", 1,item.BitOperated,item.Bit,item.Invert); _size++; //if(!_doAddress.Contains(accessor.Address)) //{ // _doAddress.Add(accessor.Address); // _size++; //} } } else if (item.Type == ANALOG) { if (!_aoMap.ContainsKey(key)) { BeckhoffAOAccessor accessor = new BeckhoffAOAccessor(key, item.Address, item.Scaling, item.DataType); _aoMap[key] = accessor; _ioItemList[AO_ITEMLIST].Add(new NotifiableIoItem() { Address = accessor.Address, Name = key }); DATA.Subscribe(key, () => accessor.Value, SubscriptionAttribute.FLAG.IgnoreSaveDB); //BeckhoffModuleIOManager.Instance.SubscribeModuleIoValue(key, accessor.Value); int dataSize = DataTypeUtil.GetDataTypeSize(item.DataType); BeckhoffItemManager.Instance.InitBeckhoffItem(key,item.Address, item.DataType,item.Scaling, "ao", dataSize,false,0, item.Invert); BeckhoffItemManager.Instance.InitWriteBeckoffItem(key, item.Address, item.DataType, "ao", dataSize, false, 0, item.Invert); _size += dataSize; } } } } /// /// 订阅IO集合 /// private void SubscribeIoItemList() { if (!_ioItemList.ContainsKey(DI_ITEMLIST)) { _ioItemList[DI_ITEMLIST] = new List(); DATA.Subscribe(DI_ITEMLIST, () => _ioItemList[DI_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB); } if (!_ioItemList.ContainsKey(DO_ITEMLIST)) { _ioItemList[DO_ITEMLIST] = new List(); DATA.Subscribe(DO_ITEMLIST, () => _ioItemList[DO_ITEMLIST], SubscriptionAttribute.FLAG.IgnoreSaveDB); } if (!_ioItemList.ContainsKey(AI_ITEMLIST)) { _ioItemList[AI_ITEMLIST] = new List(); DATA.Subscribe(AI_ITEMLIST, () => _ioItemList[AI_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB); } if (!_ioItemList.ContainsKey(AO_ITEMLIST)) { _ioItemList[AO_ITEMLIST] = new List(); DATA.Subscribe(AO_ITEMLIST, () => _ioItemList[AO_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB); } } #region 操作OP /// /// 订阅操作 /// private void SubscribeOP() { OP.Subscribe("System.SetDoValue", WriteDoOperation); OP.Subscribe("System.SetAoValue32", WriteAoOperation); } /// /// 写DO变量数值 /// /// /// /// private bool WriteDoOperation(string arg1, object[] args) { string name = (string)args[0]; bool setpoint = (bool)args[1]; BeckhoffItem item = BeckhoffItemManager.Instance.GetWriteBeckhoffItem(name); return TwincatAdoManager.Instance.WriteValue(name, setpoint); } /// /// 写AO变量数值 /// /// /// /// private bool WriteAoOperation(string arg1, object[] args) { string name = (string)args[0]; if (double.TryParse(args[1].ToString(), out var output)) { return WriteIoValue(name, output); } return false; } /// /// 写入IO数值 /// /// /// /// public bool WriteIoValue(string name,object value) { if(ScalingManager.Instance.IsContained(name)) { if(double.TryParse(value.ToString(),out var output)) { var result = ScalingManager.Instance.CalculateTwincatValueByInput(name,output); if(result.Item1) { return TwincatAdoManager.Instance.WriteValue(name, result.Item2); } else { return TwincatAdoManager.Instance.WriteValue(name, value); } } else { return TwincatAdoManager.Instance.WriteValue(name, value); } } return TwincatAdoManager.Instance.WriteValue(name, value); } #endregion #region 获取Accessor和Item public BeckhoffDIAccessor GetDIAccessor(string name) { return _diMap.ContainsKey(name) ? _diMap[name] : null; } public BeckhoffDOAccessor GetDOAccessor(string name) { return _doMap.ContainsKey(name) ? _doMap[name] : null; } public BeckhoffAIAccessor GetAIAccessor(string name) { return _aiMap.ContainsKey(name) ? _aiMap[name] : null; } public BeckhoffAOAccessor GetAOAccesssor(string name) { return _aoMap.ContainsKey(name) ? _aoMap[name] : null; } #endregion } }