| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 | 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<BeckhoffIOManager>    {        #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<string, BeckhoffDIAccessor> _diMap = new Dictionary<string, BeckhoffDIAccessor>();        private Dictionary<string, BeckhoffDOAccessor> _doMap = new Dictionary<string, BeckhoffDOAccessor>();        private Dictionary<string, BeckhoffAIAccessor> _aiMap = new Dictionary<string, BeckhoffAIAccessor>();        private Dictionary<string, BeckhoffAOAccessor> _aoMap = new Dictionary<string, BeckhoffAOAccessor>();        private Dictionary<string, List<NotifiableIoItem>> _ioItemList = new Dictionary<string, List<NotifiableIoItem>>();        private int _size = 0;                /// <summary>        /// do对应地址(多个do对应同一址)        /// </summary>        private List<string> _doAddress = new List<string>();        #endregion        #region 属性        /// <summary>        /// IO数据长度        /// </summary>        public int Size { get { return _size; } }        #endregion        /// <summary>        /// 初始化        /// </summary>        /// <param name="cfg"></param>        public void Initialize(BeckhoffCfg cfg)        {            SubscribeIoItemList();            SubscribeOP();            InitialAccessors(cfg);        }        /// <summary>        /// 初始化        /// </summary>        /// <param name="cfg"></param>        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;                    }                }            }        }        /// <summary>        /// 订阅IO集合        /// </summary>        private void SubscribeIoItemList()        {            if (!_ioItemList.ContainsKey(DI_ITEMLIST))            {                _ioItemList[DI_ITEMLIST] = new List<NotifiableIoItem>();                DATA.Subscribe(DI_ITEMLIST, () => _ioItemList[DI_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB);            }            if (!_ioItemList.ContainsKey(DO_ITEMLIST))            {                _ioItemList[DO_ITEMLIST] = new List<NotifiableIoItem>();                DATA.Subscribe(DO_ITEMLIST, () => _ioItemList[DO_ITEMLIST], SubscriptionAttribute.FLAG.IgnoreSaveDB);            }            if (!_ioItemList.ContainsKey(AI_ITEMLIST))            {                _ioItemList[AI_ITEMLIST] = new List<NotifiableIoItem>();                DATA.Subscribe(AI_ITEMLIST, () => _ioItemList[AI_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB);            }            if (!_ioItemList.ContainsKey(AO_ITEMLIST))            {                _ioItemList[AO_ITEMLIST] = new List<NotifiableIoItem>();                DATA.Subscribe(AO_ITEMLIST, () => _ioItemList[AO_ITEMLIST],SubscriptionAttribute.FLAG.IgnoreSaveDB);            }        }        #region 操作OP        /// <summary>        /// 订阅操作        /// </summary>        private void SubscribeOP()        {            OP.Subscribe("System.SetDoValue", WriteDoOperation);            OP.Subscribe("System.SetAoValue32", WriteAoOperation);        }        /// <summary>        /// 写DO变量数值        /// </summary>        /// <param name="arg1"></param>        /// <param name="args"></param>        /// <returns></returns>        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);        }        /// <summary>        /// 写AO变量数值        /// </summary>        /// <param name="arg1"></param>        /// <param name="args"></param>        /// <returns></returns>        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;                    }        /// <summary>        /// 写入IO数值        /// </summary>        /// <param name="name"></param>        /// <param name="value"></param>        /// <returns></returns>        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            }}
 |