using GSModbus.Config; namespace GSModbus.Config { /// /// 动态Modbus数据容器 - 基于配置动态存储和访问数据 /// public class DynamicModbusData { #region 私有字段 /// /// 数据存储字典 - 键为字段名,值为解析后的数据 /// private readonly Dictionary _data = new(); /// /// 原始寄存器数据 - 键为字段名,值为原始寄存器数组 /// private readonly Dictionary _rawData = new(); #endregion #region 公共属性 /// /// 数据读取时间 /// public DateTime ReadTime { get; set; } = DateTime.Now; /// /// 数据源配置 /// public ModbusConfiguration? SourceConfiguration { get; set; } /// /// 获取所有数据字段名 /// public IEnumerable FieldNames => _data.Keys; /// /// 获取所有原始寄存器数据 /// public Dictionary? RawRegisters => _rawData?.Count > 0 ? _rawData : null; #endregion #region 数据访问方法 /// /// 设置字段数据 /// /// 字段名 /// 解析后的值 /// 原始寄存器数据 public void SetFieldData(string fieldName, object? value, int[] rawRegisters) { _data[fieldName] = value; // 复制原始寄存器数据以避免引用问题 if (rawRegisters != null) { _rawData[fieldName] = (int[])rawRegisters.Clone(); Console.WriteLine($"[DATA-STORE] 字段 '{fieldName}' 存储: 解析值={value}, 原始=[{string.Join(", ", rawRegisters)}]"); } else { _rawData[fieldName] = Array.Empty(); Console.WriteLine($"[DATA-STORE] 字段 '{fieldName}' 存储: 解析值={value}, 原始数据为null"); } } /// /// 获取字段数据 /// /// 期望的数据类型 /// 字段名 /// 字段值,如果不存在或类型不匹配则返回默认值 public T? GetFieldData(string fieldName) { if (!_data.TryGetValue(fieldName, out var value)) { return default(T); } try { if (value is T typedValue) { return typedValue; } // 尝试类型转换 if (value != null) { return (T)Convert.ChangeType(value, typeof(T)); } } catch { // 转换失败,返回默认值 } return default(T); } /// /// 获取字段的原始数据(未经类型转换) /// /// 字段名 /// 字段值对象 public object? GetFieldValue(string fieldName) { _data.TryGetValue(fieldName, out var value); return value; } /// /// 获取字段的原始寄存器数据 /// /// 字段名 /// 原始寄存器数组,如果不存在则返回空数组 public int[] GetRawData(string fieldName) { return _rawData.TryGetValue(fieldName, out var rawData) ? rawData : Array.Empty(); } /// /// 检查字段是否存在 /// /// 字段名 /// 字段是否存在 public bool HasField(string fieldName) { return _data.ContainsKey(fieldName); } /// /// 获取所有字段数据的字典 /// /// 字段名到值的映射 public Dictionary GetAllFieldData() { return new Dictionary(_data); } #endregion #region 便捷访问方法 /// /// 获取字符串字段 /// public string GetString(string fieldName, string defaultValue = "") { return GetFieldData(fieldName) ?? defaultValue; } /// /// 获取整数字段 /// public int GetInt(string fieldName, int defaultValue = 0) { return GetFieldData(fieldName); } /// /// 获取字节字段 /// public byte GetByte(string fieldName, byte defaultValue = 0) { return GetFieldData(fieldName); } /// /// 获取双精度浮点字段 /// public double GetDouble(string fieldName, double defaultValue = 0.0) { return GetFieldData(fieldName); } /// /// 获取布尔字段 /// public bool GetBool(string fieldName, bool defaultValue = false) { return GetFieldData(fieldName); } /// /// 获取日期时间字段 /// public DateTime GetDateTime(string fieldName, DateTime? defaultValue = null) { return GetFieldData(fieldName) != default ? GetFieldData(fieldName) : (defaultValue ?? DateTime.MinValue); } #endregion #region 调试和诊断方法 /// /// 获取数据摘要(用于调试和日志) /// /// 数据摘要字符串 public string GetDataSummary() { var summary = new List(); foreach (var kvp in _data) { var valueStr = kvp.Value switch { string s => $"\"{s}\"", DateTime dt => dt.ToString("yyyy-MM-dd HH:mm:ss"), double d => d.ToString("F2"), null => "null", _ => kvp.Value.ToString() }; summary.Add($"{kvp.Key}: {valueStr}"); } return string.Join(", ", summary); } /// /// 获取字段详细信息(包含配置信息) /// /// 字段名 /// 字段详细信息 public string GetFieldDetails(string fieldName) { if (!HasField(fieldName)) { return $"字段 '{fieldName}' 不存在"; } var value = GetFieldValue(fieldName); var rawData = GetRawData(fieldName); var config = GetFieldConfiguration(fieldName); var details = new List { $"字段名: {fieldName}", $"显示名: {config?.DisplayName ?? "未知"}", $"数据类型: {config?.DataType ?? "未知"}", $"地址: {config?.Address ?? 0}", $"长度: {config?.Length ?? 0}", $"解析值: {value ?? "null"}", $"原始数据: [{string.Join(", ", rawData)}]" }; return string.Join("\n", details); } /// /// 获取字段配置信息 /// /// 字段名 /// 字段配置,如果不存在则返回null public DataField? GetFieldConfiguration(string fieldName) { if (SourceConfiguration?.InputAddresses == null) return null; // 在各个数据组中查找字段配置 var allFields = new List> { SourceConfiguration.InputAddresses.ControlSignals, SourceConfiguration.InputAddresses.ProductData, SourceConfiguration.InputAddresses.MeasurementData }; foreach (var fieldGroup in allFields) { if (fieldGroup.TryGetValue(fieldName, out var fieldConfig)) { return fieldConfig; } } return null; } #endregion } }