diff --git a/DeviceCommons/AllCodeMerged.txt b/DeviceCommons/AllCodeMerged.txt
index fe3f9e5a83938bdbfcb30da095839e1de83b3570..e0eb44a0785a22b86a787ce989b5b8083623831e 100644
--- a/DeviceCommons/AllCodeMerged.txt
+++ b/DeviceCommons/AllCodeMerged.txt
@@ -2,13 +2,13 @@
==================== Red5 Core Utility Project ====================
项目中所有.cs文件的内容
-生成时间:周五 2025/08/29 15:55:51.59
+生成时间:周日 2025/08/31 18:02:47.54
已过滤的文件后缀:.GlobalUsings.g.cs、.AssemblyInfo.cs、.AssemblyAttributes.cs
====================================================================
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceCommonsOptions.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceCommonsOptions.cs
================================================================
using DeviceCommons.DeviceMessages.Factories;
@@ -84,7 +84,7 @@ namespace DeviceCommons
}
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceCommonsServiceCollectionExtensions.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceCommonsServiceCollectionExtensions.cs
================================================================
using DeviceCommons.DataHandling;
@@ -409,7 +409,7 @@ namespace DeviceCommons
}
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\IDeviceCommonsConfigurationService.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\IDeviceCommonsConfigurationService.cs
================================================================
using Microsoft.Extensions.DependencyInjection;
@@ -596,7 +596,7 @@ namespace DeviceCommons
}
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DataHandling\DeviceMessageArrayPool.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DataHandling\DeviceMessageArrayPool.cs
================================================================
using DeviceCommons.DeviceMessages.Models.V1;
@@ -629,7 +629,7 @@ namespace DeviceCommons.DataHandling
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DataHandling\DeviceMessageSerializerProvider.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DataHandling\DeviceMessageSerializerProvider.cs
================================================================
using DeviceCommons.DeviceMessages.Serialization;
@@ -652,7 +652,7 @@ namespace DeviceCommons.DataHandling
{
var parser = new DeviceMessageParser();
// 配置默认解密函数以保持向后兼容性
- parser.DecryptFunc = cipherText => DeviceMessageUtilities.AES.Decrypt(cipherText, DeviceMessageArrayPool.DefaultAedPassword);
+ parser.DecryptFunc = cipherText => DeviceMessageUtilities.AES.Value.Decrypt(cipherText, DeviceMessageArrayPool.DefaultAedPassword);
return parser;
}
@@ -732,7 +732,7 @@ namespace DeviceCommons.DataHandling
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DataHandling\DeviceMessageSerializerProviderService.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DataHandling\DeviceMessageSerializerProviderService.cs
================================================================
using DeviceCommons.DeviceMessages.Serialization;
@@ -887,13 +887,14 @@ namespace DeviceCommons.DataHandling
}
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DataHandling\DeviceMessageUtilities.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DataHandling\DeviceMessageUtilities.cs
================================================================
-using DeviceCommons.DataHandling.Compression;
+using DeviceCommons.DataHandling.Compression;
using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Models.V1;
using DeviceCommons.Security;
+using DeviceCommons.Validation;
namespace DeviceCommons.DataHandling
{
@@ -901,13 +902,15 @@ namespace DeviceCommons.DataHandling
{
///
/// 优化的AES加密器,使用快速模式和缓存提升性能
+ /// 使用ThreadLocal确保线程安全
///
- public static readonly AesEncryptor AES = AesEncryptor.CreateFastMode();
+ public static readonly ThreadLocal AES = new ThreadLocal(() => new AesEncryptor(true, true));
///
/// 安全模式的AES加密器,用于生产环境
+ /// 使用ThreadLocal确保线程安全
///
- public static readonly AesEncryptor AES_SECURE = AesEncryptor.CreateSecureMode();
+ public static readonly ThreadLocal AES_SECURE = new ThreadLocal(() => new AesEncryptor(false, false));
public static readonly Compressor GZIP = new Compressor();
public static void CheckBuffer(ReadOnlySpan buffer, int startIndex, int requiredLength)
@@ -918,10 +921,20 @@ namespace DeviceCommons.DataHandling
throw new ArgumentOutOfRangeException(nameof(startIndex));
if (buffer.Length - startIndex < requiredLength)
- throw new ArgumentException("Insufficient buffer length");
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InsufficientBufferLength,
+ "缓冲区长度不足,无法读取所需的字节数",
+ nameof(buffer),
+ $"至少需要 {requiredLength} 字节",
+ $"可用 {buffer.Length - startIndex} 字节");
if (buffer.IsEmpty || startIndex < 0 || startIndex >= buffer.Length)
- throw new ArgumentException("Invalid data or startIndex");
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.ByteArrayIndexOutOfRange,
+ "数据索引无效或数据为空",
+ nameof(startIndex),
+ "有效的索引范围",
+ startIndex);
}
public static int GetValueLength(StateValueTypeEnum valueType, ReadOnlySpan data, int startIndex = 0)
@@ -942,7 +955,12 @@ namespace DeviceCommons.DataHandling
return 2;
case StateValueTypeEnum.Binary:
if (data == null || data.Length < startIndex + 2)
- throw new ArgumentException("Invalid data for binary length");
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InvalidBinaryDataFormat,
+ "二进制数据长度字段读取失败,数据不完整",
+ nameof(data),
+ "至少需要2字节的长度字段",
+ $"可用数据长度: {data.Length}");
return BitConverter.ToUInt16(data.ToArray(), startIndex);
case StateValueTypeEnum.Timestamp:
return 8;
@@ -957,7 +975,12 @@ namespace DeviceCommons.DataHandling
{
CheckBuffer(data, startIndex, 0);
if (data[startIndex] > 10)
- throw new ArgumentException("Insufficient buffer length");
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InvalidEnumValue,
+ "状态值类型枚举值超出有效范围",
+ nameof(data),
+ "StateValueTypeEnum值(0-10)",
+ data[startIndex]);
var valueType = (StateValueTypeEnum)data[startIndex];
@@ -990,7 +1013,7 @@ namespace DeviceCommons.DataHandling
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DataHandling\Compression\Compressor.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DataHandling\Compression\Compressor.cs
================================================================
using System.IO.Compression;
@@ -1055,7 +1078,7 @@ namespace DeviceCommons.DataHandling.Compression
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessage.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessage.cs
================================================================
using DeviceCommons.DeviceMessages.Models;
@@ -1070,7 +1093,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessageParser.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessageParser.cs
================================================================
using DeviceCommons.DataHandling;
@@ -1121,12 +1144,12 @@ namespace DeviceCommons.DeviceMessages.Abstractions
else if (!string.IsNullOrEmpty(password))
{
// 使用提供的密码进行AES解密
- dataTemp = DeviceMessageUtilities.AES.Decrypt(dataTemp, password);
+ dataTemp = DeviceMessageUtilities.AES.Value.Decrypt(dataTemp, password);
}
else
{
// 使用默认密码进行AES解密
- dataTemp = DeviceMessageUtilities.AES.Decrypt(dataTemp, DeviceMessageArrayPool.DefaultAedPassword);
+ dataTemp = DeviceMessageUtilities.AES.Value.Decrypt(dataTemp, DeviceMessageArrayPool.DefaultAedPassword);
}
}
@@ -1174,12 +1197,12 @@ namespace DeviceCommons.DeviceMessages.Abstractions
else if (!string.IsNullOrEmpty(password))
{
// 使用提供的密码进行AES解密
- dataTemp = await Task.Run(() => DeviceMessageUtilities.AES.Decrypt(dataTemp, password), cancellationToken).ConfigureAwait(false);
+ dataTemp = await Task.Run(() => DeviceMessageUtilities.AES.Value.Decrypt(dataTemp, password), cancellationToken).ConfigureAwait(false);
}
else
{
// 使用默认密码进行AES解密
- dataTemp = await Task.Run(() => DeviceMessageUtilities.AES.Decrypt(dataTemp, DeviceMessageArrayPool.DefaultAedPassword), cancellationToken).ConfigureAwait(false);
+ dataTemp = await Task.Run(() => DeviceMessageUtilities.AES.Value.Decrypt(dataTemp, DeviceMessageArrayPool.DefaultAedPassword), cancellationToken).ConfigureAwait(false);
}
}
@@ -1220,7 +1243,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessageSerializer.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\AbstractMessageSerializer.cs
================================================================
using DeviceCommons.DataHandling;
@@ -1311,12 +1334,12 @@ namespace DeviceCommons.DeviceMessages.Abstractions
else if (!string.IsNullOrEmpty(encryptionPassword))
{
// 使用提供的密码进行AES加密
- hex = DeviceMessageUtilities.AES.Encrypt(hex, encryptionPassword);
+ hex = DeviceMessageUtilities.AES.Value.Encrypt(hex, encryptionPassword);
}
else
{
// 使用默认密码
- hex = DeviceMessageUtilities.AES.Encrypt(hex, DeviceMessageArrayPool.DefaultAedPassword);
+ hex = DeviceMessageUtilities.AES.Value.Encrypt(hex, DeviceMessageArrayPool.DefaultAedPassword);
}
}
return header + hex;
@@ -1389,12 +1412,12 @@ namespace DeviceCommons.DeviceMessages.Abstractions
else if (!string.IsNullOrEmpty(encryptionPassword))
{
// 使用提供的密码进行AES加密
- hex = await Task.Run(() => DeviceMessageUtilities.AES.Encrypt(hex, encryptionPassword), cancellationToken).ConfigureAwait(false);
+ hex = await Task.Run(() => DeviceMessageUtilities.AES.Value.Encrypt(hex, encryptionPassword), cancellationToken).ConfigureAwait(false);
}
else
{
// 使用默认密码
- hex = await Task.Run(() => DeviceMessageUtilities.AES.Encrypt(hex, DeviceMessageArrayPool.DefaultAedPassword), cancellationToken).ConfigureAwait(false);
+ hex = await Task.Run(() => DeviceMessageUtilities.AES.Value.Encrypt(hex, DeviceMessageArrayPool.DefaultAedPassword), cancellationToken).ConfigureAwait(false);
}
}
return header + hex;
@@ -1435,7 +1458,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessageParser.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessageParser.cs
================================================================
namespace DeviceCommons.DeviceMessages.Abstractions
@@ -1460,7 +1483,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessagePayload.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessagePayload.cs
================================================================
namespace DeviceCommons.DeviceMessages.Abstractions
@@ -1472,7 +1495,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessageSerializer.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Abstractions\IMessageSerializer.cs
================================================================
using DeviceCommons.DeviceMessages.Models;
@@ -1510,7 +1533,7 @@ namespace DeviceCommons.DeviceMessages.Abstractions
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceInfoBuilder.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceInfoBuilder.cs
================================================================
using DeviceCommons.DeviceMessages.Models;
@@ -1558,10 +1581,10 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceInfoReadingBuilder.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceInfoReadingBuilder.cs
================================================================
-using DeviceCommons.DeviceMessages.Enums;
+using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Factories;
using DeviceCommons.DeviceMessages.Models.V1;
using DeviceCommons.Validation;
@@ -1617,7 +1640,12 @@ namespace DeviceCommons.DeviceMessages.Builders
double => StateValueTypeEnum.Double,
bool => StateValueTypeEnum.Bool,
ulong => StateValueTypeEnum.Timestamp,
- _ => throw new ArgumentException($"不支持的值类型:{value.GetType().Name}", nameof(value))
+ _ => throw new DeviceMessageValidationException(
+ ValidationErrorType.ValueTypeConversionFailed,
+ $"不支持的值类型,无法推断 StateValueTypeEnum: {value.GetType().Name}",
+ nameof(value),
+ "可支持的类型: string, byte[], int, short, ushort, float, double, bool, ulong",
+ value.GetType().Name)
};
}
@@ -1633,7 +1661,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceMessageBuilder.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Builders\DeviceMessageBuilder.cs
================================================================
using DeviceCommons.DataHandling;
@@ -1683,8 +1711,12 @@ namespace DeviceCommons.DeviceMessages.Builders
///
public DeviceMessageBuilder()
{
- _serializer = DeviceMessageSerializerProvider.MessageSer;
- _parser = DeviceMessageSerializerProvider.MessagePar;
+ // 为每个实例创建独立的序列化器和解析器,避免静态状态污染
+ _serializer = new DeviceMessageSerializer();
+ _parser = new DeviceMessageParser();
+
+ // 配置默认解密函数
+ _parser.DecryptFunc = cipherText => DeviceMessageUtilities.AES.Value.Decrypt(cipherText, DeviceMessageArrayPool.DefaultAedPassword);
}
private void ApplyConfiguration()
@@ -1841,8 +1873,8 @@ namespace DeviceCommons.DeviceMessages.Builders
DeviceMessageValidator.ValidatePassword(password, nameof(password));
return WithEncryption(
- plainText => DeviceMessageUtilities.AES.Encrypt(plainText, password),
- cipherText => DeviceMessageUtilities.AES.Decrypt(cipherText, password)
+ plainText => DeviceMessageUtilities.AES.Value.Encrypt(plainText, password),
+ cipherText => DeviceMessageUtilities.AES.Value.Decrypt(cipherText, password)
);
}
@@ -1852,7 +1884,7 @@ namespace DeviceCommons.DeviceMessages.Builders
/// 加密密码
/// AES加密模式(快速模式或安全模式)
/// 当前构建器实例
- public IDeviceMessageBuilder WithAesEncryption(string password, AesMode mode)
+ public IDeviceMessageBuilder WithAesEncryption(string? password, AesMode mode)
{
// 前置验证密码
DeviceMessageValidator.ValidatePassword(password, nameof(password));
@@ -2117,7 +2149,160 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Builders\IDeviceMessageBuilder.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Builders\EnhancedDeviceMessageBuilder.cs
+================================================================
+
+using DeviceCommons.DeviceMessages.Factories;
+using DeviceCommons.DeviceMessages.Models.V1;
+using DeviceCommons.DeviceMessages.Enums;
+
+namespace DeviceCommons.DeviceMessages.Builders
+{
+ ///
+ /// 增强的设备消息构建器
+ /// 能够自动根据设备类型的状态配置来创建状态
+ ///
+ public class EnhancedDeviceMessageBuilder : DeviceMessageBuilder
+ {
+ private byte _currentDeviceType;
+
+ ///
+ /// 重写WithMainDevice方法以记录设备类型
+ ///
+ public new EnhancedDeviceMessageBuilder WithMainDevice(string did, byte deviceType)
+ {
+ _currentDeviceType = deviceType;
+ base.WithMainDevice(did, deviceType);
+ return this;
+ }
+
+ ///
+ /// 重写WithMainDevice方法以记录设备类型
+ ///
+ public new EnhancedDeviceMessageBuilder WithMainDevice(string did, byte deviceType, Action config)
+ {
+ _currentDeviceType = deviceType;
+ base.WithMainDevice(did, deviceType, config);
+ return this;
+ }
+
+ ///
+ /// 使用设备状态配置添加读数
+ ///
+ /// 时间偏移
+ /// 状态值元组数组:(sid, value)
+ /// 构建器实例
+ public EnhancedDeviceMessageBuilder AddReadingWithConfiguration(short timeOffset, params (byte sid, object value)[] stateValues)
+ {
+ // 获取设备状态配置
+ var configuration = DeviceStateConfigurationRegistry.GetConfiguration(_currentDeviceType);
+ if (configuration == null)
+ {
+ throw new InvalidOperationException($"设备类型 {_currentDeviceType} 没有注册状态配置");
+ }
+
+ // 验证状态完整性
+ var providedSids = stateValues.Select(sv => sv.sid);
+ var (isValid, missingStates) = configuration.ValidateStateCompleteness(providedSids);
+
+ if (!isValid)
+ {
+ var missingStatesList = string.Join(", ", missingStates);
+ throw new InvalidOperationException($"设备类型 {_currentDeviceType} 缺少必需的状态: {missingStatesList}");
+ }
+
+ // 使用配置创建状态
+ var factory = DeviceStateConfigurationRegistry.GetFactory(_currentDeviceType);
+ if (factory is ConfigurableStateFactory configurableFactory)
+ {
+ var states = configurableFactory.CreateStatesFromValues(stateValues);
+
+ // 使用基类的方法添加读数
+ AddReading(timeOffset, reading =>
+ {
+ foreach (var state in states.StateArray)
+ {
+ reading.AddState(state.SID, state.ValueText, state.ValueType);
+ }
+ });
+ }
+ else
+ {
+ // 回退到默认实现
+ AddReading(timeOffset, stateValues.Select(sv => (sv.sid, sv.value, (StateValueTypeEnum?)null)).ToArray());
+ }
+
+ return this;
+ }
+
+ ///
+ /// 使用设备状态配置添加读数(使用字典)
+ ///
+ /// 时间偏移
+ /// 状态值字典
+ /// 构建器实例
+ public EnhancedDeviceMessageBuilder AddReadingWithConfiguration(short timeOffset, Dictionary stateValues)
+ {
+ var stateValuesArray = stateValues.Select(kv => (kv.Key, kv.Value)).ToArray();
+ return AddReadingWithConfiguration(timeOffset, stateValuesArray);
+ }
+
+ ///
+ /// 使用设备状态配置添加读数(自动填充默认值)
+ ///
+ /// 时间偏移
+ /// 状态值元组数组:(sid, value),可选值
+ /// 构建器实例
+ public EnhancedDeviceMessageBuilder AddReadingWithDefaults(short timeOffset, params (byte sid, object value)[] stateValues)
+ {
+ var configuration = DeviceStateConfigurationRegistry.GetConfiguration(_currentDeviceType);
+ if (configuration == null)
+ {
+ throw new InvalidOperationException($"设备类型 {_currentDeviceType} 没有注册状态配置");
+ }
+
+ // 创建包含所有必需状态的状态集合
+ var factory = DeviceStateConfigurationRegistry.GetFactory(_currentDeviceType);
+ if (factory is ConfigurableStateFactory configurableFactory)
+ {
+ var states = configurableFactory.CreateStatesFromValues(stateValues);
+
+ AddReading(timeOffset, reading =>
+ {
+ foreach (var state in states.StateArray)
+ {
+ reading.AddState(state.SID, state.ValueText, state.ValueType);
+ }
+ });
+ }
+
+ return this;
+ }
+
+ ///
+ /// 验证设备类型是否已注册状态配置
+ ///
+ /// 设备类型
+ /// 是否已注册
+ public static bool IsDeviceTypeConfigured(byte deviceType)
+ {
+ return DeviceStateConfigurationRegistry.IsRegistered(deviceType);
+ }
+
+ ///
+ /// 获取设备类型的状态配置信息
+ ///
+ /// 设备类型
+ /// 状态配置信息
+ public static IDeviceStateConfiguration? GetDeviceConfiguration(byte deviceType)
+ {
+ return DeviceStateConfigurationRegistry.GetConfiguration(deviceType);
+ }
+ }
+}
+
+================================================================
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Builders\IDeviceMessageBuilder.cs
================================================================
using DeviceCommons.DeviceMessages.Enums;
@@ -2217,7 +2402,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\CRCTypeEnum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\CRCTypeEnum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2232,7 +2417,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\HeaderValueTypeEnum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\HeaderValueTypeEnum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2245,7 +2430,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\MarkEnum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\MarkEnum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2275,7 +2460,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\Reserve1Enum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\Reserve1Enum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2288,7 +2473,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\Reserve2Enum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\Reserve2Enum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2301,7 +2486,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\StateValueTypeEnum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\StateValueTypeEnum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2321,7 +2506,7 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Enums\TimeStampFormatEnum.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Enums\TimeStampFormatEnum.cs
================================================================
namespace DeviceCommons.DeviceMessages.Enums
@@ -2334,7 +2519,154 @@ namespace DeviceCommons.DeviceMessages.Builders
}
================================================================
-文件路径: F:\ProductionProject\device-commons\DeviceCommons\DeviceMessages\Factories\DefaultStateFactory.cs
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Factories\ConfigurableStateFactory.cs
+================================================================
+
+using DeviceCommons.DeviceMessages.Enums;
+using DeviceCommons.DeviceMessages.Models.V1;
+
+namespace DeviceCommons.DeviceMessages.Factories
+{
+ ///
+ /// 可配置的状态工厂
+ /// 根据设备状态配置自动创建状态
+ ///
+ public class ConfigurableStateFactory : IStateFactory
+ {
+ private readonly IDeviceStateConfiguration _configuration;
+
+ public ConfigurableStateFactory(IDeviceStateConfiguration configuration)
+ {
+ _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
+ }
+
+ public IDeviceMessageInfoReadingState CreateState(byte sid, object value, StateValueTypeEnum? valueType = null)
+ {
+ // 获取状态定义
+ var stateDef = _configuration.GetStateDefinition(sid);
+ if (stateDef == null)
+ {
+ throw new ArgumentException($"未找到设备类型 {_configuration.DeviceType} 的状态ID {sid} 的定义");
+ }
+
+ // 验证状态值
+ if (!_configuration.ValidateStateValue(sid, value))
+ {
+ throw new ArgumentException($"状态ID {sid} 的值 {value} 验证失败");
+ }
+
+ // 使用配置中定义的值类型,如果没有提供的话
+ var actualValueType = valueType ?? stateDef.ValueType;
+
+ return new DeviceMessageInfoReadingState
+ {
+ SID = sid,
+ ValueType = actualValueType,
+ ValueText = value,
+ Metadata = stateDef.Name // 可选:将状态名称作为元数据
+ };
+ }
+
+ public IDeviceMessageInfoReadingStates CreateStates(params StateValueTypeEnum[] types)
+ {
+ var states = new List();
+
+ foreach (var stateDef in _configuration.StateDefinitions)
+ {
+ // 使用默认值或创建空状态
+ var value = stateDef.DefaultValue ?? GetDefaultValueForType(stateDef.ValueType);
+ var state = CreateState(stateDef.Sid, value, stateDef.ValueType);
+ states.Add(state);
+ }
+
+ return new DeviceMessageInfoReadingStates
+ {
+ StateArray = states.ToArray()
+ };
+ }
+
+ ///
+ /// 根据状态定义创建完整的状态集合
+ ///
+ /// 状态值字典,键为状态ID,值为状态值
+ /// 状态集合
+ public IDeviceMessageInfoReadingStates CreateStatesFromValues(Dictionary values)
+ {
+ var states = new List();
+
+ foreach (var stateDef in _configuration.StateDefinitions)
+ {
+ if (values.TryGetValue(stateDef.Sid, out var value))
+ {
+ // 使用提供的值
+ var state = CreateState(stateDef.Sid, value, stateDef.ValueType);
+ states.Add(state);
+ }
+ else if (stateDef.IsRequired)
+ {
+ // 必需状态但没有提供值,使用默认值
+ var defaultValue = stateDef.DefaultValue ?? GetDefaultValueForType(stateDef.ValueType);
+ var state = CreateState(stateDef.Sid, defaultValue, stateDef.ValueType);
+ states.Add(state);
+ }
+ // 非必需状态且没有提供值,跳过
+ }
+
+ return new DeviceMessageInfoReadingStates
+ {
+ StateArray = states.ToArray()
+ };
+ }
+
+ ///
+ /// 根据状态定义创建完整的状态集合(使用参数数组)
+ ///
+ /// 状态值元组数组:(sid, value)
+ /// 状态集合
+ public IDeviceMessageInfoReadingStates CreateStatesFromValues(params (byte sid, object value)[] stateValues)
+ {
+ var values = stateValues.ToDictionary(sv => sv.sid, sv => sv.value);
+ return CreateStatesFromValues(values);
+ }
+
+ ///
+ /// 获取类型的默认值
+ ///
+ /// 值类型
+ /// 默认值
+ private object GetDefaultValueForType(StateValueTypeEnum valueType)
+ {
+ return valueType switch
+ {
+ StateValueTypeEnum.String => string.Empty,
+ StateValueTypeEnum.Int32 => 0,
+ StateValueTypeEnum.Int16 => (short)0,
+ StateValueTypeEnum.UInt16 => (ushort)0,
+ StateValueTypeEnum.Float32 => 0.0f,
+ StateValueTypeEnum.Double => 0.0,
+ StateValueTypeEnum.Bool => false,
+ StateValueTypeEnum.Binary => Array.Empty(),
+ StateValueTypeEnum.Timestamp => 0UL,
+ _ => string.Empty
+ };
+ }
+
+ ///
+ /// 验证提供的状态值是否完整
+ ///
+ /// 提供的状态ID集合
+ /// 验证结果
+ public (bool IsValid, IEnumerable MissingStates) ValidateStateCompleteness(IEnumerable providedSids)
+ {
+ var missingStates = _configuration.GetMissingRequiredStates(providedSids);
+ var isValid = !missingStates.Any();
+ return (isValid, missingStates);
+ }
+ }
+}
+
+================================================================
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Factories\DefaultStateFactory.cs
================================================================
using DeviceCommons.DeviceMessages.Enums;
@@ -2353,11 +2685,1293 @@ namespace DeviceCommons.DeviceMessages.Factories
ValueText = value
};
}
+
+ public IDeviceMessageInfoReadingStates CreateStates(params StateValueTypeEnum[] types)
+ {
+ return new DeviceMessageInfoReadingStates()
+ {
+ StateArray = new IDeviceMessageInfoReadingState[]
+ {
+ CreateState("PLC",1,0d),
+ CreateState("PLC",2,0),
+ CreateState(3,true)
+ }
+ };
+ }
+
+ public IDeviceMessageInfoReadingState CreateState(string metadata, byte sid, object value, StateValueTypeEnum? valueType = null)
+ {
+ IDeviceMessageInfoReadingState state = CreateState(sid, value, valueType);
+ state.Metadata = metadata;
+ return state;
+ }
+ }
+}
+
+================================================================
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Factories\DeviceMessageProcessor.cs
+================================================================
+
+using DeviceCommons.DataHandling;
+using DeviceCommons.DeviceMessages.Abstractions;
+using DeviceCommons.DeviceMessages.Builders;
+using DeviceCommons.DeviceMessages.Models.V1;
+using DeviceCommons.DeviceMessages.Serialization;
+using DeviceCommons.Exceptions;
+using DeviceCommons.Validation;
+using System.Buffers;
+
+namespace DeviceCommons.DeviceMessages.Factories
+{
+ ///
+ /// 设备消息处理器
+ /// 提供简化的API接口,降低使用复杂度
+ ///
+ public class DeviceMessageProcessor
+ {
+ private readonly IDeviceMessageParser _parser;
+ private readonly IDeviceMessageSerializer _serializer;
+
+ public DeviceMessageProcessor()
+ {
+ _parser = DeviceMessageSerializerProvider.MessagePar;
+ _serializer = DeviceMessageSerializerProvider.MessageSer;
+ }
+
+ ///
+ /// 注册设备类型配置
+ ///
+ /// 设备类型
+ /// 配置构建器
+ /// 处理器实例(支持链式调用)
+ public DeviceMessageProcessor RegisterDeviceType(byte deviceType, Action configuration)
+ {
+ try
+ {
+ DeviceStateConfigurationRegistry.RegisterConfiguration(deviceType, configuration);
+ return this;
+ }
+ catch (Exception ex)
+ {
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InvalidConfiguration,
+ $"注册设备类型 {deviceType} 失败: {ex.Message}",
+ nameof(deviceType),
+ "有效的设备类型配置",
+ ex.Message);
+ }
+ }
+
+ ///
+ /// 解析设备消息
+ ///
+ /// 十六进制字符串
+ /// 是否启用快速解析
+ /// 解析后的设备消息
+ public IDeviceMessage ParseMessage(string hexString, bool enableFastParsing = true)
+ {
+ try
+ {
+ // 验证输入
+ if (string.IsNullOrEmpty(hexString))
+ {
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InvalidInput,
+ "消息字符串不能为空",
+ nameof(hexString),
+ "有效的十六进制字符串",
+ "null 或空字符串");
+ }
+
+ // 转换十六进制字符串
+ var bytes = ConvertHexStringToBytes(hexString);
+
+ // 设置解析上下文
+ var context = ParsingContext.Create();
+ context.EnableFastParsing = enableFastParsing;
+
+ if (_parser is IContextAwareParser contextAwareParser)
+ {
+ contextAwareParser.SetContext(context);
+ }
+
+ // 解析消息
+ return _parser.Parser(bytes);
+ }
+ catch (DeviceMessageValidationException)
+ {
+ throw; // 重新抛出验证异常
+ }
+ catch (Exception ex)
+ {
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.ParsingFailed,
+ $"消息解析失败: {ex.Message}",
+ nameof(hexString),
+ "有效的设备消息格式",
+ ex.Message);
+ }
+ }
+
+ ///
+ /// 序列化设备消息
+ ///
+ /// 设备消息
+ /// 十六进制字符串
+ public string SerializeMessage(IDeviceMessage message)
+ {
+ try
+ {
+ // 验证输入
+ if (message == null)
+ {
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.InvalidInput,
+ "设备消息不能为空",
+ nameof(message),
+ "有效的设备消息对象",
+ "null");
+ }
+
+ // 序列化消息
+ var buffer = new ArrayBufferWriter();
+ var hexString = _serializer.Serializer(buffer, message, isEncrypt: false, isCompress: false);
+ return hexString;
+ }
+ catch (DeviceMessageValidationException)
+ {
+ throw; // 重新抛出验证异常
+ }
+ catch (Exception ex)
+ {
+ throw new DeviceMessageValidationException(
+ ValidationErrorType.SerializationFailed,
+ $"消息序列化失败: {ex.Message}",
+ nameof(message),
+ "有效的设备消息对象",
+ ex.Message);
+ }
+ }
+
+ ///
+ /// 创建设备消息构建器
+ ///
+ /// 设备消息构建器
+ public IDeviceMessageBuilder CreateMessage()
+ {
+ return DeviceMessageBuilder.Create();
+ }
+
+ ///
+ /// 获取注册的设备类型统计
+ ///
+ /// 统计信息
+ public (int TotalDeviceTypes, int TotalStates) GetStatistics()
+ {
+ return DeviceStateConfigurationRegistry.GetStatistics();
+ }
+
+ ///
+ /// 检查设备类型是否已注册
+ ///
+ /// 设备类型
+ /// 是否已注册
+ public bool IsDeviceTypeRegistered(byte deviceType)
+ {
+ return DeviceStateConfigurationRegistry.IsRegistered(deviceType);
+ }
+
+ ///
+ /// 获取设备类型配置
+ ///
+ /// 设备类型
+ /// 设备配置
+ public IDeviceStateConfiguration? GetDeviceConfiguration(byte deviceType)
+ {
+ return DeviceStateConfigurationRegistry.GetConfiguration(deviceType);
+ }
+
+ ///
+ /// 验证设备消息格式
+ ///
+ /// 十六进制字符串
+ /// 验证结果
+ public (bool IsValid, string? ErrorMessage) ValidateMessageFormat(string hexString)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(hexString))
+ {
+ return (false, "消息字符串不能为空");
+ }
+
+ var bytes = ConvertHexStringToBytes(hexString);
+ DeviceMessageValidator.ValidateMessageData(bytes, nameof(hexString));
+ return (true, null);
+ }
+ catch (Exception ex)
+ {
+ return (false, ex.Message);
+ }
+ }
+
+ ///
+ /// 转换十六进制字符串为字节数组
+ ///
+ /// 十六进制字符串
+ /// 字节数组
+ private static byte[] ConvertHexStringToBytes(string hexString)
+ {
+ // 移除空格和前缀
+ hexString = hexString.Replace(" ", "").Replace("0x", "").Replace("0X", "");
+
+ // 处理 dec,raw| 前缀
+ if (hexString.StartsWith("dec,raw|"))
+ {
+ hexString = hexString.Substring("dec,raw|".Length);
+ }
+
+ if (hexString.Length % 2 != 0)
+ {
+ throw new ArgumentException("十六进制字符串长度必须为偶数");
+ }
+
+ var bytes = new byte[hexString.Length / 2];
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
+ }
+ return bytes;
+ }
+
+ ///
+ /// 转换字节数组为十六进制字符串
+ ///
+ /// 字节数组
+ /// 十六进制字符串
+ private static string ConvertBytesToHexString(ReadOnlySpan bytes)
+ {
+ return BitConverter.ToString(bytes.ToArray()).Replace("-", "");
+ }
+ }
+}
+
+================================================================
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Factories\DeviceStateConfiguration.cs
+================================================================
+
+using DeviceCommons.DeviceMessages.Enums;
+
+namespace DeviceCommons.DeviceMessages.Factories
+{
+ ///
+ /// 设备状态配置实现
+ ///
+ public class DeviceStateConfiguration : IDeviceStateConfiguration
+ {
+ private readonly Dictionary _stateDefinitionMap;
+
+ public DeviceStateConfiguration(byte deviceType, IEnumerable stateDefinitions)
+ {
+ DeviceType = deviceType;
+ StateDefinitions = stateDefinitions.ToList().AsReadOnly();
+
+ // 创建状态ID到定义的映射,提高查找效率
+ _stateDefinitionMap = StateDefinitions.ToDictionary(sd => sd.Sid);
+ }
+
+ public byte DeviceType { get; }
+
+ public IReadOnlyList StateDefinitions { get; }
+
+ public StateDefinition? GetStateDefinition(byte sid)
+ {
+ return _stateDefinitionMap.TryGetValue(sid, out var definition) ? definition : null;
+ }
+
+ public bool ValidateStateValue(byte sid, object value)
+ {
+ var definition = GetStateDefinition(sid);
+ if (definition == null)
+ return false;
+
+ // 基本类型验证
+ if (!IsValueTypeCompatible(value, definition.ValueType))
+ return false;
+
+ // 自定义验证规则
+ if (definition.ValidationRule != null && !definition.ValidationRule(value))
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// 检查值类型是否兼容
+ ///
+ /// 值
+ /// 期望的类型
+ /// 是否兼容
+ private bool IsValueTypeCompatible(object value, StateValueTypeEnum expectedType)
+ {
+ if (value == null)
+ return false;
+
+ return expectedType switch
+ {
+ StateValueTypeEnum.String => value is string,
+ StateValueTypeEnum.Int32 => value is int,
+ StateValueTypeEnum.Int16 => value is short,
+ StateValueTypeEnum.UInt16 => value is ushort,
+ StateValueTypeEnum.Float32 => value is float,
+ StateValueTypeEnum.Double => value is double,
+ StateValueTypeEnum.Bool => value is bool,
+ StateValueTypeEnum.Binary => value is byte[],
+ StateValueTypeEnum.Timestamp => value is ulong,
+ _ => false
+ };
+ }
+
+ ///
+ /// 获取必需的状态定义
+ ///
+ /// 必需的状态定义列表
+ public IEnumerable GetRequiredStates()
+ {
+ return StateDefinitions.Where(sd => sd.IsRequired);
+ }
+
+ ///
+ /// 检查是否包含所有必需的状态
+ ///
+ /// 提供的状态ID集合
+ /// 是否包含所有必需状态
+ public bool ContainsAllRequiredStates(IEnumerable providedSids)
+ {
+ var requiredSids = GetRequiredStates().Select(sd => sd.Sid).ToHashSet();
+ var providedSidsSet = providedSids.ToHashSet();
+ return requiredSids.IsSubsetOf(providedSidsSet);
+ }
+
+ ///
+ /// 获取缺失的必需状态
+ ///
+ /// 提供的状态ID集合
+ /// 缺失的必需状态ID列表
+ public IEnumerable GetMissingRequiredStates(IEnumerable providedSids)
+ {
+ var requiredSids = GetRequiredStates().Select(sd => sd.Sid).ToHashSet();
+ var providedSidsSet = providedSids.ToHashSet();
+ return requiredSids.Except(providedSidsSet);
+ }
+
+ ///
+ /// 验证状态完整性
+ ///
+ /// 提供的状态ID集合
+ /// 验证结果
+ public (bool IsValid, IEnumerable MissingStates) ValidateStateCompleteness(IEnumerable providedSids)
+ {
+ var missingStates = GetMissingRequiredStates(providedSids);
+ var isValid = !missingStates.Any();
+ return (isValid, missingStates);
+ }
+ }
+}
+
+================================================================
+文件路径: C:\Users\Rabid\Documents\device-commons\device-commons\DeviceCommons\DeviceMessages\Factories\DeviceStateConfigurationBuilder.cs
+================================================================
+
+using DeviceCommons.DeviceMessages.Enums;
+
+namespace DeviceCommons.DeviceMessages.Factories
+{
+ ///
+ /// 设备状态配置构建器
+ /// 提供流畅的API来定义设备状态配置
+ ///
+ public class DeviceStateConfigurationBuilder
+ {
+ private readonly byte _deviceType;
+ private readonly List _stateDefinitions = new();
+
+ public DeviceStateConfigurationBuilder(byte deviceType)
+ {
+ _deviceType = deviceType;
+ }
+
+ ///
+ /// 添加状态定义
+ ///
+ /// 状态ID
+ /// 值类型
+ /// 状态名称(可选)
+ /// 状态描述(可选)
+ /// 是否必需
+ /// 默认值(可选)
+ /// 验证规则(可选)
+ /// 构建器实例
+ public DeviceStateConfigurationBuilder AddState(
+ byte sid,
+ StateValueTypeEnum valueType,
+ string? name = null,
+ string? description = null,
+ bool isRequired = true,
+ object? defaultValue = null,
+ Func