269 lines
9.2 KiB
C#
269 lines
9.2 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using Protocol376Simulator.Interfaces;
|
|||
|
|
using Protocol376Simulator.Simulators;
|
|||
|
|
using Serilog;
|
|||
|
|
|
|||
|
|
namespace Protocol376Simulator.Factory
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 模拟器工厂类,负责创建和管理模拟器实例
|
|||
|
|
/// </summary>
|
|||
|
|
public class SimulatorFactory
|
|||
|
|
{
|
|||
|
|
private static readonly Dictionary<string, ISimulator> _simulators = new Dictionary<string, ISimulator>();
|
|||
|
|
private static string _serverAddress = "127.0.0.1";
|
|||
|
|
private static int _serverPort = 10502;
|
|||
|
|
private static int _addressCounter = 1;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 设置服务器地址和端口
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="serverAddress">服务器地址</param>
|
|||
|
|
/// <param name="serverPort">服务器端口</param>
|
|||
|
|
public static void SetServerConfig(string serverAddress, int serverPort)
|
|||
|
|
{
|
|||
|
|
_serverAddress = serverAddress;
|
|||
|
|
_serverPort = serverPort;
|
|||
|
|
|
|||
|
|
Log.Information("服务器配置已更新: {ServerAddress}:{ServerPort}", _serverAddress, _serverPort);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 创建集中器模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="address">集中器地址</param>
|
|||
|
|
/// <returns>创建的模拟器实例</returns>
|
|||
|
|
public static ISimulator CreateConcentrator(string address)
|
|||
|
|
{
|
|||
|
|
// 检查地址是否已存在
|
|||
|
|
if (_simulators.ContainsKey(address))
|
|||
|
|
{
|
|||
|
|
Log.Warning("集中器地址 {Address} 已存在", address);
|
|||
|
|
return _simulators[address];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建新的模拟器实例
|
|||
|
|
var simulator = new ConcentratorSimulator(address, _serverAddress, _serverPort);
|
|||
|
|
|
|||
|
|
// 订阅事件
|
|||
|
|
simulator.StatusChanged += (sender, status) => {
|
|||
|
|
Log.Information("集中器 (地址: {Address}) 状态变更: {Status}", address, status);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 添加到集合
|
|||
|
|
_simulators[address] = simulator;
|
|||
|
|
|
|||
|
|
Log.Information("已创建集中器 (地址: {Address})", address);
|
|||
|
|
|
|||
|
|
return simulator;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 创建带自动生成地址的集中器模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>创建的模拟器实例</returns>
|
|||
|
|
public static ISimulator CreateConcentratorWithAutoAddress()
|
|||
|
|
{
|
|||
|
|
string address = GenerateNextAddress();
|
|||
|
|
return CreateConcentrator(address);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 批量创建集中器模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="count">创建数量</param>
|
|||
|
|
/// <returns>创建的模拟器地址列表</returns>
|
|||
|
|
public static List<string> BatchCreateConcentrators(int count)
|
|||
|
|
{
|
|||
|
|
var addresses = new List<string>();
|
|||
|
|
|
|||
|
|
for (int i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
string address = GenerateNextAddress();
|
|||
|
|
CreateConcentrator(address);
|
|||
|
|
addresses.Add(address);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Log.Information("已批量创建 {Count} 个集中器", count);
|
|||
|
|
|
|||
|
|
return addresses;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 生成下一个集中器地址
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>生成的地址</returns>
|
|||
|
|
private static string GenerateNextAddress()
|
|||
|
|
{
|
|||
|
|
// 生成9位十六进制地址,格式如:312001001
|
|||
|
|
string address = $"31{_addressCounter:D7}";
|
|||
|
|
_addressCounter++;
|
|||
|
|
return address;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取模拟器实例
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="address">集中器地址</param>
|
|||
|
|
/// <returns>模拟器实例,如果不存在则返回null</returns>
|
|||
|
|
public static ISimulator GetSimulator(string address)
|
|||
|
|
{
|
|||
|
|
if (_simulators.TryGetValue(address, out var simulator))
|
|||
|
|
{
|
|||
|
|
return simulator;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Log.Warning("集中器地址 {Address} 不存在", address);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取所有模拟器实例
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>模拟器实例列表</returns>
|
|||
|
|
public static Dictionary<string, ISimulator> GetAllSimulators()
|
|||
|
|
{
|
|||
|
|
return _simulators;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 按范围获取模拟器地址
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="range">范围表达式</param>
|
|||
|
|
/// <returns>模拟器地址列表</returns>
|
|||
|
|
public static List<string> GetAddressesInRange(string range)
|
|||
|
|
{
|
|||
|
|
var addresses = new List<string>();
|
|||
|
|
|
|||
|
|
// 如果是"all",返回所有地址
|
|||
|
|
if (range.ToLower() == "all")
|
|||
|
|
{
|
|||
|
|
addresses.AddRange(_simulators.Keys);
|
|||
|
|
return addresses;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析范围表达式
|
|||
|
|
string[] parts = range.Split(',');
|
|||
|
|
foreach (var part in parts)
|
|||
|
|
{
|
|||
|
|
if (part.Contains("-"))
|
|||
|
|
{
|
|||
|
|
// 处理范围形式:"1-5"
|
|||
|
|
string[] rangeParts = part.Trim().Split('-');
|
|||
|
|
if (rangeParts.Length == 2 && int.TryParse(rangeParts[0], out int start) && int.TryParse(rangeParts[1], out int end))
|
|||
|
|
{
|
|||
|
|
// 将索引转换为地址
|
|||
|
|
for (int i = start; i <= end; i++)
|
|||
|
|
{
|
|||
|
|
string address = $"31{i:D7}";
|
|||
|
|
if (_simulators.ContainsKey(address))
|
|||
|
|
{
|
|||
|
|
addresses.Add(address);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 处理单个地址形式
|
|||
|
|
string address = part.Trim();
|
|||
|
|
if (_simulators.ContainsKey(address))
|
|||
|
|
{
|
|||
|
|
addresses.Add(address);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return addresses;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 按范围批量操作模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="range">范围表达式</param>
|
|||
|
|
/// <param name="action">操作委托</param>
|
|||
|
|
/// <returns>操作任务</returns>
|
|||
|
|
public static async Task BatchOperationAsync(string range, Func<ISimulator, Task> action)
|
|||
|
|
{
|
|||
|
|
var addresses = GetAddressesInRange(range);
|
|||
|
|
|
|||
|
|
Log.Information("批量操作 {Count} 个集中器", addresses.Count);
|
|||
|
|
|
|||
|
|
foreach (var address in addresses)
|
|||
|
|
{
|
|||
|
|
if (_simulators.TryGetValue(address, out var simulator))
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
await action(simulator);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "批量操作集中器 {Address} 时发生错误: {ErrorMessage}",
|
|||
|
|
address, ex.Message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 删除模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="address">集中器地址</param>
|
|||
|
|
/// <returns>是否成功删除</returns>
|
|||
|
|
public static async Task<bool> RemoveSimulatorAsync(string address)
|
|||
|
|
{
|
|||
|
|
if (_simulators.TryGetValue(address, out var simulator))
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 停止模拟器
|
|||
|
|
await simulator.StopAsync();
|
|||
|
|
|
|||
|
|
// 从集合中移除
|
|||
|
|
_simulators.Remove(address);
|
|||
|
|
|
|||
|
|
Log.Information("已删除集中器 (地址: {Address})", address);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "删除集中器 {Address} 时发生错误: {ErrorMessage}",
|
|||
|
|
address, ex.Message);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 清空所有模拟器
|
|||
|
|
/// </summary>
|
|||
|
|
public static async Task ClearAllSimulatorsAsync()
|
|||
|
|
{
|
|||
|
|
// 停止所有模拟器
|
|||
|
|
foreach (var simulator in _simulators.Values)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
await simulator.StopAsync();
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "停止模拟器时发生错误: {ErrorMessage}", ex.Message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清空集合
|
|||
|
|
_simulators.Clear();
|
|||
|
|
|
|||
|
|
// 重置地址计数器
|
|||
|
|
_addressCounter = 1;
|
|||
|
|
|
|||
|
|
Log.Information("已清空所有模拟器");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|