Files
2025-08-26 08:37:44 +08:00

636 lines
26 KiB
C#

using System;
using .Base;
using System.Collections.Generic;
using MES.Utility.Core;
using System.Text;
using System.Linq;
using TwinCAT.Ads.TypeSystem;
using TwinCAT.Ads;
namespace .ViewModel._01PLC通信调试
{
public class ADS调试ViewModel : ViewModelBase
{
public bool Enabled1 { get; set; } = true;
public bool Enabled2 { get; set; } = false;
public string NetId { get; set; } = "192.168.1.10.1.1";
public int Port { get; set; } = 851;
public string VarName { get; set; } = "Global_LaserCutting.gHmiPlc.Output.Mes.DeviceStatus.bEMG";
public int StringLength { get; set; } = 80;
public string DataType { get; set; } = "";
public string ReadedValue { get; set; } = "";
public string Message1 { get; set; } = "";
public string Message2 { get; set; } = "";
public string BoolValue { get; set; } = "";
private AdsServer ads;
public DelegateCommand ConnectCmd { get; set; }
public DelegateCommand DisconnectCmd { get; set; }
public DelegateCommand WriteCmd { get; set; }
public DelegateCommand ReadCmd { get; set; }
public ADS调试ViewModel()
{
ConnectCmd = new DelegateCommand(ConnectCmdFunc);
DisconnectCmd = new DelegateCommand(DisconnectCmdFunc);
ReadCmd = new DelegateCommand(ReadCmdFunc);
WriteCmd = new DelegateCommand(WriteCmdFunc);
}
private void ConnectCmdFunc(object obj)
{
try
{
ads = new AdsServer(NetId, Port);
ads.Connect();
Enabled1 = false;
Enabled2 = true;
}
catch
{
GlobalValues.Error("连接失败");
return;
}
}
private void DisconnectCmdFunc(object obj)
{
ads.Disconnect();
ads = null;
Enabled1 = true;
Enabled2 = false;
}
private void ReadCmdFunc(object obj)
{
string cmd = obj.ToString();
ReadedValue = "";
Message1 = "";
DataType = "";
try
{
object value = ads.Read(VarName, out string type);
Message1 = "读取成功";
DataType = type;
if (value.GetType().IsArray)
{
Array array = value as Array;
List<string> list = new List<string>();
for (int i = 0; i < array.Length; i++)
{
list.Add(array.GetValue(i).ToString());
}
ReadedValue = list.GetStrArray(" ");
}
else
{
ReadedValue = value.ToString();
}
}
catch (Exception ex)
{
Message1 = $"读取失败:{ex.Message}";
return;
}
}
private void WriteCmdFunc(object obj)
{
string cmd = obj.ToString();
try
{
if (string.IsNullOrEmpty(BoolValue))
{
Message2 = "请输入数据";
return;
}
ads.Write(VarName, BoolValue);
Message2 = $"写入成功";
}
catch (Exception ex)
{
Message2 = $"写入失败:{ex.Message}";
}
}
}
public class AdsServer
{
Dictionary<string, IAdsSymbol> symbolDict = new Dictionary<string, IAdsSymbol>();
public delegate void TcAdsStateChangedEventHandler(AdsState state);
public delegate void TcAdsRouteChangedEventHandler(AmsRouterState state);
public AmsRouterState AsmRouteState { get; set; } = AmsRouterState.Stop;
public AdsState AdsState { get; set; } = AdsState.Stop;
public AdsClient ads;
public bool SystemIsRunning => ads.IsConnected;
private TcAdsRouteChangedEventHandler tcAdsSystemStateChangedHandler;
public event TcAdsRouteChangedEventHandler TcSystemStateChanged
{
add
{
this.tcAdsSystemStateChangedHandler = (TcAdsRouteChangedEventHandler)Delegate.Combine(this.tcAdsSystemStateChangedHandler, value);
value(AsmRouteState);
}
remove
{
this.tcAdsSystemStateChangedHandler = (TcAdsRouteChangedEventHandler)Delegate.Remove(this.tcAdsSystemStateChangedHandler, value);
}
}
private TcAdsStateChangedEventHandler tcAdsClientStateChangedHandler;
public event TcAdsStateChangedEventHandler TcPlcStateChanged
{
add
{
this.tcAdsClientStateChangedHandler = (TcAdsStateChangedEventHandler)Delegate.Combine(this.tcAdsClientStateChangedHandler, value);
value(AdsState);
}
remove
{
this.tcAdsClientStateChangedHandler = (TcAdsStateChangedEventHandler)Delegate.Remove(this.tcAdsClientStateChangedHandler, value);
}
}
private int _clientPortNr = 801;
private string _netId = "";
public AdsServer(string netId, int portNr)
{
this._netId = netId;
this._clientPortNr = portNr;
ads = new AdsClient();
ads.RouterStateChanged += Client_AmsRouterNotification;
ads.AdsStateChanged += Client_AdsStateChanged;
}
private void Client_AmsRouterNotification(object sender, AmsRouterNotificationEventArgs e)
{
AsmRouteState = e.State;
tcAdsSystemStateChangedHandler?.Invoke(AsmRouteState);
}
public void Connect()
{
ads.Connect(this._netId, this._clientPortNr);
}
public void Disconnect()
{
ads.Disconnect();
ads.Dispose();
}
private void Client_AdsStateChanged(object sender, AdsStateChangedEventArgs e)
{
AdsState = e.State.AdsState;
tcAdsClientStateChangedHandler?.Invoke(AdsState);
}
public object Read(string symbolPath, out string oDataType)
{
if (!SystemIsRunning)
{
throw new Exception("PLC链接失败");
}
//bool isArray = symbolPath.Contains("[") && symbolPath.Contains("]");
//int index1 = symbolPath.IndexOf("["); int index2 = symbolPath.IndexOf("]");
//uint index = uint.Parse(symbolPath.Substring(index1 + 1, index2 - index1 - 1));
//symbolPath = symbolPath.Substring(0, index1);
IAdsSymbol symbol = null;
if (symbolDict.ContainsKey(symbolPath))
{
symbol = symbolDict[symbolPath];
}
else
{
symbol = ads.ReadSymbol(symbolPath);
if (symbol == null)
throw new Exception("找不到该变量");
symbolDict.Add(symbolPath, symbol);
}
oDataType = symbol.TypeName;
if (symbol.TypeName.Substring(0, 3) != "ARR")
{
AdsDataTypeId datatype = symbol.DataTypeId;
//BOOL
if (datatype == AdsDataTypeId.ADST_BIT)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(bool));
//byte
if (datatype == AdsDataTypeId.ADST_UINT8)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(byte));
//sbyte
if (datatype == AdsDataTypeId.ADST_INT8)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(sbyte));
//ushort
if (datatype == AdsDataTypeId.ADST_UINT16)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(ushort));
//short
if (datatype == AdsDataTypeId.ADST_INT16)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(short));
if (datatype == AdsDataTypeId.ADST_UINT32)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(uint));
if (datatype == AdsDataTypeId.ADST_INT32)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(int));
if (datatype == AdsDataTypeId.ADST_REAL32)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(float));
if (datatype == AdsDataTypeId.ADST_REAL64)
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(double));
if (datatype == AdsDataTypeId.ADST_STRING)
return ads.ReadAnyString((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, symbol.Size, Encoding.Default);
if (datatype == AdsDataTypeId.ADST_WSTRING)
{
Memory<byte> stream = new Memory<byte>(new byte[symbol.Size]);
int readLength = ads.Read((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, stream);
byte[] bytes = stream.ToArray().ToList().Take(readLength).ToArray();
int charCount = readLength / 2;
char[] charArray = new char[charCount];
for (int i = 0; i < charCount; i++)
{
char value = (char)(bytes[i * 2 + 1] << 8 | bytes[i * 2]);
charArray[i] = value;
if (value == 0)
break;
}
return new String(charArray).Trim('\0');
}
if (datatype == AdsDataTypeId.ADST_BIGTYPE)
{
if (symbol.TypeName.StartsWith("TIME") || symbol.TypeName.StartsWith("DATE") || symbol.TypeName.StartsWith("TOD"))
{
return ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, typeof(DateTime));
}
}
}
else
{
AdsDataTypeId datatype = symbol.DataTypeId;
if (datatype == AdsDataTypeId.ADST_BIT)
{
//if (isArray)
//{
// return (bool)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + index, typeof(bool));
//}
bool[] values = new bool[symbol.Size];
for (uint i = 0; i < symbol.Size; i++)
{
values[i] = (bool)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + i, typeof(bool));
}
return values;
}
//byte
if (datatype == AdsDataTypeId.ADST_UINT8)
{
//if (isArray)
//{
// return (byte)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + index, typeof(byte)); ;
//}
byte[] values = new byte[symbol.Size];
for (uint i = 0; i < symbol.Size; i++)
{
values[i] = (byte)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + i, typeof(byte));
}
return values;
}
//sbyte
if (datatype == AdsDataTypeId.ADST_INT8)
{
//if (isArray)
//{
// return (sbyte)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + index, typeof(sbyte));
//}
sbyte[] values = new sbyte[symbol.Size];
for (uint i = 0; i < symbol.Size; i++)
{
values[i] = (sbyte)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + i, typeof(sbyte));
}
return values;
}
//ushort
if (datatype == AdsDataTypeId.ADST_UINT16)
{
//if (isArray)
//{
// return (ushort)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 2U), typeof(ushort));
//}
int count = symbol.Size / 2;
ushort[] values = new ushort[count];
for (uint i = 0; i < count; i++)
{
values[i] = (ushort)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 2U), typeof(ushort));
}
return values;
}
//short
if (datatype == AdsDataTypeId.ADST_INT16)
{
//if (isArray)
//{
// return (short)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 2U), typeof(short));
//}
int count = symbol.Size / 2;
short[] values = new short[count];
for (uint i = 0; i < count; i++)
{
values[i] = (short)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 2U), typeof(short));
}
return values;
}
if (datatype == AdsDataTypeId.ADST_UINT32)
{
//if (isArray)
//{
// return (uint)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 4U), typeof(uint));
//}
int count = symbol.Size / 4;
uint[] values = new uint[count];
for (uint i = 0; i < count; i++)
{
values[i] = (uint)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 4U), typeof(uint));
}
return values;
}
if (datatype == AdsDataTypeId.ADST_INT32)
{
//if (isArray)
//{
// return (int)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 4U), typeof(int));
//}
int count = symbol.Size / 4;
int[] values = new int[count];
for (uint i = 0; i < count; i++)
{
values[i] = (int)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 4U), typeof(int));
}
return values;
}
if (datatype == AdsDataTypeId.ADST_REAL32)
{
//if (isArray)
//{
// return (float)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 4U), typeof(float));
//}
int count = symbol.Size / 4;
float[] values = new float[count];
for (uint i = 0; i < count; i++)
{
values[i] = (float)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 4U), typeof(float));
}
return values;
}
if (datatype == AdsDataTypeId.ADST_REAL64)
{
//if (isArray)
//{
// return (double)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 8U), typeof(double));
//}
int count = symbol.Size / 8;
double[] values = new double[count];
for (uint i = 0; i < count; i++)
{
values[i] = (double)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 8U), typeof(double));
}
return values;
}
//TC3 字符串数组为 ADST_STRING
if (datatype == AdsDataTypeId.ADST_STRING)
{
int every = 81;
if (symbol.TypeName.Contains("OF STRING"))
{
int index = symbol.TypeName.IndexOf("OF STRING(");
if (index != 1)
{
int index2 = symbol.TypeName.LastIndexOf(")");
every = Convert.ToInt32(symbol.TypeName.Substring(index + 10, index2 - index - 10)) + 1;
}
int count = symbol.Size / every;
string[] values = new string[count];
for (uint i = 0; i < count; i++)
{
values[i] = ads.ReadAnyString((uint)symbol.IndexGroup, (uint)(symbol.IndexOffset + (i * every)), every, Encoding.Default);
}
return values;
}
}
if (datatype == AdsDataTypeId.ADST_WSTRING)
{
int every = 512;
if (symbol.TypeName.Contains("OF WSTRING"))
{
int index = symbol.TypeName.IndexOf("OF WSTRING(");
if (index != 1)
{
int index2 = symbol.TypeName.LastIndexOf(")");
every = (Convert.ToInt32(symbol.TypeName.Substring(index + 11, index2 - index - 11)) + 1) * 2;
}
int count = symbol.Size / every;
string[] values = new string[count];
for (uint i = 0; i < count; i++)
{
Memory<byte> stream = new Memory<byte>(new byte[every]);
int readLength = ads.Read((uint)symbol.IndexGroup, (uint)(symbol.IndexOffset + (i * every)), stream);
byte[] bytes = stream.ToArray().ToList().Take(readLength).ToArray();
int charCount = readLength / 2;
char[] charArray = new char[charCount];
for (int j = 0; j < charCount; j++)
{
char value = (char)(bytes[j * 2 + 1] << 8 | bytes[j * 2]);
charArray[j] = value;
if (value == 0)
break;
}
values[i] = new String(charArray).Trim('\0');
}
return values;
}
}
if (datatype == AdsDataTypeId.ADST_BIGTYPE)
{
//TC2 字符串为ADST_BIGTYPE
if (symbol.TypeName.Contains("OF STRING"))
{
//if (isArray)
//{
// return ads.ReadAnyString((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 81U), 81, Encoding.Default);
//}
int count = symbol.Size / 81;
string[] values = new string[count];
for (uint i = 0; i < count; i++)
{
values[i] = ads.ReadAnyString((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 81U), 81, Encoding.Default);
}
return values;
}
if (symbol.TypeName.Contains("OF TIME") || symbol.TypeName.Contains("OF DATE"))
{
//if (isArray)
//{
// return (DateTime)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 4), typeof(DateTime));
//}
int count = symbol.Size / 4;
DateTime[] values = new DateTime[count];
for (uint i = 0; i < count; i++)
{
values[i] = (DateTime)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 4), typeof(DateTime));
}
return values;
}
if (symbol.TypeName.Contains("OF TOD"))
{
//if (isArray)
//{
// return (DateTime)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (index * 4), typeof(DateTime));
//}
int count = symbol.Size / 4;
DateTime[] values = new DateTime[count];
for (uint i = 0; i < count; i++)
{
values[i] = (DateTime)ads.ReadAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset + (i * 4), typeof(DateTime));
}
return values;
}
}
}
throw new Exception("不支持的数据类型");
}
public void Write(string symbolPath, string value)
{
if (!SystemIsRunning)
{
throw new Exception("PLC链接失败");
}
IAdsSymbol symbol = null;
if (symbolDict.ContainsKey(symbolPath))
{
symbol = symbolDict[symbolPath];
}
else
{
symbol = ads.ReadSymbol(symbolPath);
if (symbol == null)
throw new Exception("找不到该变量");
symbolDict.Add(symbolPath, symbol);
}
if (symbol.TypeName.Substring(0, 3) != "ARR")
{
AdsDataTypeId datatype = symbol.DataTypeId;
//BOOL
if (datatype == AdsDataTypeId.ADST_BIT)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, bool.Parse(value));
return;
}
//byte
if (datatype == AdsDataTypeId.ADST_UINT8)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, byte.Parse(value));
return;
}
//sbyte
if (datatype == AdsDataTypeId.ADST_INT8)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, sbyte.Parse(value));
return;
}
//ushort
if (datatype == AdsDataTypeId.ADST_UINT16)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, ushort.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_INT16)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, short.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_UINT32)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, uint.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_INT32)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, int.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_REAL32)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, float.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_REAL64)
{
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, double.Parse(value));
return;
}
if (datatype == AdsDataTypeId.ADST_STRING)
{
ads.WriteAnyString(symbolPath, value, symbol.Size,Encoding.Default);
//ads.WriteAnyString((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, value, symbol.Size, Encoding.Default);
return;
}
if (datatype == AdsDataTypeId.ADST_WSTRING)
{
char[] charArray = value.ToCharArray();
byte[] bytes = new byte[charArray.Length * 2];
for (int i = 0; i < charArray.Length; i++)
{
bytes[i * 2] = (byte)(charArray[i] & 0xFF);
bytes[i * 2 + 1] = (byte)(charArray[i] >> 8 & 0xFF);
}
if (bytes.Length > symbol.Size)
{
ads.Write((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, new ReadOnlyMemory<byte>(bytes));
}
else
{
byte[] newBytes = new byte[symbol.Size];
for (int i = 0; i < bytes.Length; i++)
{
newBytes[i] = bytes[i];
}
ads.Write((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, new ReadOnlyMemory<byte>(newBytes));
}
return;
}
if (datatype == AdsDataTypeId.ADST_BIGTYPE)
{
if (symbol.TypeName.StartsWith("TIME") || symbol.TypeName.StartsWith("DATE") || symbol.TypeName.StartsWith("TOD"))
{
bool flag = DateTime.TryParse(value, out DateTime result);
if (!flag)
throw new Exception("格式转换失败");
ads.WriteAny((uint)symbol.IndexGroup, (uint)symbol.IndexOffset, result);
return;
}
}
throw new Exception("不支持的数据类型");
}
else
{
throw new Exception("不支持数组批量写入");
}
}
}
}