using GSModbus.Config;
|
|
namespace GSModbus
|
{
|
/// <summary>
|
/// 配置驱动Modbus系统演示程序
|
/// </summary>
|
public static class ConfigDemo
|
{
|
/// <summary>
|
/// 演示配置系统的使用
|
/// </summary>
|
public static async Task RunDemoAsync()
|
{
|
Console.WriteLine("=== GSModbus 通用配置系统演示 ===\n");
|
|
// 1. 创建配置管理器
|
var configManager = new ConfigurationManager();
|
|
// 订阅配置事件
|
configManager.ConfigurationLoaded += (sender, e) =>
|
{
|
Console.WriteLine($"✅ 配置加载成功: {e.Configuration.ProjectName}");
|
Console.WriteLine($" 配置文件路径: {e.ConfigPath}");
|
Console.WriteLine($" PLC地址: {e.Configuration.Connection.IpAddress}:{e.Configuration.Connection.Port}");
|
};
|
|
configManager.ConfigurationError += (sender, e) =>
|
{
|
Console.WriteLine($"❌ 配置错误: {e.ErrorMessage}");
|
};
|
|
// 2. 尝试加载默认配置
|
Console.WriteLine("1. 正在加载默认配置文件...");
|
var loaded = await configManager.LoadDefaultConfigurationAsync();
|
|
if (!loaded)
|
{
|
Console.WriteLine("⚠️ 默认配置文件不存在,创建示例配置...\n");
|
await CreateExampleConfigurationAsync();
|
|
// 重试加载
|
loaded = await configManager.LoadDefaultConfigurationAsync();
|
}
|
|
if (!loaded)
|
{
|
Console.WriteLine("❌ 无法加载配置文件,演示终止");
|
return;
|
}
|
|
// 3. 显示配置信息
|
Console.WriteLine("\n2. 配置信息摘要:");
|
DisplayConfigurationSummary(configManager.CurrentConfiguration!);
|
|
// 4. 创建通用Modbus管理器
|
Console.WriteLine("\n3. 创建通用Modbus管理器...");
|
using var modbusManager = new UniversalModbusManager(configManager.CurrentConfiguration);
|
|
// 订阅事件
|
modbusManager.ConnectionStatusChanged += (sender, isConnected) =>
|
{
|
Console.WriteLine($"🔗 连接状态: {(isConnected ? "已连接" : "未连接")}");
|
};
|
|
modbusManager.DataReceived += (sender, data) =>
|
{
|
Console.WriteLine($"📊 接收到数据: {data.GetDataSummary()}");
|
};
|
|
modbusManager.ErrorOccurred += (sender, error) =>
|
{
|
Console.WriteLine($"⚠️ 通信错误: {error}");
|
};
|
|
modbusManager.StatsUpdated += (sender, stats) =>
|
{
|
Console.WriteLine($"📈 统计信息: {stats.GetSummary()}");
|
};
|
|
// 5. 演示连接(注意:实际PLC可能不存在)
|
Console.WriteLine("\n4. 尝试连接到PLC...");
|
Console.WriteLine(" 注意:这只是演示,实际PLC可能不存在");
|
|
var connected = await modbusManager.ConnectAsync();
|
|
if (connected)
|
{
|
Console.WriteLine("✅ 连接成功!数据读取将开始...");
|
|
// 等待一段时间观察数据
|
Console.WriteLine(" 正在读取数据,按任意键停止...");
|
Console.ReadKey();
|
}
|
else
|
{
|
Console.WriteLine("❌ 连接失败(这是正常的,因为演示环境中可能没有实际PLC)");
|
}
|
|
// 6. 显示字段映射
|
Console.WriteLine("\n5. 字段映射信息:");
|
DisplayFieldMappings(configManager.CurrentConfiguration!);
|
|
Console.WriteLine("\n=== 演示结束 ===");
|
}
|
|
/// <summary>
|
/// 创建示例配置文件
|
/// </summary>
|
private static async Task CreateExampleConfigurationAsync()
|
{
|
Console.WriteLine("正在创建示例配置文件...");
|
|
try
|
{
|
// 确保配置目录存在
|
var configDir = Path.GetDirectoryName(ConfigurationManager.DEFAULT_CONFIG_PATH);
|
if (!string.IsNullOrEmpty(configDir) && !Directory.Exists(configDir))
|
{
|
Directory.CreateDirectory(configDir);
|
}
|
|
// 配置文件已经存在了(我们之前创建的)
|
if (File.Exists(ConfigurationManager.DEFAULT_CONFIG_PATH))
|
{
|
Console.WriteLine("✅ 配置文件已存在");
|
return;
|
}
|
|
// 创建默认配置
|
var defaultConfig = ConfigurationManager.CreateDefaultConfiguration();
|
var configManager = new ConfigurationManager();
|
await configManager.SaveConfigurationAsync(ConfigurationManager.DEFAULT_CONFIG_PATH);
|
|
Console.WriteLine($"✅ 已创建示例配置文件: {ConfigurationManager.DEFAULT_CONFIG_PATH}");
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"❌ 创建配置文件失败: {ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 显示配置摘要信息
|
/// </summary>
|
private static void DisplayConfigurationSummary(ModbusConfiguration config)
|
{
|
Console.WriteLine($" 项目名称: {config.ProjectName}");
|
Console.WriteLine($" 配置版本: {config.ConfigVersion}");
|
Console.WriteLine($" PLC地址: {config.Connection.IpAddress}:{config.Connection.Port}");
|
Console.WriteLine($" 心跳间隔: {config.Communication.HeartbeatIntervalMs}ms");
|
Console.WriteLine($" 数据轮询: {config.Communication.DataPollingIntervalMs}ms");
|
Console.WriteLine($" 自动重连: {(config.Communication.EnableAutoReconnect ? "启用" : "禁用")}");
|
|
// 统计字段数量
|
var controlFields = config.InputAddresses.ControlSignals.Count;
|
var productFields = config.InputAddresses.ProductData.Count;
|
var measurementFields = config.InputAddresses.MeasurementData.Count;
|
var totalFields = controlFields + productFields + measurementFields;
|
|
Console.WriteLine($" 数据字段: {totalFields}个 (控制:{controlFields}, 产品:{productFields}, 测量:{measurementFields})");
|
}
|
|
/// <summary>
|
/// 显示字段映射信息
|
/// </summary>
|
private static void DisplayFieldMappings(ModbusConfiguration config)
|
{
|
Console.WriteLine(" 输出地址 (MES → PLC):");
|
Console.WriteLine($" 心跳包: D{config.OutputAddresses.HeartbeatAddress.Address}");
|
Console.WriteLine($" 数据确认: D{config.OutputAddresses.DataConfirmationAddress.Address}");
|
|
Console.WriteLine("\n 输入地址 (PLC → MES):");
|
|
if (config.InputAddresses.ControlSignals.Any())
|
{
|
Console.WriteLine(" 控制信号:");
|
foreach (var field in config.InputAddresses.ControlSignals)
|
{
|
Console.WriteLine($" {field.Value.DisplayName}: D{field.Value.Address} ({field.Value.DataType})");
|
}
|
}
|
|
if (config.InputAddresses.ProductData.Any())
|
{
|
Console.WriteLine(" 产品数据:");
|
foreach (var field in config.InputAddresses.ProductData)
|
{
|
Console.WriteLine($" {field.Value.DisplayName}: D{field.Value.Address} ({field.Value.DataType}, 长度:{field.Value.Length})");
|
}
|
}
|
|
if (config.InputAddresses.MeasurementData.Any())
|
{
|
Console.WriteLine(" 测量数据:");
|
foreach (var field in config.InputAddresses.MeasurementData)
|
{
|
var unit = !string.IsNullOrEmpty(field.Value.Unit) ? $" {field.Value.Unit}" : "";
|
Console.WriteLine($" {field.Value.DisplayName}: D{field.Value.Address} ({field.Value.DataType}{unit})");
|
}
|
}
|
}
|
|
/// <summary>
|
/// 演示动态数据访问
|
/// </summary>
|
public static void DemoDynamicDataAccess(DynamicModbusData data)
|
{
|
Console.WriteLine("\n=== 动态数据访问演示 ===");
|
|
// 获取所有字段
|
foreach (var fieldName in data.FieldNames)
|
{
|
var config = data.GetFieldConfiguration(fieldName);
|
var value = data.GetFieldValue(fieldName);
|
var displayValue = config != null ? ModbusDataParser.FormatDisplayValue(value, config) : value?.ToString();
|
|
Console.WriteLine($" {config?.DisplayName ?? fieldName}: {displayValue}");
|
}
|
|
// 演示类型安全的访问
|
Console.WriteLine("\n类型安全访问示例:");
|
Console.WriteLine($" 字符串字段示例: '{data.GetString("ProductModel", "未知")}'");
|
Console.WriteLine($" 整数字段示例: {data.GetInt("TestStation", 0)}");
|
Console.WriteLine($" 布尔字段示例: {data.GetBool("TestResult", false)}");
|
|
Console.WriteLine($"\n数据读取时间: {data.ReadTime:yyyy-MM-dd HH:mm:ss}");
|
}
|
|
/// <summary>
|
/// 测试数据解析逻辑 - 使用原始值.txt中的样本数据
|
/// </summary>
|
public static void TestDataParsing()
|
{
|
Console.WriteLine("\n=== 数据解析测试(基于原始值.txt样本数据)===");
|
|
// 创建测试用的字段配置
|
var minInstallSizeConfig = new DataField
|
{
|
Address = 6033,
|
DataType = "Integer",
|
Length = 2,
|
Scale = 0.01,
|
Unit = "mm",
|
DecimalPlaces = 2,
|
DisplayName = "最小安装尺寸"
|
};
|
|
var maxInstallSizeConfig = new DataField
|
{
|
Address = 6035,
|
DataType = "Integer",
|
Length = 2,
|
Scale = 0.01,
|
Unit = "mm",
|
DecimalPlaces = 2,
|
DisplayName = "最大安装尺寸"
|
};
|
|
var workingVoltageConfig = new DataField
|
{
|
Address = 6041,
|
DataType = "Integer",
|
Length = 2,
|
Scale = 0.01,
|
Unit = "V",
|
DecimalPlaces = 2,
|
DisplayName = "工作电压"
|
};
|
|
var workingPressureConfig = new DataField
|
{
|
Address = 6045,
|
DataType = "Integer",
|
Length = 2,
|
Scale = 0.01,
|
Unit = "bar",
|
DecimalPlaces = 2,
|
DisplayName = "工作压力"
|
};
|
|
// 原始值.txt中的测试数据
|
Console.WriteLine("\n测试样本数据:");
|
TestSingleField("最小安装尺寸", new int[] { -31513, 0 }, minInstallSizeConfig);
|
TestSingleField("最大安装尺寸", new int[] { -18440, 0 }, maxInstallSizeConfig);
|
TestSingleField("工作电压", new int[] { 2891, 0 }, workingVoltageConfig);
|
TestSingleField("工作压力", new int[] { -31039, 1 }, workingPressureConfig);
|
|
// 额外的测试数据
|
TestSingleField("速度", new int[] { 541, 0 }, new DataField
|
{
|
DataType = "Integer", Length = 2, Scale = 0.01, Unit = "mm/s", DecimalPlaces = 2, DisplayName = "速度"
|
});
|
TestSingleField("工作电流", new int[] { 125, 0 }, new DataField
|
{
|
DataType = "Integer", Length = 2, Scale = 0.01, Unit = "A", DecimalPlaces = 2, DisplayName = "工作电流"
|
});
|
}
|
|
private static void TestSingleField(string testName, int[] registers, DataField config)
|
{
|
Console.WriteLine($"\n--- 测试 {testName} ---");
|
Console.WriteLine($"原始寄存器: [{string.Join(", ", registers)}]");
|
|
try
|
{
|
var result = ModbusDataParser.ParseFieldData(registers, config);
|
var displayValue = ModbusDataParser.FormatDisplayValue(result, config);
|
|
Console.WriteLine($"解析结果: {result}");
|
Console.WriteLine($"显示值: {displayValue}");
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"解析失败: {ex.Message}");
|
}
|
}
|
}
|
}
|