| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 | 
							- using Aitex.Core.RT.Event;
 
- using Aitex.Core.RT.IOCore;
 
- using Aitex.Core.RT.Log;
 
- using Aitex.Core.Util;
 
- using MECF.Framework.Common.Beckhoff.IOAxis;
 
- using MECF.Framework.Common.IOCore;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.IO;
 
- using System.Linq;
 
- using System.Text;
 
- using System.Threading;
 
- using System.Threading.Tasks;
 
- using System.Xml;
 
- using TwinCAT;
 
- using TwinCAT.Ads;
 
- using TwinCAT.Ads.TypeSystem;
 
- using TwinCAT.Ads.ValueAccess;
 
- using TwinCAT.TypeSystem;
 
- namespace MECF.Framework.Common.TwinCat
 
- {
 
-     public class TwincatAdoManager : Singleton<TwincatAdoManager>
 
-     {
 
-         #region 内部变量
 
-         private TcAdsClient _adsClient = null;
 
-         private string _ipAddress = "";
 
-         private int _port = 851;
 
-         private BeckhoffCfg _cfg;
 
-         private Dictionary<int, BeckhoffItem> _handleItemDic = new Dictionary<int, BeckhoffItem>();
 
-         private Dictionary<string, int> _notificationNameHandleDic = new Dictionary<string, int>();
 
-         private Dictionary<string, int> _writeNameHandleDic = new Dictionary<string, int>();
 
-         private AdsStream _adsStream;
 
-         private BinaryReader _reader;
 
-         private bool _isConnected = false;
 
-         /// <summary>
 
-         /// BitOperated地址数值字典(key-BitOperated为true地址,value-数值)
 
-         /// </summary>
 
-         private Dictionary<string, byte> _bitOperatedAddressValueDic = new Dictionary<string, byte>();
 
-         /// <summary>
 
-         /// BitOperated锁
 
-         /// </summary>
 
-         private object _bitOperatedLocker = new object();
 
-         #endregion
 
-         #region 属性
 
-         public bool IsConnect
 
-         {
 
-             get { return _isConnected; }
 
-             set { _isConnected = value; }
 
-         }
 
-         #endregion
 
-         /// <summary>
 
-         /// 初始化
 
-         /// </summary>
 
-         public void Initialize()
 
-         {
 
-             int size=BeckhoffIOManager.Instance.Size+BeckhoffAxisManager.Instance.Size+BeckhoffCounterManager.Instance.Size;
 
-             Init(BeckhoffManager.Instance.BeckhoffCfg, size+100);
 
-         }
 
-         /// <summary>
 
-         /// 初始化
 
-         /// </summary>
 
-         /// <param name="ipAddress"></param>
 
-         /// <param name="port"></param>
 
-         private void Init(BeckhoffCfg beckhoffCfg,int size)
 
-         {
 
-             _adsClient = new TcAdsClient();
 
-             _adsClient.ConnectionStateChanged += AdsClient_ConnectionStateChanged;
 
-             _cfg = beckhoffCfg;
 
-             _ipAddress = beckhoffCfg.Controller.IPAddress;
 
-             _port = int.Parse(beckhoffCfg.Controller.PortAddress);
 
-             _adsStream = new AdsStream(size);
 
-             _reader=new BinaryReader(_adsStream);
 
-             _adsClient.AdsNotification += AdsClient_AdsNotification;
 
-             _adsClient.AdsNotificationError += AdsClient_AdsNotificationError;
 
-             Start();
 
-         }
 
-         private void AdsClient_AdsNotificationError(object sender, AdsNotificationErrorEventArgs e)
 
-         {
 
-         }
 
-         /// <summary>
 
-         /// 连接状态变化
 
-         /// </summary>
 
-         /// <param name="sender"></param>
 
-         /// <param name="e"></param>
 
-         private void AdsClient_ConnectionStateChanged(object sender, TwinCAT.ConnectionStateChangedEventArgs e)
 
-         {
 
-             LOG.WriteLog(eEvent.INFO_TWINCAT, "System", $"Twincat connect{_cfg.Controller.IPAddress}:{_cfg.Controller.PortAddress} stated changed from {e.OldState} to {e.NewState}");
 
-             if (e.NewState==TwinCAT.ConnectionState.Connected)
 
-             {
 
-                 try
 
-                 {
 
-                     StateInfo stateInfo = _adsClient.ReadState();
 
-                     CreateWriteHandle();
 
-                     SubscribeNotification();                    
 
-                     _isConnected = true;
 
-                     BeckhoffAxisManager.Instance.StartCoeInterface();
 
-                 }
 
-                 catch(Exception ex)
 
-                 {
 
-                     _isConnected = false;
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT,"System",$"Twincat connect{_cfg.Controller.IPAddress}:{_cfg.Controller.PortAddress} error");
 
-                     return;
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 _isConnected = false;
 
-                 LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat connect{_cfg.Controller.IPAddress}:{_cfg.Controller.PortAddress} error");
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 启动
 
-         /// </summary>
 
-         public void Start()
 
-         {
 
-             try
 
-             {
 
-                 _adsClient.Connect(_ipAddress, _port);
 
-             }
 
-             catch
 
-             {
 
-                 LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat connect{_cfg.Controller.IPAddress}:{_cfg.Controller.PortAddress} error");
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 订阅变量
 
-         /// </summary>
 
-         private void SubscribeNotification()
 
-         {
 
-             _notificationNameHandleDic.Clear();
 
-             _handleItemDic.Clear();
 
-             int count = 0;
 
-             List<BeckhoffItem> beckhoffItems = BeckhoffItemManager.Instance.GetIOItems();
 
-             foreach(BeckhoffItem item in beckhoffItems)
 
-             {
 
-                 try
 
-                 {
 
-                     int handle = _adsClient.AddDeviceNotification(item.Address, _adsStream, count, item.Size, AdsTransMode.OnChange, 0, 0, item);
 
-                     _notificationNameHandleDic[item.Name] = handle;
 
-                     _handleItemDic[handle] = item;
 
-                     count += item.Size;
 
-                 }
 
-                 catch(Exception ex)
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat add variable {item.Name} error");
 
-                 }
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 创建写入句柄
 
-         /// </summary>
 
-         private void CreateWriteHandle()
 
-         {
 
-             _writeNameHandleDic.Clear();
 
-             foreach(BeckhoffItem item in  BeckhoffItemManager.Instance.GetWriteItems())
 
-             {
 
-                 try
 
-                 {
 
-                     int handle = _adsClient.CreateVariableHandle(item.Address);
 
-                     _writeNameHandleDic[item.Name] = handle;
 
-                 }
 
-                 catch
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat create variable handle {item.Name} error");
 
-                 }
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 写入数值
 
-         /// </summary>
 
-         /// <param name="name"></param>
 
-         /// <param name="value"></param>
 
-         /// <returns></returns>
 
-         public bool WriteValue(string name,object value)
 
-         {
 
-             if(_writeNameHandleDic.ContainsKey(name))
 
-             {
 
-                 if(!_isConnected)
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT,"System", $"Twincat connected failed, write variable {name} error");
 
-                     return false;
 
-                 }
 
-                 int handle = _writeNameHandleDic[name];
 
-                 BeckhoffItem item = BeckhoffItemManager.Instance.GetIOBeckhoffItem(name);
 
-                 object convertedValue = value;
 
-                 
 
-                 try
 
-                 {
 
-                     if (item != null && item.BitOperated)
 
-                     {
 
-                         if (item.Invert && convertedValue is bool)
 
-                         {
 
-                             convertedValue = !(bool)convertedValue;
 
-                         }
 
-                         lock (_bitOperatedLocker)
 
-                         {
 
-                             convertedValue = GetBeckoffItemValue(item, convertedValue);
 
-                             _adsClient.WriteAny(handle, convertedValue);
 
-                             _bitOperatedAddressValueDic[item.Address] = (byte)convertedValue;
 
-                         }
 
-                     }
 
-                     else
 
-                     {
 
-                         _adsClient.WriteAny(handle, convertedValue);
 
-                     }
 
-                     LOG.WriteLog(eEvent.INFO_TWINCAT, "System", $"Twincat write variable {name} value {convertedValue}");
 
-                     return true;
 
-                 }
 
-                 catch(Exception ex)
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT,"System", $"Twincat write variable {name} error {ex.Message}");
 
-                     return false;
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 LOG.WriteLog(eEvent.ERR_TWINCAT,"System", $"Twincat doesnot has {name} variable");
 
-             }
 
-             return false;
 
-         }
 
-         /// <summary>
 
-         /// 获取Beckhoff项数值(用于解决BitOperated为true)
 
-         /// </summary>
 
-         /// <param name="name"></param>
 
-         /// <param name="value"></param>
 
-         /// <returns></returns>
 
-         private object GetBeckoffItemValue(BeckhoffItem item,object value)
 
-         {
 
-             if (_bitOperatedAddressValueDic.ContainsKey(item.Address))
 
-             {
 
-                 byte addressValue = _bitOperatedAddressValueDic[item.Address];
 
-                 bool[] boolArray = Converter.GetboolArrayByByte(addressValue);
 
-                 bool boolValue = (bool)value;
 
-                 if (item.Bit < boolArray.Length)
 
-                 {
 
-                     boolArray[item.Bit] = boolValue;
 
-                 }
 
-                 byte byt = Converter.GetByteValueByBoolArray(boolArray);
 
-                 return byt;
 
-             }
 
-             else
 
-             {
 
-                 return value;
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 变量数值发生变化事件
 
-         /// </summary>
 
-         /// <param name="sender"></param>
 
-         /// <param name="e"></param>
 
-         private void AdsClient_AdsNotification(object sender, AdsNotificationEventArgs e)
 
-         {
 
-             try
 
-             {
 
-                 BeckhoffItem item = null;
 
-                 if (_handleItemDic.ContainsKey(e.NotificationHandle))
 
-                 {
 
-                     item = _handleItemDic[e.NotificationHandle];
 
-                 }
 
-                 else
 
-                 {
 
-                     item = (BeckhoffItem)e.UserData;
 
-                 }
 
-                 e.DataStream.Position = e.Offset;
 
-                 if (item != null)
 
-                 {
 
-                     switch (item.IoType)
 
-                     {
 
-                         case "di":
 
-                             BeckhoffDIAccessor diAccessor = BeckhoffIOManager.Instance.GetDIAccessor(item.Name);
 
-                             if (diAccessor != null)
 
-                             {
 
-                                 diAccessor.Value = _reader.ReadBoolean();
 
-                                 if (item.Invert)
 
-                                 {
 
-                                     IOModuleManager.Instance.UpdateIoValue(item.Name, !diAccessor.Value);
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     IOModuleManager.Instance.UpdateIoValue(item.Name, diAccessor.Value);
 
-                                 }
 
-                             }
 
-                             break;
 
-                         case "do":
 
-                             BeckhoffDOAccessor doAccessor = BeckhoffIOManager.Instance.GetDOAccessor(item.Name);
 
-                             if (doAccessor != null)
 
-                             {
 
-                                 if (item.BitOperated)
 
-                                 {
 
-                                     byte byt = _reader.ReadByte();
 
-                                     lock (_bitOperatedLocker)
 
-                                     {
 
-                                         _bitOperatedAddressValueDic[doAccessor.Address] = byt;
 
-                                     }
 
-                                     doAccessor.Value = ((byt >> item.Bit) & 0x01) == 0x01;
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     doAccessor.Value = _reader.ReadBoolean();
 
-                                 }
 
-                                 if (item.Invert)
 
-                                 {
 
-                                     IOModuleManager.Instance.UpdateIoValue(item.Name, !doAccessor.Value);
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     IOModuleManager.Instance.UpdateIoValue(item.Name, doAccessor.Value);
 
-                                 }
 
-                             }
 
-                             break;
 
-                         case "ai":
 
-                             BeckhoffAIAccessor aiAccessor = BeckhoffIOManager.Instance.GetAIAccessor(item.Name);
 
-                             if (aiAccessor != null)
 
-                             {
 
-                                 double twincatValue = GetAnalogValue(item.DataType);
 
-                                 var result = ScalingManager.Instance.CalculateValueByTwincatVariable(item.Name, twincatValue);
 
-                                 if (result.Item1)
 
-                                 {
 
-                                     aiAccessor.Value = result.Item2;
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     aiAccessor.Value = twincatValue;
 
-                                 }
 
-                                 IOModuleManager.Instance.UpdateIoValue(item.Name, aiAccessor.Value);
 
-                             }
 
-                             break;
 
-                         case "ao":
 
-                             BeckhoffAOAccessor aoAccessor = BeckhoffIOManager.Instance.GetAOAccesssor(item.Name);
 
-                             if (aoAccessor != null)
 
-                             {
 
-                                 double twincatValue = GetAnalogValue(item.DataType);
 
-                                 var result = ScalingManager.Instance.CalculateValueByTwincatVariable(item.Name, twincatValue);
 
-                                 if (result.Item1)
 
-                                 {
 
-                                     aoAccessor.Value = result.Item2;
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     aoAccessor.Value = twincatValue;
 
-                                 }
 
-                                 IOModuleManager.Instance.UpdateIoValue(item.Name, aoAccessor.Value);
 
-                             }
 
-                             break;
 
-                         case "axis":
 
-                             object itemValue = GetDataTypeValue(item.DataType);
 
-                             if (item.Invert)
 
-                             {
 
-                                 bool boolValue = (bool)itemValue;
 
-                                 IOModuleManager.Instance.UpdateIoValue(item.Name, !boolValue);
 
-                             }
 
-                             else
 
-                             {
 
-                                 IOModuleManager.Instance.UpdateIoValue(item.Name, itemValue);
 
-                             }
 
-                             break;
 
-                         case "counter":
 
-                             if (item.Invert)
 
-                             {
 
-                                 object counterItemValue = GetDataTypeValue(item.DataType);
 
-                                 bool boolValue = (bool)counterItemValue;
 
-                                 BeckhoffCounterManager.Instance.SetCounterValue(item.Name, !boolValue);
 
-                             }
 
-                             else
 
-                             {                                
 
-                                 object counterItemValue = GetDataTypeValue(item.DataType);
 
-                                 BeckhoffCounterManager.Instance.SetCounterValue(item.Name, counterItemValue);
 
-                             }
 
-                             break;
 
-                     }
 
-                 }
 
-             }
 
-             catch(Exception ex)
 
-             {
 
-                 LOG.WriteLog(eEvent.ERR_TWINCAT, "System", ex.Message);
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 获取模拟数量数值 
 
-         /// </summary>
 
-         /// <param name="dataType"></param>
 
-         /// <returns></returns>
 
-         private double GetAnalogValue(string dataType)
 
-         {
 
-             return double.Parse(GetDataTypeValue(dataType).ToString());
 
-         }
 
-         /// <summary>
 
-         /// 获取数据类型数值
 
-         /// </summary>
 
-         /// <param name="dataType"></param>
 
-         /// <returns></returns>
 
-         private object GetDataTypeValue(string dataType)
 
-         {
 
-             switch (dataType)
 
-             {
 
-                 case "byte":
 
-                     return _reader.ReadByte();
 
-                 case "sint":
 
-                     return _reader.ReadSByte();
 
-                 case "usint":
 
-                     return _reader.ReadByte();
 
-                 case "short":
 
-                     return _reader.ReadInt16();
 
-                 case "int":
 
-                     return _reader.ReadInt16();
 
-                 case "uint":
 
-                     return _reader.ReadUInt16();
 
-                 case "dint":
 
-                     return _reader.ReadInt32();
 
-                 case "udint":
 
-                     return _reader.ReadUInt32();
 
-                 case "long":
 
-                     return _reader.ReadInt64();
 
-                 case "float":
 
-                     return _reader.ReadSingle();
 
-                 case "ulong":
 
-                     return _reader.ReadUInt64();
 
-                 case "double":
 
-                     return _reader.ReadDouble();
 
-                 case "bool":
 
-                     return _reader.ReadBoolean();
 
-                 default:
 
-                     return _reader.ReadDouble();
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 停止
 
-         /// </summary>
 
-         public void Stop()
 
-         {
 
-             _adsClient.Dispose();
 
-         }
 
-         #region 支持写入结构体
 
-         /* T必须字段必须为连续地址,
 
-          *  [StructLayout(LayoutKind.Sequential)]
 
-             public class Tag
 
-             {
 
-                 [MarshalAs(UnmanagedType.I1)]
 
-                 public bool DO_PVN21; 
 
-                 [MarshalAs(UnmanagedType.I1)]
 
-                 public bool DO_PV11;
 
-                 [MarshalAs(UnmanagedType.R4)]
 
-                 public float AI_Chamber_Pressure_10t;
 
-             }
 
-          * */
 
-         /// <summary>
 
-         /// 写入类
 
-         /// </summary>
 
-         /// <typeparam name="T"></typeparam>
 
-         /// <param name="name"></param>
 
-         /// <param name="data"></param>
 
-         /// <returns></returns>
 
-         public (bool success, int status) WriteStruct<T>(string name, T data)
 
-         {
 
-             if (_writeNameHandleDic.ContainsKey(name))
 
-             {
 
-                 if (!_isConnected)
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat connected failed, write variable {name} error");
 
-                     return (false, 0);
 
-                 }
 
-                 try
 
-                 {
 
-                     int handle = _writeNameHandleDic[name];
 
-                     _adsClient.WriteAny(handle, data);
 
-                     LOG.WriteLog(eEvent.INFO_TWINCAT, "System", $"Twincat write variable {name} value {data}");
 
-                     return (true, 0);
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat write variable {name} error {ex.Message}");
 
-                     return (false, 1);
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 LOG.WriteLog(eEvent.ERR_TWINCAT, "System", $"Twincat doesnot has {name} variable");
 
-                 return (false, 0);
 
-             }
 
-         }
 
-         #endregion
 
-     }
 
- }
 
 
  |