2024-10-07 15:15:18 +08:00
|
|
|
|
using IoTClient;
|
|
|
|
|
|
using IoTClient.Clients.PLC;
|
|
|
|
|
|
using IoTClient.Common.Enums;
|
|
|
|
|
|
using IoTClient.Enums;
|
|
|
|
|
|
using Net462DllTest.Enums;
|
2024-10-20 12:10:57 +08:00
|
|
|
|
using Net462DllTest.Model;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
using Net462DllTest.Signal;
|
|
|
|
|
|
using Net462DllTest.Utils;
|
2024-10-20 12:10:57 +08:00
|
|
|
|
using Serein.Library;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
using Serein.Library.Utils;
|
|
|
|
|
|
using System;
|
2024-10-20 12:10:57 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Net462DllTest.Trigger
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[AutoRegister]
|
2024-12-23 23:19:10 +08:00
|
|
|
|
public class SiemensPlcDevice : TaskFlowTrigger<PlcVarName>
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
|
|
|
|
|
public SiemensClient Client { get; set; }
|
|
|
|
|
|
public SiemensVersion Version { get; set; }
|
|
|
|
|
|
public string IP { get; set; } = "127.0.0.1";
|
|
|
|
|
|
public int Port { get; set; } = 102;
|
|
|
|
|
|
public PlcState State { get; set; } = PlcState.PowerOff;
|
|
|
|
|
|
public bool IsTimedRefresh { get; set; } = false; // 是否定时刷新
|
|
|
|
|
|
public IGSModel<PlcVarName, PlcVarModel> Model { get; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private readonly object _lockObj = new object(); // 防止多次初始化读取任务
|
|
|
|
|
|
private readonly ConcurrentBag<Task> TimedRefreshTask = new ConcurrentBag<Task>(); // 定时读取任务
|
|
|
|
|
|
private readonly ConcurrentBag<PlcVarInfo> VarInfos = new ConcurrentBag<PlcVarInfo>(); // 所有变量信息
|
|
|
|
|
|
private readonly ConcurrentBag<PlcVarInfo> OnRefreshs = new ConcurrentBag<PlcVarInfo>(); // 数据变更后需要通知触发器的变量信息
|
|
|
|
|
|
private readonly ConcurrentBag<PlcVarInfo> OnChangeds = new ConcurrentBag<PlcVarInfo>(); // 读取读取后需要通知触发器的变量信息
|
|
|
|
|
|
|
|
|
|
|
|
public SiemensPlcDevice(PlcVarModel model)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Model = new GSModel<PlcVarName, PlcVarModel>(model);
|
|
|
|
|
|
LoadVarInfos();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载变量信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void LoadVarInfos()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var property in typeof(PlcVarModel).GetProperties())
|
|
|
|
|
|
{
|
|
|
|
|
|
var attribute = property.GetCustomAttribute<BindValueAttribute>();
|
|
|
|
|
|
if (attribute?.Value is PlcVarName varName)
|
|
|
|
|
|
{
|
|
|
|
|
|
var varInfo = varName.ToVarInfo();
|
|
|
|
|
|
VarInfos.Add(varInfo);
|
|
|
|
|
|
if (varInfo.IsTimingRead) // 是否定时刷新
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (varInfo.NotificationType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case PlcVarInfo.OnNotificationType.OnRefresh:
|
|
|
|
|
|
OnRefreshs.Add(varInfo); // 变量读取时通知触发器的变量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PlcVarInfo.OnNotificationType.OnChanged:
|
|
|
|
|
|
OnChangeds.Add(varInfo); // 变量变更时才需要通知触发器的变量
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Init(SiemensVersion version, string ip, int port)
|
|
|
|
|
|
{
|
|
|
|
|
|
Client = new SiemensClient(version, ip, port);
|
|
|
|
|
|
Version = version;
|
|
|
|
|
|
IP = ip;
|
|
|
|
|
|
Port = port;
|
|
|
|
|
|
Client.Open();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Close()
|
|
|
|
|
|
{
|
|
|
|
|
|
Client?.Close();
|
|
|
|
|
|
Client = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-08 11:25:51 +08:00
|
|
|
|
public void Write(PlcVarName varName, object value)
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
2024-10-08 11:25:51 +08:00
|
|
|
|
var varInfo = varName.ToVarInfo();
|
|
|
|
|
|
if (this.State == PlcState.Runing)
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
2024-10-08 11:25:51 +08:00
|
|
|
|
if (varInfo.IsReadOnly)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception($"PLC变量{varInfo}当前禁止写入");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Client.WriteVar(varInfo, value); // 尝试写入PLC
|
|
|
|
|
|
Model.Set(varName, value);
|
|
|
|
|
|
Console.WriteLine($"PLC变量{varInfo}写入数据:{value}");
|
|
|
|
|
|
}
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
2024-10-08 11:25:51 +08:00
|
|
|
|
else
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
2024-10-08 11:25:51 +08:00
|
|
|
|
throw new Exception($"PLC处于非预期状态{this.State}");
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-08 11:25:51 +08:00
|
|
|
|
public object Read(PlcVarName varName)
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
2024-10-08 11:25:51 +08:00
|
|
|
|
var varInfo = varName.ToVarInfo();
|
|
|
|
|
|
var result = Client.ReadVar(varInfo);// 尝试读取数据
|
|
|
|
|
|
Model.Set(varName, result); // 缓存读取的数据
|
|
|
|
|
|
return result;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void BatchRefresh()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach(var varInfo in VarInfos)
|
|
|
|
|
|
{
|
2024-10-08 11:25:51 +08:00
|
|
|
|
Read(varInfo.Name); // 无条件批量读取
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 开启定时批量读取任务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async Task OpenTimedRefreshAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TimedRefreshTask.IsEmpty)
|
|
|
|
|
|
{
|
|
|
|
|
|
InitTimedRefreshTask();
|
|
|
|
|
|
}
|
|
|
|
|
|
IsTimedRefresh = true;
|
|
|
|
|
|
await Task.WhenAll(TimedRefreshTask.ToArray());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关闭定时任务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void CloseTimedRefresh() => IsTimedRefresh = false;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 初始化定时刷新任务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void InitTimedRefreshTask()
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("开始初始化刷新任务");
|
|
|
|
|
|
lock (_lockObj)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var varInfo in OnChangeds)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"添加监视任务(OnChanged):{varInfo.Name}");
|
|
|
|
|
|
ScheduleTask(varInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (var varInfo in OnRefreshs)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"添加监视任务(OnRefresh):{varInfo.Name}");
|
|
|
|
|
|
ScheduleTask(varInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 定时读取PLC变量,并刷新Model的值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="varInfo"></param>
|
|
|
|
|
|
private void ScheduleTask(PlcVarInfo varInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
var task = Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var signal = varInfo.Name;
|
|
|
|
|
|
object oldData;
|
|
|
|
|
|
object newData;
|
|
|
|
|
|
bool isNotification;
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(varInfo.Interval);
|
|
|
|
|
|
if (!IsTimedRefresh || Client is null) break;
|
|
|
|
|
|
|
|
|
|
|
|
oldData = Model.Get(signal); // 暂存旧数据
|
2024-10-08 11:25:51 +08:00
|
|
|
|
newData = Read(signal); // 获取新数据
|
2024-10-07 15:15:18 +08:00
|
|
|
|
if (varInfo.NotificationType == PlcVarInfo.OnNotificationType.OnRefresh)
|
|
|
|
|
|
{
|
|
|
|
|
|
isNotification = true; // 无条件触发通知
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
isNotification = !oldData.Equals(newData); // 变更时才会触发通知
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isNotification)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"VarName: {signal}\t\tOld Data: {oldData}\tNew Data: {newData}");
|
2024-12-23 23:19:10 +08:00
|
|
|
|
await InvokeTriggerAsync(signal, newData);
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
TimedRefreshTask.Add(task);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"西门子Plc[{this.Version}-{this.IP}:{this.Port}]";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 拓展方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static class MyPlcExtension
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 缓存变量信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static readonly Dictionary<PlcVarName, PlcVarInfo> VarInfoDict = new Dictionary<PlcVarName, PlcVarInfo>();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取变量信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="plcVarEnum"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
|
public static PlcVarInfo ToVarInfo(this PlcVarName plcVarEnum)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (VarInfoDict.ContainsKey(plcVarEnum))
|
|
|
|
|
|
{
|
|
|
|
|
|
return VarInfoDict[plcVarEnum];
|
|
|
|
|
|
}
|
2024-12-23 23:19:10 +08:00
|
|
|
|
var plcValue = EnumHelper.GetAttributeValue<PlcVarName, PlcVarInfoAttribute, PlcVarInfo>(plcVarEnum, attr => attr.Info)
|
2024-10-07 15:15:18 +08:00
|
|
|
|
?? throw new Exception($"获取变量异常:{plcVarEnum},没有标记PlcValueAttribute");
|
|
|
|
|
|
if (string.IsNullOrEmpty(plcValue.Address))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception($"获取变量异常:{plcVarEnum},变量地址为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
VarInfoDict.Add(plcVarEnum, plcValue);
|
|
|
|
|
|
plcValue.Name = plcVarEnum;
|
|
|
|
|
|
return plcValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 读取PLC
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static object ReadVar(this SiemensClient client, PlcVarInfo varInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (client is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException($"PLC尚未初始化");
|
|
|
|
|
|
}
|
|
|
|
|
|
object resultvalue;
|
|
|
|
|
|
switch (varInfo.DataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DataTypeEnum.String:
|
|
|
|
|
|
var resultString = client.ReadString(varInfo.Address);
|
|
|
|
|
|
if (!resultString.IsSucceed) throw new Exception(resultString.Err);
|
|
|
|
|
|
resultvalue = resultString.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Bool:
|
|
|
|
|
|
var resultBool = client.ReadBoolean(varInfo.Address);
|
|
|
|
|
|
if (!resultBool.IsSucceed) throw new Exception(resultBool.Err);
|
|
|
|
|
|
resultvalue = resultBool.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Float:
|
|
|
|
|
|
var resultFloat = client.ReadFloat(varInfo.Address);
|
|
|
|
|
|
if (!resultFloat.IsSucceed) throw new Exception(resultFloat.Err);
|
|
|
|
|
|
resultvalue = resultFloat.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Double:
|
|
|
|
|
|
var resultDouble = client.ReadDouble(varInfo.Address);
|
|
|
|
|
|
if (!resultDouble.IsSucceed) throw new Exception(resultDouble.Err);
|
|
|
|
|
|
resultvalue = resultDouble.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Byte:
|
|
|
|
|
|
var resultByte = client.ReadByte(varInfo.Address);
|
|
|
|
|
|
if (!resultByte.IsSucceed) throw new Exception(resultByte.Err);
|
|
|
|
|
|
resultvalue = resultByte.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int16:
|
|
|
|
|
|
var resultInt16 = client.ReadInt16(varInfo.Address);
|
|
|
|
|
|
if (!resultInt16.IsSucceed) throw new Exception(resultInt16.Err);
|
|
|
|
|
|
resultvalue = resultInt16.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt16:
|
|
|
|
|
|
var resultUint16 = client.ReadUInt16(varInfo.Address);
|
|
|
|
|
|
if (!resultUint16.IsSucceed) throw new Exception(resultUint16.Err);
|
|
|
|
|
|
resultvalue = resultUint16.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int32:
|
|
|
|
|
|
var resultInt32 = client.ReadInt32(varInfo.Address);
|
|
|
|
|
|
if (!resultInt32.IsSucceed) throw new Exception(resultInt32.Err);
|
|
|
|
|
|
resultvalue = resultInt32.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt32:
|
|
|
|
|
|
var resultUInt32 = client.ReadUInt32(varInfo.Address);
|
|
|
|
|
|
if (!resultUInt32.IsSucceed) throw new Exception(resultUInt32.Err);
|
|
|
|
|
|
resultvalue = resultUInt32.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int64:
|
|
|
|
|
|
var resultInt64 = client.ReadInt64(varInfo.Address);
|
|
|
|
|
|
if (!resultInt64.IsSucceed) throw new Exception(resultInt64.Err);
|
|
|
|
|
|
resultvalue = resultInt64.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt64:
|
|
|
|
|
|
var resultUInt64 = client.ReadUInt64(varInfo.Address);
|
|
|
|
|
|
if (!resultUInt64.IsSucceed) throw new Exception(resultUInt64.Err);
|
|
|
|
|
|
resultvalue = resultUInt64.Value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
throw new NotImplementedException($"变量为指定数据类型,或是非预期的数据类型{varInfo}");
|
|
|
|
|
|
}
|
|
|
|
|
|
return resultvalue;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 转换数据类型,写入PLC
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static object WriteVar(this SiemensClient client, PlcVarInfo varInfo, object value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (client is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException($"PLC尚未初始化");
|
|
|
|
|
|
}
|
|
|
|
|
|
DataTypeEnum dataType = varInfo.DataType;
|
|
|
|
|
|
object convertValue;
|
|
|
|
|
|
Result result;
|
|
|
|
|
|
switch (dataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DataTypeEnum.String:
|
|
|
|
|
|
var @string = value.ToString();
|
|
|
|
|
|
convertValue = @string;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @string);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Bool:
|
|
|
|
|
|
var @bool = bool.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @bool;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @bool);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Float:
|
|
|
|
|
|
var @float = float.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @float;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @float);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Double:
|
|
|
|
|
|
var @double = double.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @double;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @double);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Byte:
|
|
|
|
|
|
var @byte = byte.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @byte;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @byte);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int16:
|
|
|
|
|
|
var @short = short.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @short;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @short);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt16:
|
|
|
|
|
|
var @ushort = ushort.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @ushort;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @ushort);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int32:
|
|
|
|
|
|
var @int = int.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @int;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @int);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt32:
|
|
|
|
|
|
var @uint = uint.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @uint;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @uint);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.Int64:
|
|
|
|
|
|
var @long = long.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @long;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @long);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataTypeEnum.UInt64:
|
|
|
|
|
|
var @ulong = ulong.Parse(value.ToString());
|
|
|
|
|
|
convertValue = @ulong;
|
|
|
|
|
|
result = client.Write(varInfo.Address, @ulong);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
throw new NotImplementedException($"变量为指定数据类型,或是非预期的数据类型{varInfo}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (result.IsSucceed)
|
|
|
|
|
|
{
|
|
|
|
|
|
return convertValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(result.Err);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 类型转换
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataType"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
//public static Type ToDataType(this DataTypeEnum dataType)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// Type plcDataType;
|
|
|
|
|
|
// switch (dataType)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// case DataTypeEnum.String:
|
|
|
|
|
|
// plcDataType = typeof(string);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Bool:
|
|
|
|
|
|
// plcDataType = typeof(bool);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Float:
|
|
|
|
|
|
// plcDataType = typeof(float);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Double:
|
|
|
|
|
|
// plcDataType = typeof(double);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Byte:
|
|
|
|
|
|
// plcDataType = typeof(byte);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Int16:
|
|
|
|
|
|
// plcDataType = typeof(short);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.UInt16:
|
|
|
|
|
|
// plcDataType = typeof(ushort);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Int32:
|
|
|
|
|
|
// plcDataType = typeof(int);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.UInt32:
|
|
|
|
|
|
// plcDataType = typeof(uint);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.Int64:
|
|
|
|
|
|
// plcDataType = typeof(long);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case DataTypeEnum.UInt64:
|
|
|
|
|
|
// plcDataType = typeof(ulong);
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// default:
|
|
|
|
|
|
// throw new NotImplementedException();
|
|
|
|
|
|
// }
|
|
|
|
|
|
// return plcDataType;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|