将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。

This commit is contained in:
QI Mingxuan
2026-04-16 17:31:13 +08:00
parent 6ec4c3ddaa
commit 2bd6e566c3
581 changed files with 74600 additions and 222 deletions
+219
View File
@@ -0,0 +1,219 @@
using System;
using System.Configuration;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Plc.Exceptions;
namespace XP.Hardware.PLC.Configs
{
/// <summary>
/// PLC 配置加载器(读取 App.config| PLC Configuration Loader (reads from App.config)
/// </summary>
public class ConfigLoader
{
private readonly ILoggerService _logger;
/// <summary>
/// 构造函数 | Constructor
/// </summary>
/// <param name="logger">日志服务 | Logger service</param>
public ConfigLoader(ILoggerService logger)
{
_logger = logger.ForModule("ConfigLoader");
}
/// <summary>
/// 从 App.config 加载 PLC 配置 | Load PLC configuration from App.config
/// </summary>
/// <param name="prefix">配置前缀,默认为 "Plc" | Configuration prefix, default is "Plc"</param>
/// <returns>PLC 配置对象 | PLC configuration object</returns>
public PlcConfig LoadPlcConfig(string prefix = "Plc")
{
try
{
_logger.Info($"开始从 App.config 加载 PLC 配置,前缀: {prefix}");
var config = new PlcConfig();
// 读取 IP 地址 | Read IP address
var ipAddress = ConfigurationManager.AppSettings[$"{prefix}:IpAddress"];
if (!string.IsNullOrEmpty(ipAddress))
{
config.IpAddress = ipAddress;
}
// 读取端口号 | Read port
var port = ConfigurationManager.AppSettings[$"{prefix}:Port"];
if (int.TryParse(port, out var portValue))
{
config.Port = portValue;
}
// 读取 Rack | Read Rack
var rack = ConfigurationManager.AppSettings[$"{prefix}:Rack"];
if (short.TryParse(rack, out var rackValue))
{
config.Rack = rackValue;
}
// 读取 Slot | Read Slot
var slot = ConfigurationManager.AppSettings[$"{prefix}:Slot"];
if (short.TryParse(slot, out var slotValue))
{
config.Slot = slotValue;
}
// 读取 PLC 类型 | Read PLC type
var plcType = ConfigurationManager.AppSettings[$"{prefix}:PlcType"];
if (!string.IsNullOrEmpty(plcType) && Enum.TryParse<PlcType>(plcType, true, out var plcTypeValue))
{
config.PlcType = plcTypeValue;
}
else if (!string.IsNullOrEmpty(plcType))
{
_logger.Warn($"无效的 PLC 类型: {plcType},使用默认值: {config.PlcType}");
}
// 读取数据块配置 | Read data block configuration
var readDbBlock = ConfigurationManager.AppSettings[$"{prefix}:ReadDbBlock"];
if (!string.IsNullOrEmpty(readDbBlock))
{
config.ReadDbBlock = readDbBlock;
}
var readStartAddress = ConfigurationManager.AppSettings[$"{prefix}:ReadStartAddress"];
if (int.TryParse(readStartAddress, out var readStartValue))
{
config.ReadStartAddress = readStartValue;
}
var readLength = ConfigurationManager.AppSettings[$"{prefix}:ReadLength"];
if (int.TryParse(readLength, out var readLengthValue))
{
config.ReadLength = readLengthValue;
}
// 读取批量读取周期 | Read bulk read interval
var bulkReadInterval = ConfigurationManager.AppSettings[$"{prefix}:BulkReadIntervalMs"];
if (int.TryParse(bulkReadInterval, out var bulkReadIntervalValue))
{
config.BulkReadIntervalMs = bulkReadIntervalValue;
}
// 读取超时配置 | Read timeout configuration
var connectTimeout = ConfigurationManager.AppSettings[$"{prefix}:ConnectTimeoutMs"];
if (int.TryParse(connectTimeout, out var connectTimeoutValue))
{
config.ConnectTimeoutMs = connectTimeoutValue;
}
var readTimeout = ConfigurationManager.AppSettings[$"{prefix}:ReadTimeoutMs"];
if (int.TryParse(readTimeout, out var readTimeoutValue))
{
config.ReadTimeoutMs = readTimeoutValue;
}
var writeTimeout = ConfigurationManager.AppSettings[$"{prefix}:WriteTimeoutMs"];
if (int.TryParse(writeTimeout, out var writeTimeoutValue))
{
config.WriteTimeoutMs = writeTimeoutValue;
}
// 读取重连配置 | Read reconnection configuration
var bReConnect = ConfigurationManager.AppSettings[$"{prefix}:bReConnect"];
if (bool.TryParse(bReConnect, out var bReConnectValue))
{
config.bReConnect = bReConnectValue;
}
// 验证配置参数 | Validate configuration parameters
ValidateConfig(config);
_logger.Info($"成功加载 PLC 配置: {config.IpAddress}:{config.Port}, Rack={config.Rack}, Slot={config.Slot}, 型号={config.PlcType}");
return config;
}
catch (PlcException)
{
// PlcException 直接向上抛出 | Re-throw PlcException
throw;
}
catch (Exception ex)
{
_logger.Error(ex, $"加载 PLC 配置失败: {ex.Message}");
throw new PlcException("配置加载失败", ex);
}
}
/// <summary>
/// 验证配置参数 | Validate configuration parameters
/// </summary>
/// <param name="config">PLC 配置对象 | PLC configuration object</param>
private void ValidateConfig(PlcConfig config)
{
// 验证 IP 地址不为空 | Validate IP address is not empty
if (string.IsNullOrWhiteSpace(config.IpAddress))
{
throw new PlcException("PLC IP 地址不能为空");
}
// 验证端口号范围 (1-65535) | Validate port range (1-65535)
if (config.Port < 1 || config.Port > 65535)
{
throw new PlcException($"PLC 端口号无效: {config.Port},有效范围: 1-65535");
}
// 验证 Rack 范围 (0-7) | Validate Rack range (0-7)
if (config.Rack < 0 || config.Rack > 7)
{
throw new PlcException($"Rack 参数无效: {config.Rack},有效范围: 0-7");
}
// 验证 Slot 范围 (0-31) | Validate Slot range (0-31)
if (config.Slot < 0 || config.Slot > 31)
{
throw new PlcException($"Slot 参数无效: {config.Slot},有效范围: 0-31");
}
// 验证超时时间大于 0 | Validate timeout is greater than 0
if (config.ConnectTimeoutMs <= 0)
{
throw new PlcException($"连接超时时间无效: {config.ConnectTimeoutMs},必须大于 0");
}
if (config.ReadTimeoutMs <= 0)
{
throw new PlcException($"读取超时时间无效: {config.ReadTimeoutMs},必须大于 0");
}
if (config.WriteTimeoutMs <= 0)
{
throw new PlcException($"写入超时时间无效: {config.WriteTimeoutMs},必须大于 0");
}
// 验证数据块配置,缺失时使用默认值 | Validate data block configuration, use default if missing
if (string.IsNullOrWhiteSpace(config.ReadDbBlock))
{
_logger.Warn("ReadDbBlock 未配置,使用默认值: DB1");
config.ReadDbBlock = "DB1";
}
if (config.ReadLength <= 0)
{
_logger.Warn($"ReadLength 无效: {config.ReadLength},使用默认值: 100");
config.ReadLength = 100;
}
if (config.ReadStartAddress < 0)
{
_logger.Warn($"ReadStartAddress 无效: {config.ReadStartAddress},使用默认值: 0");
config.ReadStartAddress = 0;
}
// 验证批量读取周期 | Validate bulk read interval
if (config.BulkReadIntervalMs <= 0)
{
_logger.Warn($"BulkReadIntervalMs 无效: {config.BulkReadIntervalMs},使用默认值: 100");
config.BulkReadIntervalMs = 100;
}
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XP.Hardware.PLC.Configs
{
/// <summary>
/// PLC 类型枚举 | PLC Type Enumeration
/// </summary>
public enum PlcType
{
/// <summary>
/// S7-200Smart 系列 | S7-200Smart series
/// </summary>
S200Smart,
/// <summary>
/// S7-300 系列 | S7-300 series
/// </summary>
S300,
/// <summary>
/// S7-400 系列 | S7-400 series
/// </summary>
S400,
/// <summary>
/// S7-1200 系列 | S7-1200 series
/// </summary>
S1200,
/// <summary>
/// S7-1500 系列 | S7-1500 series
/// </summary>
S1500
}
public class PlcConfig
{
// 连接配置
public string IpAddress { get; set; } = "127.0.0.1";
public int Port { get; set; } = 502;
public short Rack { get; set; } = 0;
public short Slot { get; set; } = 1;
/// <summary>
/// PLC 型号类型 | PLC model type
/// </summary>
public PlcType PlcType { get; set; } = PlcType.S1200;
// 读取配置 | Read configuration
public string ReadDbBlock { get; set; } = "DB1";
public int ReadStartAddress { get; set; } = 0;
public int ReadLength { get; set; } = 100; // 字节长度
/// <summary>
/// 批量读取周期(ms| Bulk read interval (ms)
/// </summary>
public int BulkReadIntervalMs { get; set; } = 100;
// 超时与重试
public int ConnectTimeoutMs { get; set; } = 3000;
public int ReadTimeoutMs { get; set; } = 3000;
public int WriteTimeoutMs { get; set; } = 3000;
public bool bReConnect { get; set; } = false;
}
}