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;
}
}
}