using ProjectBase.Data.Redis; using SIASUN.Autopilot.Device.EventMessage; using SIASUN.Autopilot.Model; using System; using TwinCAT.Ads; namespace SIASUN.Autopilot.Device.BeckHoff { /// /// 类型限定为 string、boolen、int、double、结构体 /// /// public class TwinCatAds : AbsTwinCatOpc { #region 变量 private int iHandle; private int notificationHandle; private TcAdsClient adsClient =null; private T strValue; private MoBeckhoffNode moBFNodeInfo = null; private object objUserData { get; set; } #endregion private RedisHelper redis =null; public TwinCatAds(MoBeckhoffNode mNodeInfo):base() { try { moBFNodeInfo = mNodeInfo; objUserData = mNodeInfo.NodeName; this.adsClient = base.GetAds(); ConnectOpc(); } catch (Exception ex) { throw new Exception(ex.Message); } } #region 方法 public bool ConnectOpc() { if (redis == null) redis = new RedisHelper(); if (!adsClient.IsConnected) { adsClient.Connect(moBFNodeInfo.IP, moBFNodeInfo.Port); } adsClient.AdsNotificationEx += new AdsNotificationExEventHandler(adsClient_AdsNotificationEx); iHandle = adsClient.CreateVariableHandle(moBFNodeInfo.NodeName); if (moBFNodeInfo.ReceiveType != 1) { notificationHandle = adsClient.AddDeviceNotificationEx(moBFNodeInfo.NodeName, AdsTransMode.OnChange, 10, 0, objUserData, typeof(T)); } return true; } public override bool DisConnectOpc() { try { DeleteNotification(); adsClient.Dispose(); iHandle = 0; } catch (Exception ex) { throw new Exception(ex.Message); } return true; } public override bool IsConnectOpc() { return adsClient.IsConnected; } public override bool CreateNotification() { try { notificationHandle = adsClient.AddDeviceNotificationEx(moBFNodeInfo.NodeName, AdsTransMode.OnChange, 10, 0, objUserData, typeof(T)); } catch (Exception ex) { throw new Exception(ex.Message); } return true; } public override bool DeleteNotification() { try { if (notificationHandle != 0) { adsClient.DeleteDeviceNotification(notificationHandle); notificationHandle = 0; } } catch (Exception ex) { throw new Exception(ex.Message); } return true; } private void adsClient_AdsNotificationEx(object sender, AdsNotificationExEventArgs e) { if (!e.NotificationHandle.Equals(notificationHandle)) return; strValue = (T)e.Value; redis.SetHash("plc_node", e.UserData.ToString(), strValue); EventMessages.GetSingleton().Publish(e.UserData.ToString(), typeof(T).ToString(), e.Value.ToString()); } public override void Set(object nodevalue, String datatype) { switch (datatype) { case "double": adsClient.WriteAny(iHandle, Convert.ToDouble(nodevalue)); break; case "int": adsClient.WriteAny(iHandle, Convert.ToInt16(nodevalue)); break; case "uint": adsClient.WriteAny(iHandle, Convert.ToUInt16(nodevalue)); break; case "dint": adsClient.WriteAny(iHandle, Convert.ToInt32(nodevalue)); break; case "word": adsClient.WriteAny(iHandle, Convert.ToInt16(nodevalue)); break; case "bool": adsClient.WriteAny(iHandle, Convert.ToBoolean(nodevalue)); break; case "byte": adsClient.WriteAny(iHandle, Convert.ToByte(nodevalue)); break; case "real": adsClient.WriteAny(iHandle, Convert.ToSingle(nodevalue)); break; default: throw new IndexOutOfRangeException($"TwinCatAds get {objUserData} error, value = { Convert.ToSingle(nodevalue)}, no match type."); //break; }; } public override object Get(out Type _type) { strValue = (T)adsClient.ReadAny(iHandle, typeof(T)); _type = typeof(T); redis.SetHash("plc_node", objUserData.ToString(), strValue); return strValue; } #endregion } }