using Microsoft.AspNetCore.SignalR.Protocol; using MQTTnet.AspNetCore.Client.Tcp; using Newtonsoft.Json; using NPOI.SS.Formula.Functions; using System; using System.Net.Sockets; using System.Reflection; using System.Text; using TwinCAT.Ads; namespace AmrControl.ADS { public class TcClient { protected static TcClient Instance = null; /// /// ADS 通信模块 /// AdsClient tcAdsClient; List tcConfigs = new List(); string netId = "169.254.88.162.1.1"; int port = 851; private readonly static object balanceLock = new object(); public bool State = false; public static TcClient GetInstance() { lock(balanceLock) { if (Instance == null) Instance = new TcClient(); } return Instance; } private TcClient() { LoadConfig(); netId = AppHelper.ReadAppSettings("Ads", "netID"); string strPort = AppHelper.ReadAppSettings("Ads", "port"); port = int.Parse(strPort); InitAds(); } /// /// 初始化ADS /// /// internal bool InitAds() { State = false; try { if (tcAdsClient != null) { tcAdsClient.Disconnect(); tcAdsClient.Dispose(); } } catch (Exception e) { throw new Exception("Initads 中发生异常,尝试关闭ads连接的时候发生:" + e.Message); } try { tcAdsClient = new AdsClient(); tcAdsClient.Connect(netId, port); if (tcAdsClient.IsConnected == false) { throw new Exception("Initads 中IsConnected == false"); return false; } StateInfo state = tcAdsClient.ReadState(); if (state.AdsState == AdsState.Run) { State = true; return true; } else { throw new Exception("Initads中,AdsState != AdsState.Run ,AdsState = " + state.AdsState.ToString()); return false; } } catch(Exception ex) { throw new Exception("Initads 中发生异常,创建新的ads连接的时候发生:" + ex.Message); return false; } } internal void Close() { try { State = false; if (tcAdsClient != null) { tcAdsClient.Disconnect(); tcAdsClient.Dispose(); tcAdsClient = null; } } catch (Exception e) { //throw new Exception("Initads 中发生异常,尝试关闭ads连接的时候发生:" + e.Message); } } /// /// 从配置文件加载硬件的参数配置 /// void LoadConfig() { string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ads.json"); if (File.Exists(path) == false) throw new Exception("未找到配置文件ads.json"); try { FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); byte[] data = new byte[fs.Length]; fs.Read(data, 0, data.Length); fs.Close(); string strConfig = Encoding.UTF8.GetString(data); List ls = JsonConvert.DeserializeObject>(strConfig); tcConfigs.Clear(); tcConfigs.AddRange(ls); } catch(Exception ee) { Console.WriteLine(ee.Message); } } public bool WriteValue(string name , T Data) { uint hvar = 0; bool ok = true; if (tcAdsClient == null || string.IsNullOrEmpty(name)) { return false; } //从配置中找到当前参数的定义 TcValue item = tcConfigs.FirstOrDefault(val => val.name.Equals(name)); if (item == null) { throw new Exception($"配置文件ads.json中未找到参数:{name}"); //return false; } try { hvar = tcAdsClient.CreateVariableHandle(name); } catch (Exception err) { throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message); } try { switch(typeof(T).Name) { case "Boolean": AdsStream datastream = new AdsStream(1); //bool值位为1 BinaryWriter binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((bool)(object)Data); ReadOnlyMemory buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Byte": datastream = new AdsStream(1); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((byte)(object)Data); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Int32": datastream = new AdsStream(4); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((int)(object)Data); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Single": datastream = new AdsStream(4); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((float)(object)Data); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Double": datastream = new AdsStream(8); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((double)(object)Data); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Int16": datastream = new AdsStream(2); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write((short)(object)Data); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "Byte[]": byte[] data = (byte[])(object)Data; int len = 0; //写入不超过定义的长度 if (data.Length <= item.length) { len = data.Length; } else { len = item.length; data[len - 1] = 0; } datastream = new AdsStream(len); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write(data,0,len); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; case "String": string str = (string)(object)Data; byte[] bufs = Encoding.ASCII.GetBytes(str); //加一个 '\0'结尾 data = new byte[bufs.Length + 1]; Array.Copy(bufs,data,bufs.Length); data[data.Length - 1] = 0; // '\0' len = 0; //写入不超过定义的长度 if (data.Length <= item.length) { len = data.Length; } else { len = item.length; data[len - 1] = 0; } datastream = new AdsStream(len); binwrite = new BinaryWriter(datastream); datastream.Position = 0; binwrite.Write(data, 0, len); buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); break; default: break; } } catch (Exception err) { throw new Exception("Write的时候发生异常:" + err.Message); ok = false; } try { tcAdsClient.DeleteVariableHandle(hvar); } catch (Exception err) { throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message); } return ok; } public T ReadValue(string name) { uint hvar = 0; bool ok = true; T t = default(T); if (tcAdsClient == null) { throw new Exception("ADS未初始化!"); } if (string.IsNullOrEmpty(name)) { throw new Exception("参数名称name = null"); } //从配置中找到当前参数的定义 TcValue item = tcConfigs.FirstOrDefault(val => val.name.Equals(name)); if (item == null) { throw new Exception($"配置文件ads.json中未找到参数:{name}"); //return false; } try { hvar = tcAdsClient.CreateVariableHandle(name); } catch (Exception err) { throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message); //return false; } try { switch (typeof(T).Name) { case "Boolean": byte[] buffer = new byte[1]; Memory buf = new Memory(buffer); int len = tcAdsClient.Read(hvar, buf); if(len > 0) { bool val = buf.GetArray()[0] > 0; t = (T)Convert.ChangeType(val, typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Byte": buffer = new byte[1]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { t = (T)Convert.ChangeType(buf.GetArray()[0], typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Int32": buffer = new byte[4]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { int val = BitConverter.ToInt32(buf.ToArray(), 0); t = (T)Convert.ChangeType(val, typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Single": buffer = new byte[4]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { float val = BitConverter.ToSingle(buf.ToArray(), 0); t = (T)Convert.ChangeType(val, typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Double": buffer = new byte[8]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { double val = BitConverter.ToDouble(buf.ToArray(), 0); t = (T)Convert.ChangeType(val, typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Int16": buffer = new byte[2]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { short val = BitConverter.ToInt16(buf.ToArray(), 0); t = (T)Convert.ChangeType(val, typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "Byte[]": buffer = new byte[item.length]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { t = (T)Convert.ChangeType(buf.ToArray(), typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; case "String": buffer = new byte[item.length]; buf = new Memory(buffer); len = tcAdsClient.Read(hvar, buf); if (len > 0) { t = (T)Convert.ChangeType(Encoding.ASCII.GetString(buf.ToArray()), typeof(T)); } else { throw new Exception("ADS没有读到值!"); } break; default: break; } } catch (Exception err) { throw new Exception("Read的时候发生异常:" + err.Message); ok = false; } try { tcAdsClient.DeleteVariableHandle(hvar); } catch (Exception err) { throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message); } return t; } public byte[] ReadBytes(string name,int length) { uint hvar = 0; bool ok = true; byte[] t = new byte[length]; if (tcAdsClient == null) { throw new Exception("ADS未初始化!"); } try { hvar = tcAdsClient.CreateVariableHandle(name); } catch (Exception err) { throw new Exception("CreateVariableHandle的时候发生异常:" + err.Message); //return false; } try { byte[] buffer = new byte[length]; Memory buf = new Memory(buffer); int len = tcAdsClient.Read(hvar, buf); if (len > 0) { Array.Copy(buf.ToArray(), t, len); buf = null; buffer = null; } else { throw new Exception("ADS没有读到值!"); } } catch (Exception err) { throw new Exception("Read的时候发生异常:" + err.Message); ok = false; } try { tcAdsClient.DeleteVariableHandle(hvar); } catch (Exception err) { throw new Exception("DeleteVariableHandle的时候发生异常:" + err.Message); } return t; } /// /// 不知道异步会不会有问题,看这个逻辑,ADS内部应该是会处理的 /// /// /// /// bool WriteBool(string name , bool Data) { if(tcAdsClient == null) { return false; } uint hvar = 0; bool ok = true; try { hvar = tcAdsClient.CreateVariableHandle(name); } catch (Exception err) { Console.WriteLine("WriteBool中发生异常,CreateVariableHandle的时候发生:" + err.Message); return false; } AdsStream datastream = new AdsStream(1); //bool值位为1 BinaryWriter binwrite = new BinaryWriter(datastream); datastream.Position = 0; try { binwrite.Write(Data); ReadOnlyMemory buffer = new ReadOnlyMemory(datastream.ToArray()); tcAdsClient.Write(hvar, buffer); } catch (Exception err) { Console.WriteLine("WriteBool中发生异常,Write的时候发生:" + err.Message); ok = false; } try { tcAdsClient.DeleteVariableHandle(hvar); } catch (Exception err) { Console.WriteLine("WriteBool中发生异常,DeleteVariableHandle的时候发生:" + err.Message); } return ok; } } }