Files

220 lines
8.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}
}