Protocol376Simulator/Factory/SimulatorFactory.cs
2025-05-08 17:26:10 +08:00

269 lines
9.2 KiB
C#
Raw 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.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("已清空所有模拟器");
}
}
}