using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Protocol376Simulator.Factory;
using Protocol376Simulator.Interfaces;
using Protocol376Simulator.Models;
using Protocol376Simulator.Simulators;
using Serilog;
namespace Protocol376Simulator.CommandProcessor
{
///
/// 命令处理器类,负责处理控制台命令
///
public class CommandHandler
{
private readonly RandomDataGenerator _dataGenerator = new RandomDataGenerator();
private bool _useRandomData = false;
private bool _displayHexLog = false;
///
/// 处理命令
///
/// 命令及参数
/// 处理任务
public async Task ProcessCommand(string[] commandParts)
{
if (commandParts == null || commandParts.Length == 0)
{
return;
}
string command = commandParts[0].ToLower();
try
{
switch (command)
{
case "help":
DisplayHelp();
break;
case "server":
// 设置服务器地址和端口
if (commandParts.Length >= 3)
{
string serverAddress = commandParts[1];
if (int.TryParse(commandParts[2], out int serverPort))
{
SimulatorFactory.SetServerConfig(serverAddress, serverPort);
}
else
{
Log.Warning("无效的端口号");
}
}
else
{
Log.Warning("语法: server
");
}
break;
case "create":
// 创建集中器
if (commandParts.Length >= 2)
{
string address = commandParts[1];
var simulator = SimulatorFactory.CreateConcentrator(address);
// 启用十六进制日志
if (_displayHexLog)
{
simulator.MessageReceived += (sender, message) => {
string hexString = BitConverter.ToString(message).Replace("-", " ");
Log.Debug("集中器 (地址: {Address}) 收到原始报文: {HexMessage}", address, hexString);
};
}
}
else
{
Log.Warning("语法: create ");
}
break;
case "auto":
// 自动创建集中器
var newSimulator = SimulatorFactory.CreateConcentratorWithAutoAddress();
Log.Information("已自动创建集中器: {Address}",
((ConcentratorSimulator)newSimulator)._concentratorAddress);
break;
case "batch":
// 批量创建集中器
if (commandParts.Length >= 2 && int.TryParse(commandParts[1], out int count))
{
SimulatorFactory.BatchCreateConcentrators(count);
}
else
{
Log.Warning("语法: batch ");
}
break;
case "connect":
// 连接集中器
if (commandParts.Length >= 2)
{
string address = commandParts[1];
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
await simulator.StartAsync();
}
}
else
{
Log.Warning("语法: connect ");
}
break;
case "login":
// 发送登录消息
if (commandParts.Length >= 2)
{
await SendLoginCommand(commandParts[1]);
}
else
{
Log.Warning("语法: login ");
}
break;
case "heartbeat":
// 发送心跳消息
if (commandParts.Length >= 2)
{
await SendHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: heartbeat ");
}
break;
case "valve":
// 发送阀控消息
if (commandParts.Length >= 3 && byte.TryParse(commandParts[2], out byte operation))
{
await SendValveControlCommand(commandParts[1], operation);
}
else
{
Log.Warning("语法: valve (1=开阀, 2=关阀, 3=查询状态)");
}
break;
case "upload":
// 发送数据上传消息
if (commandParts.Length >= 3 && byte.TryParse(commandParts[2], out byte dataType))
{
await SendDataUploadCommand(commandParts[1], dataType);
}
else
{
Log.Warning("语法: upload (1=水表, 2=电表, 3=气表, 4=状态)");
}
break;
case "read":
// 发送读数据消息
if (commandParts.Length >= 3 && byte.TryParse(commandParts[2], out byte readType))
{
await SendReadDataCommand(commandParts[1], readType);
}
else
{
Log.Warning("语法: read (1=水表, 2=电表, 3=气表, 4=状态)");
}
break;
case "setparam":
// 发送设置参数消息
if (commandParts.Length >= 4 && byte.TryParse(commandParts[2], out byte paramType))
{
string paramValue = commandParts[3];
await SendSetParameterCommand(commandParts[1], paramType, paramValue);
}
else
{
Log.Warning("语法: setparam ");
}
break;
case "startbeat":
// 启动自动心跳
if (commandParts.Length >= 2)
{
await StartAutoHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: startbeat ");
}
break;
case "stopbeat":
// 停止自动心跳
if (commandParts.Length >= 2)
{
await StopAutoHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: stopbeat ");
}
break;
case "status":
// 显示集中器状态
if (commandParts.Length >= 2)
{
ShowConcentratorStatusCommand(commandParts[1]);
}
else
{
Log.Warning("语法: status ");
}
break;
case "setdata":
// 设置表计数据
if (commandParts.Length >= 4 && byte.TryParse(commandParts[2], out byte setDataType))
{
string dataValue = commandParts[3];
SetMeterDataCommand(commandParts[1], setDataType, dataValue);
}
else
{
Log.Warning("语法: setdata ");
}
break;
case "autoresponse":
// 设置自动响应
if (commandParts.Length >= 3 && bool.TryParse(commandParts[2], out bool enabled))
{
SetAutoResponseCommand(commandParts[1], enabled);
}
else
{
Log.Warning("语法: autoresponse ");
}
break;
case "disconnect":
// 断开集中器
if (commandParts.Length >= 2)
{
await DisconnectConcentratorCommand(commandParts[1]);
}
else
{
Log.Warning("语法: disconnect ");
}
break;
case "list":
// 列出所有集中器
ListAllConcentratorsCommand();
break;
case "batchlogin":
// 批量登录
if (commandParts.Length >= 2)
{
await BatchLoginCommand(commandParts[1]);
}
else
{
Log.Warning("语法: batchlogin ");
}
break;
case "batchbeat":
// 批量发送心跳
if (commandParts.Length >= 2)
{
await BatchSendHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: batchbeat ");
}
break;
case "batchvalve":
// 批量阀控
if (commandParts.Length >= 3 && byte.TryParse(commandParts[2], out byte batchOperation))
{
await BatchValveControlCommand(commandParts[1], batchOperation);
}
else
{
Log.Warning("语法: batchvalve ");
}
break;
case "batchstartbeat":
// 批量启动自动心跳
if (commandParts.Length >= 2)
{
await BatchStartAutoHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: batchstartbeat ");
}
break;
case "batchstopbeat":
// 批量停止自动心跳
if (commandParts.Length >= 2)
{
await BatchStopAutoHeartbeatCommand(commandParts[1]);
}
else
{
Log.Warning("语法: batchstopbeat ");
}
break;
case "stats":
// 显示通信统计
if (commandParts.Length >= 2)
{
ShowCommunicationStatisticsCommand(commandParts[1]);
}
else
{
Log.Warning("语法: stats ");
}
break;
case "reconnect":
// 设置重连参数
if (commandParts.Length >= 5 &&
bool.TryParse(commandParts[2], out bool autoReconnect) &&
int.TryParse(commandParts[3], out int maxAttempts) &&
int.TryParse(commandParts[4], out int delaySeconds))
{
SetReconnectParametersCommand(commandParts[1], autoReconnect, maxAttempts, delaySeconds);
}
else
{
Log.Warning("语法: reconnect ");
}
break;
case "userand":
// 设置是否使用随机数据
if (commandParts.Length >= 2 && bool.TryParse(commandParts[1], out bool useRandom))
{
_useRandomData = useRandom;
Log.Information("随机数据生成已{Status}", useRandom ? "启用" : "禁用");
}
else
{
Log.Warning("语法: userand ");
}
break;
case "hexlog":
// 设置是否显示十六进制日志
if (commandParts.Length >= 2 && bool.TryParse(commandParts[1], out bool displayHex))
{
_displayHexLog = displayHex;
Log.Information("十六进制日志已{Status}", displayHex ? "启用" : "禁用");
}
else
{
Log.Warning("语法: hexlog ");
}
break;
case "clear":
// 清空所有模拟器
await SimulatorFactory.ClearAllSimulatorsAsync();
break;
default:
Log.Warning("未知命令: {Command}", command);
break;
}
}
catch (Exception ex)
{
Log.Error(ex, "执行命令 {Command} 时发生错误: {ErrorMessage}", command, ex.Message);
}
}
private async Task SendLoginCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
await simulator.SendLoginMessageAsync();
Log.Information("集中器 (地址: {Address}) 已发送登录消息", address);
}
}
private async Task SendHeartbeatCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
await simulator.SendHeartbeatMessageAsync();
Log.Information("集中器 (地址: {Address}) 已发送心跳消息", address);
}
}
private async Task SendValveControlCommand(string address, byte operation)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
await concentrator.SendValveControlMessageAsync(operation);
Log.Information("集中器 (地址: {Address}) 已发送阀控消息, 操作码: {Operation}",
address, operation);
}
}
private async Task SendDataUploadCommand(string address, byte dataType)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
await concentrator.SendDataUploadMessageAsync(dataType);
Log.Information("集中器 (地址: {Address}) 已发送数据上传消息, 数据类型: {DataType}",
address, dataType);
}
}
private async Task SendReadDataCommand(string address, byte dataType)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
await concentrator.SendReadDataMessageAsync(dataType);
Log.Information("集中器 (地址: {Address}) 已发送读数据消息, 数据类型: {DataType}",
address, dataType);
}
}
private async Task SendSetParameterCommand(string address, byte paramType, string paramValue)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
// 将参数值转换为字节数组
byte[] paramData;
// 使用随机数据
if (paramValue.ToLower() == "random")
{
paramData = _dataGenerator.GenerateParameter(paramType);
Log.Information("已生成随机参数数据: 类型={Type}", paramType);
}
else
{
// 使用指定的数据值
if (paramValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
// 十六进制数据
string hexString = paramValue.Substring(2);
paramData = new byte[hexString.Length / 2];
for (int i = 0; i < paramData.Length; i++)
{
paramData[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
}
else
{
// 默认作为整数处理
if (int.TryParse(paramValue, out int value))
{
paramData = BitConverter.GetBytes(value);
}
else
{
// 字符串处理
paramData = System.Text.Encoding.ASCII.GetBytes(paramValue);
}
}
}
await concentrator.SendSetParameterMessageAsync(paramType, paramData);
Log.Information("集中器 (地址: {Address}) 已发送设置参数消息, 参数类型: {ParamType}",
address, paramType);
}
}
private async Task StartAutoHeartbeatCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
simulator.StartHeartbeat();
Log.Information("集中器 (地址: {Address}) 已启动自动心跳", address);
}
}
private async Task StopAutoHeartbeatCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
simulator.StopHeartbeat();
Log.Information("集中器 (地址: {Address}) 已停止自动心跳", address);
}
}
private void ShowConcentratorStatusCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
string status = simulator.GetStatus();
Console.WriteLine(status);
}
}
private void SetMeterDataCommand(string address, byte dataType, string dataValue)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
// 根据dataValue设置数据
byte[] meterData;
// 使用随机数据
if (dataValue.ToLower() == "random")
{
if (dataType <= 3) // 水表、电表、气表
{
meterData = _dataGenerator.GenerateMeterData(dataType);
}
else // 状态数据
{
meterData = _dataGenerator.GenerateStatusData();
}
Log.Information("已生成随机表计数据: 类型={Type}", dataType);
}
else
{
// 使用指定的数据值
if (dataValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
// 十六进制数据
string hexString = dataValue.Substring(2);
meterData = new byte[hexString.Length / 2];
for (int i = 0; i < meterData.Length; i++)
{
meterData[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
}
else
{
// 默认作为整数处理
if (int.TryParse(dataValue, out int value))
{
meterData = BitConverter.GetBytes(value);
}
else
{
// 字符串处理
meterData = System.Text.Encoding.ASCII.GetBytes(dataValue);
}
}
}
concentrator.UpdateMeterData(dataType, meterData);
Log.Information("集中器 (地址: {Address}) 表计数据已设置, 类型: {DataType}",
address, dataType);
}
}
private void SetAutoResponseCommand(string address, bool enabled)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
concentrator.SetAutoResponse(enabled);
Log.Information("集中器 (地址: {Address}) 自动响应已设置为: {Enabled}",
address, enabled);
}
}
private async Task DisconnectConcentratorCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null)
{
await simulator.StopAsync();
Log.Information("集中器 (地址: {Address}) 已断开连接", address);
}
}
private void ListAllConcentratorsCommand()
{
var simulators = SimulatorFactory.GetAllSimulators();
if (simulators.Count == 0)
{
Console.WriteLine("没有集中器实例");
return;
}
Console.WriteLine($"共有 {simulators.Count} 个集中器实例:");
foreach (var entry in simulators)
{
string connectionStatus = entry.Value.IsConnected ? "已连接" : "未连接";
Console.WriteLine($" {entry.Key}: {connectionStatus}");
}
}
private async Task BatchLoginCommand(string range)
{
await SimulatorFactory.BatchOperationAsync(range, async (simulator) => {
await simulator.SendLoginMessageAsync();
});
Log.Information("批量登录操作已完成");
}
private async Task BatchSendHeartbeatCommand(string range)
{
await SimulatorFactory.BatchOperationAsync(range, async (simulator) => {
await simulator.SendHeartbeatMessageAsync();
});
Log.Information("批量心跳操作已完成");
}
private async Task BatchValveControlCommand(string range, byte operation)
{
await SimulatorFactory.BatchOperationAsync(range, async (simulator) => {
if (simulator is ConcentratorSimulator concentrator)
{
await concentrator.SendValveControlMessageAsync(operation);
}
});
Log.Information("批量阀控操作已完成, 操作码: {Operation}", operation);
}
private async Task BatchStartAutoHeartbeatCommand(string range)
{
await SimulatorFactory.BatchOperationAsync(range, (simulator) => {
simulator.StartHeartbeat();
return Task.CompletedTask;
});
Log.Information("批量启动自动心跳操作已完成");
}
private async Task BatchStopAutoHeartbeatCommand(string range)
{
await SimulatorFactory.BatchOperationAsync(range, (simulator) => {
simulator.StopHeartbeat();
return Task.CompletedTask;
});
Log.Information("批量停止自动心跳操作已完成");
}
private void ShowCommunicationStatisticsCommand(string address)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
string stats = concentrator.GetCommunicationStatistics();
Console.WriteLine(stats);
}
}
private void SetReconnectParametersCommand(string address, bool autoReconnect, int maxAttempts, int delaySeconds)
{
var simulator = SimulatorFactory.GetSimulator(address);
if (simulator != null && simulator is ConcentratorSimulator concentrator)
{
concentrator.SetReconnectParameters(autoReconnect, maxAttempts, delaySeconds);
Log.Information("集中器 (地址: {Address}) 重连参数已设置: 自动重连={AutoReconnect}, 最大尝试次数={MaxAttempts}, 延迟={Delay}秒",
address, autoReconnect, maxAttempts, delaySeconds);
}
}
private void DisplayHelp()
{
Console.WriteLine("可用命令:");
Console.WriteLine(" help - 显示帮助信息");
Console.WriteLine(" server - 设置服务器地址和端口");
Console.WriteLine(" create - 创建集中器");
Console.WriteLine(" auto - 自动创建集中器(自动生成地址)");
Console.WriteLine(" batch - 批量创建集中器");
Console.WriteLine(" connect - 连接集中器到服务器");
Console.WriteLine(" login - 发送登录消息");
Console.WriteLine(" heartbeat - 发送心跳消息");
Console.WriteLine(" valve - 发送阀控消息 (1=开阀, 2=关阀, 3=查询)");
Console.WriteLine(" upload - 发送数据上传消息 (1=水表, 2=电表, 3=气表, 4=状态)");
Console.WriteLine(" read - 发送数据读取消息");
Console.WriteLine(" setparam - 发送设置参数消息");
Console.WriteLine(" startbeat - 启动自动心跳");
Console.WriteLine(" stopbeat - 停止自动心跳");
Console.WriteLine(" status - 显示集中器状态");
Console.WriteLine(" setdata - 设置表计数据");
Console.WriteLine(" autoresponse - 设置自动响应");
Console.WriteLine(" disconnect - 断开集中器连接");
Console.WriteLine(" list - 显示所有集中器");
Console.WriteLine(" batchlogin - 批量登录");
Console.WriteLine(" batchbeat - 批量发送心跳");
Console.WriteLine(" batchvalve - 批量阀控");
Console.WriteLine(" batchstartbeat - 批量启动自动心跳");
Console.WriteLine(" batchstopbeat - 批量停止自动心跳");
Console.WriteLine(" stats - 显示通信统计");
Console.WriteLine(" reconnect - 设置重连参数");
Console.WriteLine(" userand - 设置是否使用随机数据");
Console.WriteLine(" hexlog - 设置是否显示十六进制日志");
Console.WriteLine(" clear - 清空所有模拟器");
Console.WriteLine(" exit/quit/0 - 退出程序");
Console.WriteLine("");
Console.WriteLine("范围表达式说明:");
Console.WriteLine(" all - 所有集中器");
Console.WriteLine(" 1-5 - 地址后缀为1到5的集中器");
Console.WriteLine(" 312003001,312003002 - 指定的集中器列表");
}
}
}