827 lines
27 KiB
C#
827 lines
27 KiB
C#
using System.Reflection;
|
||
using System.Text;
|
||
using HslCommunication;
|
||
using HslCommunication.Profinet.Siemens;
|
||
using PlcTool.Siemens.Entity;
|
||
using PlcTool.Siemens.PLCAttribute;
|
||
|
||
namespace PlcTool.Siemens;
|
||
|
||
public class SiemensS7
|
||
{
|
||
|
||
/*
|
||
* 作者:菻蔃
|
||
*
|
||
* 版本时间:2023年4月15日
|
||
*
|
||
*/
|
||
|
||
private const string tip = "致其他开发者,此组件为收费组件,若您有意使用,请自行联系作者购买授权,擅自使用本公司激活码将承担责任";
|
||
|
||
/// <summary>
|
||
/// 存储PLC连接
|
||
/// </summary>
|
||
readonly List<SiemensS7Connection> siemensS7Connections = [];
|
||
|
||
/// <summary>
|
||
/// 存储DB块具体在哪个PLC中
|
||
/// </summary>
|
||
readonly List<PlcDBName> plcDBNames = [];
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 操作PLC的类,传入PLC类型,地址,和组件激活码。
|
||
/// </summary>
|
||
/// <param name="authorizationCode"></param>
|
||
/// <exception cref="Exception"></exception>
|
||
public SiemensS7(string? authorizationCode = null)
|
||
{
|
||
if (string.IsNullOrEmpty(authorizationCode))
|
||
{
|
||
/*致本公司开发者,此为 10.6.1 版本激活码,若激活失败,尝试使用此版本*/
|
||
/*致其他开发者,此组件为收费组件,若您有意使用,请自行联系作者购买授权,擅自使用本公司激活码将承担责任*/
|
||
authorizationCode = "f562cc4c-4772-4b32-bdcd-f3e122c534e3";
|
||
}
|
||
bool isAuthorization = Authorization.SetAuthorizationCode(authorizationCode);
|
||
if (!isAuthorization)
|
||
{
|
||
/*这里抛出异常,一定记得提醒开发者注册*/
|
||
throw new Exception("组件未激活,上述激活码可能会因为版本更新而失效,请联系公司获取最新激活码,测试时可注释此行,未激活将只能使用24小时,切记上线前一定记得激活!!!");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加PLC信息
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="plcs"></param>
|
||
/// <returns></returns>
|
||
public SiemensS7 SetPlcs<T>(List<T> plcs) where T : class
|
||
{
|
||
if (plcs == null || plcs.Count == 0)
|
||
{
|
||
throw new Exception("传入数据为空。");
|
||
}
|
||
Type type = typeof(T);
|
||
var properties = type.GetProperties();
|
||
/*定义两个存储属性的变量*/
|
||
PropertyInfo? plcIdProperty = null;
|
||
PropertyInfo? plcIPProperty = null;
|
||
PropertyInfo? plcKindProperty = null;
|
||
PropertyInfo? rackProperty = null;
|
||
PropertyInfo? soltindProperty = null;
|
||
/*轮询查找到的属性给变量赋值*/
|
||
foreach (var property in properties)
|
||
{
|
||
var plcIdattributes = property.GetCustomAttributes(typeof(PlcIdAttribute), false);
|
||
if (plcIdattributes.Length != 0)
|
||
{
|
||
plcIdProperty = property;
|
||
}
|
||
var plcIPattributes = property.GetCustomAttributes(typeof(PlcIPAttribute), false);
|
||
if (plcIPattributes.Length != 0)
|
||
{
|
||
plcIPProperty = property;
|
||
}
|
||
var plcKindattributes = property.GetCustomAttributes(typeof(PlcKindAttribute), false);
|
||
if (plcKindattributes.Length != 0)
|
||
{
|
||
plcKindProperty = property;
|
||
}
|
||
var rackattributes = property.GetCustomAttributes(typeof(RackAttribute), false);
|
||
if (rackattributes.Length != 0)
|
||
{
|
||
rackProperty = property;
|
||
}
|
||
var soltattributes = property.GetCustomAttributes(typeof(SlotAttribute), false);
|
||
if (soltattributes.Length != 0)
|
||
{
|
||
soltindProperty = property;
|
||
}
|
||
}
|
||
/*判断是否有对应的特性*/
|
||
if (plcIdProperty == null || plcIPProperty == null || plcKindProperty == null)
|
||
{
|
||
throw new Exception("未正确识别类中的属性特性,需要同时添加 PlcIdAttribution、PlcIPAttribute 和 PlcKindAttribute 三个特性。");
|
||
}
|
||
/*添加对应的值*/
|
||
foreach (T plc in plcs)
|
||
{
|
||
var plckind = plcKindProperty.GetValue(plc)!.ToString().ToPlcKind();
|
||
var plcip = plcIPProperty.GetValue(plc)!.ToString();
|
||
|
||
SiemensS7Connection siemensS7Connection = new()
|
||
{
|
||
PlcId = Convert.ToInt32(plcIdProperty.GetValue(plc)),
|
||
SiemensS7 = new SiemensS7Net(plckind, plcip)
|
||
};
|
||
siemensS7Connection.SiemensS7.Rack = Convert.ToByte(rackProperty!.GetValue(plc));
|
||
siemensS7Connection.SiemensS7.Slot = Convert.ToByte(soltindProperty!.GetValue(plc));
|
||
siemensS7Connections.Add(siemensS7Connection);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加PLC的Db地址信息
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="dbNames"></param>
|
||
/// <returns></returns>
|
||
public SiemensS7 SetPlcDB<T>(List<T>? dbNames) where T : class
|
||
{
|
||
if (dbNames == default || dbNames.Count == 0)
|
||
{
|
||
throw new Exception("传入的数据为空");
|
||
}
|
||
Type type = typeof(T);
|
||
var properties = type.GetProperties();
|
||
/*定义两个存储属性的变量*/
|
||
PropertyInfo? plcIdProperty = null;
|
||
PropertyInfo? dbNameProperty = null;
|
||
PropertyInfo? dbAddressProperty = null;
|
||
/*轮询查找到的属性给变量赋值*/
|
||
foreach (var property in properties)
|
||
{
|
||
var plcIdattributes = property.GetCustomAttributes(typeof(PlcIdAttribute), false);
|
||
if (plcIdattributes.Length != 0)
|
||
{
|
||
plcIdProperty = property;
|
||
}
|
||
var dbNameattributes = property.GetCustomAttributes(typeof(PlcDBNameAttribute), false);
|
||
if (dbNameattributes.Length != 0)
|
||
{
|
||
dbNameProperty = property;
|
||
}
|
||
var dbAddressattributes = property.GetCustomAttributes(typeof(PlcDBAddressAttribute), false);
|
||
if (dbAddressattributes.Length != 0)
|
||
{
|
||
dbAddressProperty = property;
|
||
}
|
||
}
|
||
/*判断是否有对应的特性*/
|
||
if (plcIdProperty == null || dbNameProperty == null || dbAddressProperty == null)
|
||
{
|
||
throw new Exception("未正确识别类中的属性特性,需要同时添加 PlcIdAttribute、PlcDBNameAttribute、PlcDBAddressAttribute 三个特性。");
|
||
}
|
||
/*添加对应的值*/
|
||
foreach (T dbName in dbNames)
|
||
{
|
||
PlcDBName plcDBName = new()
|
||
{
|
||
PlcId = Convert.ToUInt32(plcIdProperty.GetValue(dbName)),
|
||
DBName = dbNameProperty.GetValue(dbName)!.ToString(),
|
||
};
|
||
var dbaddress = dbAddressProperty.GetValue(dbName);
|
||
plcDBName.DBAddress = dbaddress == null ? "" : dbaddress.ToString();
|
||
plcDBNames.Add(plcDBName);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 连接PLC
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 请使用异步重载方法
|
||
/// </remarks>
|
||
public SemS7Result ConnectPlcs()
|
||
{
|
||
if (siemensS7Connections.Count == 0)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = "没有设置PLC连接,请先调用 SetPlcs 方法。"
|
||
};
|
||
}
|
||
/*连接PLC*/
|
||
foreach (SiemensS7Connection siemensS7Connection in siemensS7Connections)
|
||
{
|
||
if (siemensS7Connection.SiemensS7 == default)
|
||
{
|
||
continue;
|
||
}
|
||
siemensS7Connection.SiemensS7.ConnectTimeOut = 2000;
|
||
var connectResult = siemensS7Connection.SiemensS7.ConnectServer();
|
||
if (!connectResult.IsSuccess)
|
||
{
|
||
// 只要有一个连接失败,直接返回错误信息
|
||
connectResult.Message =
|
||
$"PLC:{siemensS7Connection.SiemensS7.IpAddress} 连接失败,异常信息:{connectResult.Message}";
|
||
return connectResult.ToSemS7Result();
|
||
}
|
||
}
|
||
return new SemS7Result()
|
||
{
|
||
Success = true,
|
||
ErrCode = 0,
|
||
Message = "所有PLC连接成功"
|
||
};
|
||
}
|
||
|
||
#region 根据名称读写PLC数据
|
||
|
||
|
||
/// <summary>
|
||
/// 根据名称写入PLC值,目前不支持 string
|
||
/// 写入前请提前转换好对应的数据格式
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="values"></param>
|
||
/// <returns></returns>
|
||
public (SemS7Result result, byte[]? bytes) WritePlcWhithName(string plcDBName, params object[] values)
|
||
{
|
||
if (values.Length == 0)
|
||
{
|
||
return (new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 997,
|
||
Message = $"写入失败,传入的值为空。"
|
||
}, default);
|
||
}
|
||
/*根据名称获取地址*/
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return (new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
}, default);
|
||
}
|
||
(Exception? Ex, byte[]? bytes) getByte = GetPlcBytes(values);
|
||
if (getByte.Ex != null)
|
||
{
|
||
return (new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 996,
|
||
Message = $"{getByte.Ex.Message}"
|
||
}, default);
|
||
}
|
||
byte[]? bytes = getByte.bytes;//获取转化成功的数组
|
||
OperateResult operateResult = siemensS7.Write(dbAddress, bytes);
|
||
return (operateResult.ToSemS7Result(), bytes);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入bool值
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="values"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result WriteBoolWhithName(string plcDBName, params bool[] values)
|
||
{
|
||
if (values.Length == 0)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 997,
|
||
Message = $"写入失败,传入的值为空。"
|
||
};
|
||
}
|
||
/*根据名称获取地址*/
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
OperateResult operateResult = siemensS7.Write(dbAddress, values);
|
||
return operateResult.ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据地址写入值
|
||
/// </summary>
|
||
/// /// <param name="plcNo"></param>
|
||
/// <param name="plcDBAddress"></param>
|
||
/// <param name="values"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result WritePlcWhithAddress(int plcNo, string plcDBAddress, params object[] values)
|
||
{
|
||
if (values.Length == 0)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 997,
|
||
Message = $"写入失败,传入的值为空。"
|
||
};
|
||
}
|
||
/*根据名称获取地址*/
|
||
SiemensS7Net? siemensS7 = GetSiemensS7(plcNo);
|
||
if (siemensS7 == default)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = "找不到该PLC连接"
|
||
};
|
||
}
|
||
(Exception? Ex, byte[]? bytes) getByte = GetPlcBytes(values);
|
||
if (getByte.Ex != null)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 996,
|
||
Message = $"{getByte.Ex.Message}"
|
||
};
|
||
}
|
||
byte[]? bytes = getByte.bytes;//获取转化成功的数组
|
||
OperateResult operateResult = siemensS7.Write(plcDBAddress, bytes);
|
||
return operateResult.ToSemS7Result();
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 根据名称写入PLC值,写入string
|
||
/// 写入前请提前转换好对应的数据格式
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="value"></param>
|
||
/// <param name="encoding">自定的编码信息,一般System.Text.Encoding.ASCII即可,中文需要 Encoding.GetEncoding("gb2312")</param>
|
||
/// <returns></returns>
|
||
public SemS7Result WriteStringWhithName(string plcDBName, string value, Encoding encoding)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.Write(dbAddress, value, encoding).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个Byte数组
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="length"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<byte[]> ReadByteWithName(string plcDBName, ushort length)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<byte[]>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.Read(dbAddress, length).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个Byte
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<byte> ReadByteWithName(string plcDBName)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<byte>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
SemS7Result<byte[]> actionResult = ReadByteWithName(dbAddress!, 1);
|
||
if (!actionResult.Success)
|
||
{
|
||
return new SemS7Result<byte>()
|
||
{
|
||
Success = false,
|
||
ErrCode = actionResult.ErrCode,
|
||
Message = actionResult.Message
|
||
};
|
||
}
|
||
|
||
var values = actionResult.Value;
|
||
if (values == default || values.Length == 0)
|
||
{
|
||
return new SemS7Result<byte>()
|
||
{
|
||
Success = false,
|
||
ErrCode = actionResult.ErrCode,
|
||
Message = actionResult.Message
|
||
};
|
||
}
|
||
return new SemS7Result<byte>()
|
||
{
|
||
Success = true,
|
||
ErrCode = actionResult.ErrCode,
|
||
Message = actionResult.Message,
|
||
Value = values[0]
|
||
};
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一定数量的Int16值
|
||
/// 对应PLC数据类型为 W,int,
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="length"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<short[]> ReadInt16WithName(string plcDBName, ushort length)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<short[]>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadInt16(dbAddress, length).ToSemS7Result();
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一个Int16值
|
||
/// 对应PLC数据类型为 W,int,
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<short> ReadInt16WithName(string plcDBName)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<short>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadInt16(dbAddress).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一定数量的Int32值
|
||
/// 对应PLC数据类型为 DW,Dint,
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="length"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<int[]> ReadInt32WithName(string plcDBName, ushort length)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<int[]>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadInt32(dbAddress, length).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一个Int32值
|
||
/// 对应PLC数据类型为 DW,Dint,
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<int> ReadInt32WithName(string plcDBName)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<int>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadInt32(dbAddress).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一定数量的bool值
|
||
/// 对应PLC数据类型为 X
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// /// <param name="length"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<bool[]> ReadBoolWithName(string plcDBName, ushort length)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<bool[]>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadBool(dbAddress, length).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据名称读取一个Int32值
|
||
/// 对应PLC数据类型为 X
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <returns></returns>
|
||
public SemS7Result<bool> ReadBoolWithName(string plcDBName)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<bool>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadBool(dbAddress).ToSemS7Result();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据名称读取string值
|
||
/// 对应PLC数据类型为 string
|
||
/// </summary>
|
||
/// <param name="plcDBName"></param>
|
||
/// <param name="length"></param>
|
||
/// <param name="encoding">自定的编码信息,一般System.Text.Encoding.ASCII即可,中文需要 Encoding.GetEncoding("gb2312")</param>
|
||
/// <returns></returns>
|
||
public SemS7Result<string> ReadStringWithName(string plcDBName, ushort length, Encoding encoding)
|
||
{
|
||
(SiemensS7Net? siemensS7, string? dbAddress, string? errText) = GetSiemensS7(plcDBName);
|
||
if (siemensS7 == null)
|
||
{
|
||
return new SemS7Result<string>()
|
||
{
|
||
Success = false,
|
||
ErrCode = 999,
|
||
Message = errText
|
||
};
|
||
}
|
||
return siemensS7.ReadString(dbAddress, length, encoding).ToSemS7Result();
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 根据DB名称查找其对应的连接
|
||
/// </summary>
|
||
/// <param name="dbName"></param>
|
||
/// <returns></returns>
|
||
private (SiemensS7Net? siemensS7, string? dbAddress, string? errText) GetSiemensS7(string dbName)
|
||
{
|
||
if (plcDBNames.Count == 0 || siemensS7Connections.Count == 0)
|
||
{
|
||
return (null, null, "未设置 plc 或者 未设置 DB地址,请调用 SetPlcs 方法设置 plc 或者 调用 SetPlcDB 方法设置 DB地址");
|
||
}
|
||
/*找出该地址对应的ID*/
|
||
PlcDBName? plcDBName = plcDBNames.Find(f => f.DBName == dbName);
|
||
if (plcDBName == default)
|
||
{
|
||
return (null, null, "该DB地址不存在,请核实wcs数据录入是否正确");
|
||
}
|
||
/*找出该ID对应的连接*/
|
||
SiemensS7Connection? siemensS7Connection = siemensS7Connections.Find(f => f.PlcId == plcDBName.PlcId);
|
||
if (siemensS7Connection == default)
|
||
{
|
||
return (null, null, "该PLC连接不存在,请核实wcs数据录入是否正确");
|
||
}
|
||
return (siemensS7Connection.SiemensS7, plcDBName.DBAddress, null);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 根据plcNo 返回连接信息
|
||
/// </summary>
|
||
/// <param name="plcNo"></param>
|
||
/// <returns></returns>
|
||
private SiemensS7Net? GetSiemensS7(int plcNo)
|
||
{
|
||
/*找出该ID对应的连接*/
|
||
SiemensS7Connection? siemensS7Connection = siemensS7Connections.Find(f => f.PlcId == plcNo);
|
||
if (siemensS7Connection == default)
|
||
{
|
||
return default;
|
||
}
|
||
return siemensS7Connection.SiemensS7;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
//NetworkDoubleBase dataTransfrom = new NetworkDoubleBase();
|
||
private readonly SiemensS7Net dataTransfrom = new(SiemensPLCS.S1500);
|
||
|
||
#region 将 byte 数组转化为值
|
||
|
||
|
||
/// <summary>
|
||
/// 将数组转化为值
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="bytes"></param>
|
||
/// <param name="index"></param>
|
||
/// <returns></returns>
|
||
public object? Trans<T>(byte[] bytes, int index) where T : struct
|
||
{
|
||
Type type = typeof(T);
|
||
if (type == typeof(short))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransInt16(bytes, index);
|
||
}
|
||
else if (type == typeof(int))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransInt32(bytes, index);
|
||
}
|
||
else if (type == typeof(bool))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransBool(bytes, index);
|
||
}
|
||
else if (type == typeof(double))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransDouble(bytes, index);
|
||
}
|
||
else if (type == typeof(float))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransSingle(bytes, index);
|
||
}
|
||
else if (type == typeof(uint))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransUInt32(bytes, index);
|
||
}
|
||
else if (type == typeof(ushort))
|
||
{
|
||
return dataTransfrom.ByteTransform.TransUInt16(bytes, index);
|
||
}
|
||
else
|
||
{
|
||
return null; // 不支持的数据类型
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region 将传入的值转化成 byte 数组
|
||
/// <summary>
|
||
/// 将传入的值转化成byte数组
|
||
/// </summary>
|
||
/// <param name="values"></param>
|
||
/// <returns></returns>
|
||
public (Exception? Ex, byte[]? bytes) GetPlcBytes(object[] values)
|
||
{
|
||
List<byte> bytes = [];
|
||
foreach (object value in values)
|
||
{
|
||
Type type = value.GetType();
|
||
if (type == typeof(short))
|
||
{
|
||
short va = Convert.ToInt16(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(int))
|
||
{
|
||
int va = Convert.ToInt32(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(bool))
|
||
{
|
||
bool va = Convert.ToBoolean(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(double))
|
||
{
|
||
double va = Convert.ToDouble(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(float))
|
||
{
|
||
float va = Convert.ToSingle(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(uint))
|
||
{
|
||
uint va = Convert.ToUInt32(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else if (type == typeof(ushort))
|
||
{
|
||
ushort va = Convert.ToUInt16(value);
|
||
byte[] data = dataTransfrom.ByteTransform.TransByte(va);
|
||
bytes.AddRange(data);
|
||
}
|
||
else
|
||
{
|
||
return (new Exception($"传入的数据中有不支持的数据类型 {type.Name} "), null);
|
||
}
|
||
}
|
||
return (null, [.. bytes]);
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region 根据名称和偏移量返回地址
|
||
|
||
/// <summary>
|
||
/// 根据名称和偏移量返回地址
|
||
/// </summary>
|
||
/// <param name="dbName"></param>
|
||
/// <param name="moveBit"></param>
|
||
/// <returns></returns>
|
||
public string GetAddressWithNameAndBit(string dbName, int moveBit)
|
||
{
|
||
/*
|
||
* 1、判断有几个点
|
||
* 有一个点的不是bool值
|
||
* 有两个点的是bool值
|
||
* 必须写全,如DB100等价于DB100.0,但不允许写DB100,因为容易识别错误
|
||
*/
|
||
if (plcDBNames.Count == 0)
|
||
{
|
||
return string.Empty; // 没有注册DB地址,
|
||
}
|
||
/*找出该地址对应的ID*/
|
||
PlcDBName? plcDBName = plcDBNames.Find(f => f.DBName == dbName);
|
||
if (plcDBName == default)
|
||
{
|
||
return string.Empty; // 找不到DB地址
|
||
}
|
||
|
||
string startDBAddress = plcDBName.DBAddress ?? string.Empty;
|
||
string[] dbInfos = startDBAddress.Split('.');
|
||
if (dbInfos.Length == 2)
|
||
{
|
||
// 只有一个点,判断为非Bool值
|
||
int startPoint = Convert.ToInt32(dbInfos[1]);
|
||
string newDBAddress = $"{dbInfos[0]}.{startPoint + moveBit}";
|
||
return newDBAddress;
|
||
}
|
||
else if (dbInfos.Length == 3)
|
||
{
|
||
// 有两个点,判断为bool值
|
||
int bigAddress = Convert.ToInt32(dbInfos[1]);
|
||
int smallAddress = Convert.ToInt32(dbInfos[2]);
|
||
while (moveBit > 0)
|
||
{
|
||
smallAddress++;
|
||
if (smallAddress >= 8)
|
||
{
|
||
bigAddress++;
|
||
smallAddress = 0;
|
||
}
|
||
moveBit--;
|
||
}
|
||
|
||
return $"{dbInfos[0]}.{bigAddress}.{smallAddress}";
|
||
}
|
||
|
||
return string.Empty;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
} |