TwinCatAds.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using ProjectBase.Data.Redis;
  2. using SIASUN.Autopilot.Device.EventMessage;
  3. using SIASUN.Autopilot.Model;
  4. using System;
  5. using TwinCAT.Ads;
  6. namespace SIASUN.Autopilot.Device.BeckHoff
  7. {
  8. /// <summary>
  9. /// 类型限定为 string、boolen、int、double、结构体
  10. /// </summary>
  11. /// <typeparam name="T"></typeparam>
  12. public class TwinCatAds<T> : AbsTwinCatOpc
  13. {
  14. #region 变量
  15. private int iHandle;
  16. private int notificationHandle;
  17. private TcAdsClient adsClient =null;
  18. private T strValue;
  19. private MoBeckhoffNode moBFNodeInfo = null;
  20. private object objUserData { get; set; }
  21. #endregion
  22. private RedisHelper redis =null;
  23. public TwinCatAds(MoBeckhoffNode mNodeInfo):base()
  24. {
  25. try
  26. {
  27. moBFNodeInfo = mNodeInfo;
  28. objUserData = mNodeInfo.NodeName;
  29. this.adsClient = base.GetAds();
  30. ConnectOpc();
  31. }
  32. catch (Exception ex)
  33. {
  34. throw new Exception(ex.Message);
  35. }
  36. }
  37. #region 方法
  38. public bool ConnectOpc()
  39. {
  40. if (redis == null)
  41. redis = new RedisHelper();
  42. if (!adsClient.IsConnected)
  43. {
  44. adsClient.Connect(moBFNodeInfo.IP, moBFNodeInfo.Port);
  45. }
  46. adsClient.AdsNotificationEx += new AdsNotificationExEventHandler(adsClient_AdsNotificationEx);
  47. iHandle = adsClient.CreateVariableHandle(moBFNodeInfo.NodeName);
  48. if (moBFNodeInfo.ReceiveType != 1)
  49. {
  50. notificationHandle = adsClient.AddDeviceNotificationEx(moBFNodeInfo.NodeName, AdsTransMode.OnChange, 10, 0, objUserData, typeof(T));
  51. }
  52. return true;
  53. }
  54. public override bool DisConnectOpc()
  55. {
  56. try
  57. {
  58. DeleteNotification();
  59. adsClient.Dispose();
  60. iHandle = 0;
  61. }
  62. catch (Exception ex)
  63. {
  64. throw new Exception(ex.Message);
  65. }
  66. return true;
  67. }
  68. public override bool IsConnectOpc()
  69. {
  70. return adsClient.IsConnected;
  71. }
  72. public override bool CreateNotification()
  73. {
  74. try
  75. {
  76. notificationHandle = adsClient.AddDeviceNotificationEx(moBFNodeInfo.NodeName, AdsTransMode.OnChange, 10, 0, objUserData, typeof(T));
  77. }
  78. catch (Exception ex)
  79. {
  80. throw new Exception(ex.Message);
  81. }
  82. return true;
  83. }
  84. public override bool DeleteNotification()
  85. {
  86. try
  87. {
  88. if (notificationHandle != 0)
  89. {
  90. adsClient.DeleteDeviceNotification(notificationHandle);
  91. notificationHandle = 0;
  92. }
  93. }
  94. catch (Exception ex)
  95. {
  96. throw new Exception(ex.Message);
  97. }
  98. return true;
  99. }
  100. private void adsClient_AdsNotificationEx(object sender, AdsNotificationExEventArgs e)
  101. {
  102. if (!e.NotificationHandle.Equals(notificationHandle))
  103. return;
  104. strValue = (T)e.Value;
  105. redis.SetHash<T>("plc_node", e.UserData.ToString(), strValue);
  106. EventMessages.GetSingleton().Publish(e.UserData.ToString(), typeof(T).ToString(), e.Value.ToString());
  107. }
  108. public override void Set(object nodevalue, String datatype)
  109. {
  110. switch (datatype)
  111. {
  112. case "double":
  113. adsClient.WriteAny(iHandle, Convert.ToDouble(nodevalue));
  114. break;
  115. case "int":
  116. adsClient.WriteAny(iHandle, Convert.ToInt16(nodevalue));
  117. break;
  118. case "uint":
  119. adsClient.WriteAny(iHandle, Convert.ToUInt16(nodevalue));
  120. break;
  121. case "dint":
  122. adsClient.WriteAny(iHandle, Convert.ToInt32(nodevalue));
  123. break;
  124. case "word":
  125. adsClient.WriteAny(iHandle, Convert.ToInt16(nodevalue));
  126. break;
  127. case "bool":
  128. adsClient.WriteAny(iHandle, Convert.ToBoolean(nodevalue));
  129. break;
  130. case "byte":
  131. adsClient.WriteAny(iHandle, Convert.ToByte(nodevalue));
  132. break;
  133. case "real":
  134. adsClient.WriteAny(iHandle, Convert.ToSingle(nodevalue));
  135. break;
  136. default:
  137. throw new IndexOutOfRangeException($"TwinCatAds get {objUserData} error, value = { Convert.ToSingle(nodevalue)}, no match type.");
  138. //break;
  139. };
  140. }
  141. public override object Get(out Type _type)
  142. {
  143. strValue = (T)adsClient.ReadAny(iHandle, typeof(T));
  144. _type = typeof(T);
  145. redis.SetHash<T>("plc_node", objUserData.ToString(), strValue);
  146. return strValue;
  147. }
  148. #endregion
  149. }
  150. }