diff --git a/JiShe.CollectBus.sln b/JiShe.CollectBus.sln index f02dd6e..272514c 100644 --- a/JiShe.CollectBus.sln +++ b/JiShe.CollectBus.sln @@ -66,6 +66,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Analyzers. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Analyzers", "modules\JiShe.CollectBus.Analyzers\JiShe.CollectBus.Analyzers.csproj", "{EB97C7BB-1E4A-CBA4-04C1-22DBF48A253A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Migration.Application.Contracts", "services\JiShe.CollectBus.Migration.Application.Contracts\JiShe.CollectBus.Migration.Application.Contracts.csproj", "{E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Migration.Application", "services\JiShe.CollectBus.Migration.Application\JiShe.CollectBus.Migration.Application.csproj", "{B955C5DA-3C20-35D2-0770-8FE473C41C44}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Migration.Host", "web\JiShe.CollectBus.Migration.Host\JiShe.CollectBus.Migration.Host.csproj", "{995D3D91-7221-D4A3-A7B2-FEC202328A18}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Migration.HttpApi", "web\JiShe.CollectBus.Migration.HttpApi\JiShe.CollectBus.Migration.HttpApi.csproj", "{8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -160,6 +168,22 @@ Global {EB97C7BB-1E4A-CBA4-04C1-22DBF48A253A}.Debug|Any CPU.Build.0 = Debug|Any CPU {EB97C7BB-1E4A-CBA4-04C1-22DBF48A253A}.Release|Any CPU.ActiveCfg = Release|Any CPU {EB97C7BB-1E4A-CBA4-04C1-22DBF48A253A}.Release|Any CPU.Build.0 = Release|Any CPU + {E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A}.Release|Any CPU.Build.0 = Release|Any CPU + {B955C5DA-3C20-35D2-0770-8FE473C41C44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B955C5DA-3C20-35D2-0770-8FE473C41C44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B955C5DA-3C20-35D2-0770-8FE473C41C44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B955C5DA-3C20-35D2-0770-8FE473C41C44}.Release|Any CPU.Build.0 = Release|Any CPU + {995D3D91-7221-D4A3-A7B2-FEC202328A18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {995D3D91-7221-D4A3-A7B2-FEC202328A18}.Debug|Any CPU.Build.0 = Debug|Any CPU + {995D3D91-7221-D4A3-A7B2-FEC202328A18}.Release|Any CPU.ActiveCfg = Release|Any CPU + {995D3D91-7221-D4A3-A7B2-FEC202328A18}.Release|Any CPU.Build.0 = Release|Any CPU + {8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -187,6 +211,10 @@ Global {75B7D419-C261-577D-58D6-AA3ACED9129F} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} {DD68F314-BC66-5601-B094-B1A7BE93F4E0} = {EBF7C01F-9B4F-48E6-8418-2CBFDA51EB0B} {EB97C7BB-1E4A-CBA4-04C1-22DBF48A253A} = {2E0FE301-34C3-4561-9CAE-C7A9E65AEE59} + {E01625B5-B5B7-7A4B-468F-EC12C1BDBA2A} = {BA4DA3E7-9AD0-47AD-A0E6-A0BB6700DA23} + {B955C5DA-3C20-35D2-0770-8FE473C41C44} = {BA4DA3E7-9AD0-47AD-A0E6-A0BB6700DA23} + {995D3D91-7221-D4A3-A7B2-FEC202328A18} = {A02F7D8A-04DC-44D6-94D4-3F65712D6B94} + {8A113DE5-7D50-6E6B-739F-B6EEAD5E13B4} = {A02F7D8A-04DC-44D6-94D4-3F65712D6B94} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs index 9212cda..00a7129 100644 --- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs +++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs @@ -577,19 +577,43 @@ namespace JiShe.CollectBus.IncrementalGenerator var elementDeclaredName = element.Type.Name;//元组元素类型名称 initializerLines.Add( - $"new EntityMemberInfo(" + - $"\"{prop.Name}.{elementName}\", " + - $"typeof({elementType}), " + - $"typeof({elementType}).Name, " +//$"\"{elementDeclaredName}\", " + - $"(e) => Get{prop.Name}_{elementName}(({entityType})e), " + - $"(e, v) => Set{prop.Name}_{elementName}(({entityType})e, ({elementType})v))"); - } - } - } + $"new EntityMemberInfo(" + + $"\"{prop.Name}.{elementName}\", " + + $"typeof({elementType}), " + + $"GetValueTupleElementDeclaredTypeName(typeof({elementType})), " +//$"\"{elementDeclaredName}\", " + + $"(e) => Get{prop.Name}_{elementName}(({entityType})e), " + + $"(e, v) => Set{prop.Name}_{elementName}(({entityType})e, ({elementType})v))"); + } + } + } - code.AppendLine(string.Join(",\n", initializerLines)); - code.AppendLine(" };"); - } + code.AppendLine(string.Join(",\n", initializerLines)); + code.AppendLine(" };"); + + code.AppendLine(GetValueTupleElementName()); + } + + private static string GetValueTupleElementName() + { + return """ + public static string GetValueTupleElementDeclaredTypeName(Type declaredType) + { + string typeName; + // 处理可空类型 + if (declaredType.IsGenericType && declaredType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + Type underlyingType = Nullable.GetUnderlyingType(declaredType); + typeName = underlyingType.Name; + } + else + { + typeName = declaredType.Name; + } + + return typeName; + } + """; + } private static string GenerateAttributeInitializer(AttributeData attribute) diff --git a/modules/JiShe.CollectBus.IoTDB/Context/IoTDBRuntimeContext.cs b/modules/JiShe.CollectBus.IoTDB/Context/IoTDBRuntimeContext.cs index ef68325..7384716 100644 --- a/modules/JiShe.CollectBus.IoTDB/Context/IoTDBRuntimeContext.cs +++ b/modules/JiShe.CollectBus.IoTDB/Context/IoTDBRuntimeContext.cs @@ -7,7 +7,7 @@ namespace JiShe.CollectBus.IoTDB.Context /// /// IoTDB SessionPool 运行时上下文 /// - public class IoTDBRuntimeContext: IScopedDependency + public class IoTDBRuntimeContext: IScopedDependency//ITransientDependency { private readonly bool _defaultValue; diff --git a/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs index 82a0d47..a5d885d 100644 --- a/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs +++ b/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs @@ -16,6 +16,8 @@ namespace JiShe.CollectBus.IoTDB.Interface ///// 是否使用表模型 //void SwitchSessionPool(bool useTableSession); + IIoTDbProvider GetSessionPool(bool sessionpolType); + /// /// 插入数据 /// diff --git a/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs index 9df2488..da14d20 100644 --- a/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs +++ b/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs @@ -44,7 +44,11 @@ namespace JiShe.CollectBus.IoTDB.Model /// 时标,也就是业务时间戳,单位毫秒,必须通过DateTimeOffset获取 /// public long Timestamps { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - + + /// + /// 设备路径 + /// + private string _devicePath; /// /// 设备路径 /// @@ -52,18 +56,16 @@ namespace JiShe.CollectBus.IoTDB.Model { get { - return $"root.{SystemName.ToLower()}.`{ProjectId}`.`{DeviceType}`.{DataType}.`{DeviceId}`"; + // 如果未手动设置路径,则自动生成 + if (string.IsNullOrWhiteSpace(_devicePath)) + { + return $"root.{SystemName.ToLower()}.`{ProjectId}`.`{DeviceType}`.{DataType}.`{DeviceId}`"; + } + return _devicePath; } set - { - if (string.IsNullOrWhiteSpace(value)) - { - DevicePath = $"root.{SystemName.ToLower()}.`{ProjectId}`.`{DeviceType}`.{DataType}.`{DeviceId}`"; - } - else - { - DevicePath = value; - } + { + _devicePath = value; // 直接赋值给支持字段,避免递归 } } } diff --git a/modules/JiShe.CollectBus.IoTDB/Options/QueryCondition.cs b/modules/JiShe.CollectBus.IoTDB/Options/QueryCondition.cs index 40dd443..bccf017 100644 --- a/modules/JiShe.CollectBus.IoTDB/Options/QueryCondition.cs +++ b/modules/JiShe.CollectBus.IoTDB/Options/QueryCondition.cs @@ -1,4 +1,7 @@ -namespace JiShe.CollectBus.IoTDB.Options +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Helpers; + +namespace JiShe.CollectBus.IoTDB.Options { /// /// 查询条件 @@ -19,10 +22,43 @@ /// 是否数值,如果是数值,则进行数值比较,否则进行字符串比较 /// public bool IsNumber { get; set; } = false; - + + private object _rawValue; /// /// 值 /// - public object Value { get; set; } + public object Value + { + get => ApplyValueConversion(_rawValue); + set => _rawValue = value; + } + + /// + /// 值转换 + /// + /// + /// + private object ApplyValueConversion(object rawValue) + { + string declaredTypeName = rawValue.GetType().Name; + + Func converter = GetQueryConditionValue(declaredTypeName); + return converter(rawValue); + } + + /// + /// 查询条件值转换委托 + /// + /// + /// + private Func GetQueryConditionValue(string declaredTypeName) + { + return declaredTypeName?.ToUpper() switch + { + "DATETIME" => v => v != null ? ((DateTime)v).ToUniversalTime().Ticks : null, + "STRING" => v => v != null ? $"'{v}'" : "''", + _ => v => v + }; + } } } diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs index 791240d..cd57ea9 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs @@ -36,11 +36,22 @@ namespace JiShe.CollectBus.IoTDB.Provider { private static readonly ConcurrentDictionary MetadataCache = new(); private readonly ILogger _logger; - private readonly IIoTDbSessionFactory _sessionFactory; - private readonly IoTDBRuntimeContext _runtimeContext; + private readonly IIoTDbSessionFactory _sessionFactory; + + /// + /// 存储模型切换标识,是否使用table模型存储, 默认为false,标识tree模型存储 + /// + public bool UseTableSessionPool { get; set; } + + private IIoTDbSessionPool CurrentSession { get; set; } + + public IIoTDbProvider GetSessionPool(bool useTableSessionPool) + { + CurrentSession = _sessionFactory.GetSessionPool(useTableSessionPool); + UseTableSessionPool = useTableSessionPool; + return this; + } - private IIoTDbSessionPool CurrentSession => - _sessionFactory.GetSessionPool(_runtimeContext.UseTableSessionPool); /// /// IoTDbProvider @@ -50,12 +61,10 @@ namespace JiShe.CollectBus.IoTDB.Provider /// public IoTDbProvider( ILogger logger, - IIoTDbSessionFactory sessionFactory, - IoTDBRuntimeContext runtimeContext) + IIoTDbSessionFactory sessionFactory) { _logger = logger; _sessionFactory = sessionFactory; - _runtimeContext = runtimeContext; } @@ -77,6 +86,7 @@ namespace JiShe.CollectBus.IoTDB.Provider _logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 tablet 为null"); return; } + _logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {tablet.First().InsertTargetName}"); await CurrentSession.InsertAsync(tablet.First()); } @@ -96,6 +106,11 @@ namespace JiShe.CollectBus.IoTDB.Provider { try { + if (entities == null || entities.Count() <= 0) + { + _logger.LogError($"{nameof(BatchInsertAsync)} 参数异常,-101"); + return; + } var metadata = await GetMetadata(); var batchSize = 1000; @@ -109,8 +124,11 @@ namespace JiShe.CollectBus.IoTDB.Provider _logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 tablet 为null"); return; } + foreach (var item in tablet) { + _logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {item.InsertTargetName}"); + await CurrentSession.InsertAsync(item); } } @@ -320,10 +338,7 @@ namespace JiShe.CollectBus.IoTDB.Provider { return null; } - - //var accessor = SourceEntityAccessorFactory.GetAccessor(); - - //var memberCache = BuildMemberCache(accessor); + if (metadata.EntityType == null) { @@ -335,16 +350,16 @@ namespace JiShe.CollectBus.IoTDB.Provider throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 不属于IoTDB数据模型实体,属于异常情况,-102"); } - if (metadata.EntityType == EntityTypeEnum.TreeModel && _runtimeContext.UseTableSessionPool == true) + if (metadata.EntityType == EntityTypeEnum.TreeModel && UseTableSessionPool == true) { throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 tree模型不能使用table模型Session连接,属于异常情况,-103"); } - else if (metadata.EntityType == EntityTypeEnum.TableModel && _runtimeContext.UseTableSessionPool == false) + else if (metadata.EntityType == EntityTypeEnum.TableModel && UseTableSessionPool == false) { - throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接,属于异常情况,-104"); + throw new Exception($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接,属于异常情况,-104"); } string tableNameOrTreePath = string.Empty; - if (_runtimeContext.UseTableSessionPool)//表模型 + if ( UseTableSessionPool)//表模型 { //如果指定了路径 if (!string.IsNullOrWhiteSpace(metadata.TableNameOrTreePath)) @@ -405,7 +420,7 @@ namespace JiShe.CollectBus.IoTDB.Provider } } - return _runtimeContext.UseTableSessionPool + return UseTableSessionPool ? BuildTableSessionTablet(metadata, tableNameOrTreePath, tempColumnNames, values.Select(d => d.ToList()).ToList(), timestamps.ToList()) : BuildSessionTablet(metadata, tableNameOrTreePath, tempColumnNames, values.Select(d => d.ToList()).ToList(), timestamps.ToList()); } @@ -490,7 +505,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var metadata = await GetMetadata(); var sb = new StringBuilder(); - if (!_runtimeContext.UseTableSessionPool) + if (!UseTableSessionPool) { sb.Append("DELETE "); } @@ -519,16 +534,16 @@ namespace JiShe.CollectBus.IoTDB.Provider /// /// private string TranslateCondition(QueryCondition condition) - { + { return condition.Operator switch { - ">" => condition.IsNumber ? $"{condition.Field} > {condition.Value}" : $"{condition.Field} > '{condition.Value}'", - "<" => condition.IsNumber ? $"{condition.Field} < {condition.Value}" : $"{condition.Field} < '{condition.Value}'", - "=" => condition.IsNumber ? $"{condition.Field} = {condition.Value}" : $"{condition.Field} = '{condition.Value}'", + ">" => $"{condition.Field} > {condition.Value}", + "<" => $"{condition.Field} < {condition.Value}", + "=" => $"{condition.Field} = {condition.Value}", _ => throw new NotSupportedException($"{nameof(TranslateCondition)} 将查询条件转换为SQL语句时操作符 {condition.Operator} 属于异常情况") }; } - + /// /// 获取查询条件的总数量 /// @@ -795,7 +810,8 @@ namespace JiShe.CollectBus.IoTDB.Provider { return declaredTypeName switch { - "DATETIME" => value => value != null ? ((DateTime)value).GetDateTimeOffset().ToUnixTimeNanoseconds() : null, + "DATETIME" => value => value != null ? Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds() : null, + "DECIMAL" => value => value != null ? Convert.ToDouble( value) : null, _ => value => value }; } @@ -897,7 +913,7 @@ namespace JiShe.CollectBus.IoTDB.Provider ["DATETIME"] = TSDataType.TIMESTAMP, ["DATE"] = TSDataType.DATE, ["BLOB"] = TSDataType.BLOB, - ["DECIMAL"] = TSDataType.STRING, + ["DECIMAL"] = TSDataType.DOUBLE, ["STRING"] = TSDataType.STRING }; @@ -933,7 +949,7 @@ namespace JiShe.CollectBus.IoTDB.Provider TSDataType.BOOLEAN => Convert.ToBoolean(value), TSDataType.INT32 => Convert.ToInt32(value), TSDataType.INT64 => Convert.ToInt64(value), - TSDataType.FLOAT => Convert.ToDouble(value), + TSDataType.FLOAT => Convert.ToSingle(value), TSDataType.DOUBLE => Convert.ToDouble(value), TSDataType.TEXT => Convert.ToString(value), TSDataType.NONE => null, diff --git a/modules/JiShe.CollectBus.Kafka.Test/Properties/launchSettings.json b/modules/JiShe.CollectBus.Kafka.Test/Properties/launchSettings.json new file mode 100644 index 0000000..33504c9 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "WSL": { + "commandName": "WSL2", + "distributionName": "" + } + } +} \ No newline at end of file diff --git a/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs b/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs index bf752eb..043af46 100644 --- a/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs +++ b/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs @@ -1,6 +1,7 @@ using Confluent.Kafka; using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Serialization; using Microsoft.AspNetCore.DataProtection.KeyManagement; @@ -127,80 +128,88 @@ namespace JiShe.CollectBus.Kafka.Consumer /// public async Task SubscribeAsync(string[] topics, Func> messageHandler, string? groupId = null) where TKey : notnull where TValue : class { - await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => + try { - - var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; - var cts = new CancellationTokenSource(); - - var consumer = _consumerStore.GetOrAdd(consumerKey, _ => - ( - CreateConsumer(groupId), - cts - )).Consumer as IConsumer; - - consumer!.Subscribe(topics); - - _ = Task.Run(async () => + await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => { - while (!cts.IsCancellationRequested) - { - try - { - //_logger.LogInformation($"Kafka消费: {string.Join("", topics)} 开始拉取消息...."); - var result = consumer.Consume(cts.Token); - if (result == null || result.Message == null || result.Message.Value == null) + var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; + var cts = new CancellationTokenSource(); + + var consumer = _consumerStore.GetOrAdd(consumerKey, _ => + ( + CreateConsumer(groupId), + cts + )).Consumer as IConsumer; + + consumer!.Subscribe(topics); + + _ = Task.Run(async () => + { + while (!cts.IsCancellationRequested) + { + try { - await Task.Delay(DelayTime, cts.Token); - continue; - } - if (result.IsPartitionEOF) - { -#if DEBUG - _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); -#endif - await Task.Delay(DelayTime, cts.Token); - continue; - } - if (_kafkaOptionConfig.EnableFilter) - { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; - // 检查 Header 是否符合条件 - if (!headersFilter.Match(result.Message.Headers)) + //_logger.LogInformation($"Kafka消费: {string.Join("", topics)} 开始拉取消息...."); + + var result = consumer.Consume(cts.Token); + if (result == null || result.Message == null || result.Message.Value == null) { - consumer.Commit(result); // 提交偏移量 - // 跳过消息 + await Task.Delay(DelayTime, cts.Token); continue; } + if (result.IsPartitionEOF) + { +#if DEBUG + _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); +#endif + await Task.Delay(DelayTime, cts.Token); + continue; + } + if (_kafkaOptionConfig.EnableFilter) + { + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; + // 检查 Header 是否符合条件 + if (!headersFilter.Match(result.Message.Headers)) + { + consumer.Commit(result); // 提交偏移量 + // 跳过消息 + continue; + } + } + bool sucess = await messageHandler(result.Message.Key, result.Message.Value); + if (sucess) + consumer.Commit(result); // 手动提交 + } + catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) + { + _logger.LogError(ex, $"{string.Join("、", topics)}消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 + } + catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) + { + _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 + } + catch (OperationCanceledException) + { + //ignore + } + catch (Exception ex) + { + _logger.LogError(ex, "处理消息时发生未知错误"); } - bool sucess = await messageHandler(result.Message.Key, result.Message.Value); - if (sucess) - consumer.Commit(result); // 手动提交 } - catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)}消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (OperationCanceledException) - { - //ignore - } - catch (Exception ex) - { - _logger.LogError(ex, "处理消息时发生未知错误"); - } - } - }, cts.Token); - await Task.CompletedTask; - }); + }, cts.Token); + await Task.CompletedTask; + }); + } + catch (Exception ex) + { + + throw; + } } @@ -215,76 +224,84 @@ namespace JiShe.CollectBus.Kafka.Consumer /// public async Task SubscribeAsync(string[] topics, Func> messageHandler, string? groupId) where TValue : class { - await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => + try { - var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}"; - var cts = new CancellationTokenSource(); - var consumer = _consumerStore.GetOrAdd(consumerKey, _ => - ( - CreateConsumer(groupId), - cts - )).Consumer as IConsumer; - - consumer!.Subscribe(topics); - - _ = Task.Run(async () => + await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => { - int count = 0; - while (!cts.IsCancellationRequested) - { - try - { - //_logger.LogInformation($"Kafka消费: {string.Join("", topics)}_{count} 开始拉取消息...."); - count++; - var result = consumer.Consume(cts.Token); - if (result == null || result.Message == null || result.Message.Value == null) - { - await Task.Delay(DelayTime, cts.Token); - continue; - } + var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}"; + var cts = new CancellationTokenSource(); + var consumer = _consumerStore.GetOrAdd(consumerKey, _ => + ( + CreateConsumer(groupId), + cts + )).Consumer as IConsumer; - if (result.IsPartitionEOF) + consumer!.Subscribe(topics); + + _ = Task.Run(async () => + { + int count = 0; + while (!cts.IsCancellationRequested) + { + try { -#if DEBUG - _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); -#endif - await Task.Delay(DelayTime, cts.Token); - continue; - } - if (_kafkaOptionConfig.EnableFilter) - { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; - // 检查 Header 是否符合条件 - if (!headersFilter.Match(result.Message.Headers)) + //_logger.LogInformation($"Kafka消费: {string.Join("", topics)}_{count} 开始拉取消息...."); + count++; + var result = consumer.Consume(cts.Token); + if (result == null || result.Message == null || result.Message.Value == null) { - consumer.Commit(result); // 提交偏移量 - // 跳过消息 + await Task.Delay(DelayTime, cts.Token); continue; } + + if (result.IsPartitionEOF) + { +#if DEBUG + _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); +#endif + await Task.Delay(DelayTime, cts.Token); + continue; + } + if (_kafkaOptionConfig.EnableFilter) + { + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; + // 检查 Header 是否符合条件 + if (!headersFilter.Match(result.Message.Headers)) + { + consumer.Commit(result); // 提交偏移量 + // 跳过消息 + continue; + } + } + bool sucess = await messageHandler(result.Message.Value); + if (sucess) + consumer.Commit(result); // 手动提交 + //else + // consumer.StoreOffset(result); + } + catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) + { + _logger.LogError(ex, $"{string.Join("、", topics)}消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 + } + catch (OperationCanceledException) + { + //ignore + } + catch (Exception ex) + { + _logger.LogError(ex, "处理消息时发生未知错误"); } - bool sucess = await messageHandler(result.Message.Value); - if (sucess) - consumer.Commit(result); // 手动提交 - //else - // consumer.StoreOffset(result); } - catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)}消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (OperationCanceledException) - { - //ignore - } - catch (Exception ex) - { - _logger.LogError(ex, "处理消息时发生未知错误"); - } - } - }, cts.Token); - await Task.CompletedTask; - }); + }, cts.Token); + await Task.CompletedTask; + }); + } + catch (Exception ex) + { + + throw; + } } @@ -300,7 +317,15 @@ namespace JiShe.CollectBus.Kafka.Consumer /// 批次超时时间 public async Task SubscribeBatchAsync(string topic, Func, Task> messageBatchHandler, string? groupId = null, int batchSize = 100, TimeSpan? batchTimeout = null) where TKey : notnull where TValue : class { - await SubscribeBatchAsync(new[] { topic }, messageBatchHandler, groupId, batchSize, batchTimeout); + try + { + await SubscribeBatchAsync(new[] { topic }, messageBatchHandler, groupId, batchSize, batchTimeout); + } + catch (Exception ex) + { + + throw; + } } /// @@ -315,117 +340,125 @@ namespace JiShe.CollectBus.Kafka.Consumer /// 批次超时时间 public async Task SubscribeBatchAsync(string[] topics, Func, Task> messageBatchHandler, string? groupId = null, int batchSize = 100, TimeSpan? batchTimeout = null) where TKey : notnull where TValue : class { - await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => + try { - - var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; - var cts = new CancellationTokenSource(); - - var consumer = _consumerStore.GetOrAdd(consumerKey, _ => - ( - CreateConsumer(groupId), - cts - )).Consumer as IConsumer; - consumer!.Subscribe(topics); - - var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒 - - _ = Task.Run(async () => + await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => { - var messages = new List<(TValue Value, TopicPartitionOffset Offset)>(); - var startTime = DateTime.UtcNow; - while (!cts.IsCancellationRequested) + var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; + var cts = new CancellationTokenSource(); + + var consumer = _consumerStore.GetOrAdd(consumerKey, _ => + ( + CreateConsumer(groupId), + cts + )).Consumer as IConsumer; + consumer!.Subscribe(topics); + + var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒 + + _ = Task.Run(async () => { - try - { - // 非阻塞快速累积消息 - while (messages.Count < batchSize && (DateTime.UtcNow - startTime) < timeout) - { - var result = consumer.Consume(TimeSpan.Zero); // 非阻塞调用 + var messages = new List<(TValue Value, TopicPartitionOffset Offset)>(); + var startTime = DateTime.UtcNow; - if (result != null) + while (!cts.IsCancellationRequested) + { + try + { + // 非阻塞快速累积消息 + while (messages.Count < batchSize && (DateTime.UtcNow - startTime) < timeout) { - if (result.IsPartitionEOF) + var result = consumer.Consume(TimeSpan.Zero); // 非阻塞调用 + + if (result != null) { + if (result.IsPartitionEOF) + { #if DEBUG - _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); + _logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); #endif + await Task.Delay(DelayTime, cts.Token); + } + else if (result.Message.Value != null) + { + if (_kafkaOptionConfig.EnableFilter) + { + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; + // 检查 Header 是否符合条件 + if (!headersFilter.Match(result.Message.Headers)) + { + consumer.Commit(result); // 提交偏移量 + // 跳过消息 + continue; + } + } + messages.Add((result.Message.Value, result.TopicPartitionOffset)); + } + } + else + { + // 无消息时短暂等待 await Task.Delay(DelayTime, cts.Token); } - else if (result.Message.Value != null) + } + + // 处理批次 + if (messages.Count > 0) + { + bool success = await messageBatchHandler(messages.Select(m => m.Value).ToList()); + if (success) { - if (_kafkaOptionConfig.EnableFilter) + var offsetsByPartition = new Dictionary(); + foreach (var msg in messages) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; - // 检查 Header 是否符合条件 - if (!headersFilter.Match(result.Message.Headers)) + var tp = msg.Offset.TopicPartition; + var offset = msg.Offset.Offset; + if (!offsetsByPartition.TryGetValue(tp, out var currentMax) || offset > currentMax) { - consumer.Commit(result); // 提交偏移量 - // 跳过消息 - continue; + offsetsByPartition[tp] = offset; } } - messages.Add((result.Message.Value, result.TopicPartitionOffset)); - } - } - else - { - // 无消息时短暂等待 - await Task.Delay(DelayTime, cts.Token); - } - } - // 处理批次 - if (messages.Count > 0) + var offsetsToCommit = offsetsByPartition + .Select(kv => new TopicPartitionOffset(kv.Key, new Offset(kv.Value + 1))) + .ToList(); + consumer.Commit(offsetsToCommit); + } + messages.Clear(); + } + + startTime = DateTime.UtcNow; + } + catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) { - bool success = await messageBatchHandler(messages.Select(m => m.Value).ToList()); - if (success) - { - var offsetsByPartition = new Dictionary(); - foreach (var msg in messages) - { - var tp = msg.Offset.TopicPartition; - var offset = msg.Offset.Offset; - if (!offsetsByPartition.TryGetValue(tp, out var currentMax) || offset > currentMax) - { - offsetsByPartition[tp] = offset; - } - } - - var offsetsToCommit = offsetsByPartition - .Select(kv => new TopicPartitionOffset(kv.Key, new Offset(kv.Value + 1))) - .ToList(); - consumer.Commit(offsetsToCommit); - } - messages.Clear(); + _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 } + catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) + { + _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 + } + catch (OperationCanceledException) + { + //ignore + } + catch (Exception ex) + { + _logger.LogError(ex, "处理批量消息时发生未知错误"); + } + } + }, cts.Token); - startTime = DateTime.UtcNow; - } - catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (OperationCanceledException) - { - //ignore - } - catch (Exception ex) - { - _logger.LogError(ex, "处理批量消息时发生未知错误"); - } - } - }, cts.Token); + await Task.CompletedTask; + }); + } + catch (Exception ex) + { - await Task.CompletedTask; - }); + throw; + } } @@ -441,7 +474,15 @@ namespace JiShe.CollectBus.Kafka.Consumer /// 消费等待时间 public async Task SubscribeBatchAsync(string topic, Func, Task> messageBatchHandler, string? groupId = null, int batchSize = 100, TimeSpan? batchTimeout = null, TimeSpan? consumeTimeout = null) where TValue : class { - await SubscribeBatchAsync(new[] { topic }, messageBatchHandler, groupId, batchSize, batchTimeout, consumeTimeout); + try + { + await SubscribeBatchAsync(new[] { topic }, messageBatchHandler, groupId, batchSize, batchTimeout, consumeTimeout); + } + catch (Exception ex) + { + + throw; + } } @@ -458,116 +499,124 @@ namespace JiShe.CollectBus.Kafka.Consumer /// 消费等待时间 public async Task SubscribeBatchAsync(string[] topics, Func, Task> messageBatchHandler, string? groupId = null, int batchSize = 100, TimeSpan? batchTimeout = null, TimeSpan? consumeTimeout = null) where TValue : class { - await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => + try { - - var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}"; - var cts = new CancellationTokenSource(); - - var consumer = _consumerStore.GetOrAdd(consumerKey, _ => - ( - CreateConsumer(groupId), - cts - )).Consumer as IConsumer; - - consumer!.Subscribe(topics); - - var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒 - - _ = Task.Run(async () => + await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token => { - var messages = new List<(TValue Value, TopicPartitionOffset Offset)>(); - var startTime = DateTime.UtcNow; - while (!cts.IsCancellationRequested) + var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}"; + var cts = new CancellationTokenSource(); + + var consumer = _consumerStore.GetOrAdd(consumerKey, _ => + ( + CreateConsumer(groupId), + cts + )).Consumer as IConsumer; + + consumer!.Subscribe(topics); + + var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒 + + _ = Task.Run(async () => { - try - { - // 非阻塞快速累积消息 - while (messages.Count < batchSize && (DateTime.UtcNow - startTime) < timeout) - { - var result = consumer.Consume(TimeSpan.Zero); // 非阻塞调用 + var messages = new List<(TValue Value, TopicPartitionOffset Offset)>(); + var startTime = DateTime.UtcNow; - if (result != null) + while (!cts.IsCancellationRequested) + { + try + { + // 非阻塞快速累积消息 + while (messages.Count < batchSize && (DateTime.UtcNow - startTime) < timeout) { - if (result.IsPartitionEOF) + var result = consumer.Consume(TimeSpan.Zero); // 非阻塞调用 + + if (result != null) { - //_logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); + if (result.IsPartitionEOF) + { + //_logger.LogInformation("Kafka消费: {Topic} 分区 {Partition} 已消费完", result.Topic, result.Partition); + await Task.Delay(DelayTime, cts.Token); + } + else if (result.Message.Value != null) + { + if (_kafkaOptionConfig.EnableFilter) + { + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; + // 检查 Header 是否符合条件 + if (!headersFilter.Match(result.Message.Headers)) + { + consumer.Commit(result); // 提交偏移量 + // 跳过消息 + continue; + } + } + messages.Add((result.Message.Value, result.TopicPartitionOffset)); + } + } + else + { + // 无消息时短暂等待 await Task.Delay(DelayTime, cts.Token); } - else if (result.Message.Value != null) + } + + // 处理批次 + if (messages.Count > 0) + { + bool success = await messageBatchHandler(messages.Select(m => m.Value).ToList()); + if (success) { - if (_kafkaOptionConfig.EnableFilter) + var offsetsByPartition = new Dictionary(); + foreach (var msg in messages) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; - // 检查 Header 是否符合条件 - if (!headersFilter.Match(result.Message.Headers)) + var tp = msg.Offset.TopicPartition; + var offset = msg.Offset.Offset; + if (!offsetsByPartition.TryGetValue(tp, out var currentMax) || offset > currentMax) { - consumer.Commit(result); // 提交偏移量 - // 跳过消息 - continue; + offsetsByPartition[tp] = offset; } } - messages.Add((result.Message.Value, result.TopicPartitionOffset)); - } - } - else - { - // 无消息时短暂等待 - await Task.Delay(DelayTime, cts.Token); - } - } - // 处理批次 - if (messages.Count > 0) + var offsetsToCommit = offsetsByPartition + .Select(kv => new TopicPartitionOffset(kv.Key, new Offset(kv.Value + 1))) + .ToList(); + consumer.Commit(offsetsToCommit); + } + messages.Clear(); + } + + startTime = DateTime.UtcNow; + } + catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) { - bool success = await messageBatchHandler(messages.Select(m => m.Value).ToList()); - if (success) - { - var offsetsByPartition = new Dictionary(); - foreach (var msg in messages) - { - var tp = msg.Offset.TopicPartition; - var offset = msg.Offset.Offset; - if (!offsetsByPartition.TryGetValue(tp, out var currentMax) || offset > currentMax) - { - offsetsByPartition[tp] = offset; - } - } - - var offsetsToCommit = offsetsByPartition - .Select(kv => new TopicPartitionOffset(kv.Key, new Offset(kv.Value + 1))) - .ToList(); - consumer.Commit(offsetsToCommit); - } - messages.Clear(); + _logger.LogError(ex, $"消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 } + catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) + { + _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); + throw; // 抛出异常,以便重试 + } + catch (OperationCanceledException) + { + //ignore + } + catch (Exception ex) + { + _logger.LogError(ex, "处理批量消息时发生未知错误"); + } + } + }, cts.Token); - startTime = DateTime.UtcNow; - } - catch (ConsumeException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (KafkaException ex) when (KafkaPollyPipeline.IsRecoverableError(ex)) - { - _logger.LogError(ex, $"{string.Join("、", topics)} 消息消费失败: {ex.Error.Reason}"); - throw; // 抛出异常,以便重试 - } - catch (OperationCanceledException) - { - //ignore - } - catch (Exception ex) - { - _logger.LogError(ex, "处理批量消息时发生未知错误"); - } - } - }, cts.Token); + await Task.CompletedTask; + }); + } + catch (Exception ex) + { - await Task.CompletedTask; - }); + throw; + } } @@ -578,12 +627,20 @@ namespace JiShe.CollectBus.Kafka.Consumer /// public void Unsubscribe(string[] topics, string? groupId) where TKey : notnull where TValue : class { - var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; - if (_consumerStore.TryRemove(consumerKey, out var entry)) + try { - entry.CTS.Cancel(); - (entry.Consumer as IDisposable)?.Dispose(); - entry.CTS.Dispose(); + var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}"; + if (_consumerStore.TryRemove(consumerKey, out var entry)) + { + entry.CTS.Cancel(); + (entry.Consumer as IDisposable)?.Dispose(); + entry.CTS.Dispose(); + } + } + catch (Exception ex) + { + + throw; } } diff --git a/modules/JiShe.CollectBus.Kafka/KafkaSubscribeExtensions.cs b/modules/JiShe.CollectBus.Kafka/KafkaSubscribeExtensions.cs index 028762f..ccbe540 100644 --- a/modules/JiShe.CollectBus.Kafka/KafkaSubscribeExtensions.cs +++ b/modules/JiShe.CollectBus.Kafka/KafkaSubscribeExtensions.cs @@ -226,6 +226,11 @@ namespace JiShe.CollectBus.Kafka // 处理消费错误 logger.LogError($"kafka批量消费异常:{ex.Message}"); } + catch (Exception ex) + { + // 处理消费错误 + logger.LogError($"kafka批量消费异常:{ex.Message}"); + } return await Task.FromResult(false); }, attr.GroupId, attr.BatchSize, attr.BatchTimeout); } @@ -248,6 +253,11 @@ namespace JiShe.CollectBus.Kafka // 处理消费错误 logger.LogError($"kafka消费异常:{ex.Message}"); } + catch (Exception ex) + { + // 处理消费错误 + logger.LogError($"kafka批量消费异常:{ex.Message}"); + } return await Task.FromResult(false); }, attr.GroupId); } @@ -260,125 +270,133 @@ namespace JiShe.CollectBus.Kafka /// private static async Task ProcessMessageAsync(List messages, MethodInfo method, object subscribe) { - var parameters = method.GetParameters(); - bool isGenericTask = method.ReturnType.IsGenericType - && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>); - bool existParameters = parameters.Length > 0; - object[]? executeParameters = null; - - if (existParameters) + try { - IList? list = null; - Tuple tuple = method.GetParameterTypeInfo(); - bool isEnumerable = false; - if (tuple.Item2 != null) - { - Type listType = typeof(List<>).MakeGenericType(tuple.Item2); - list = (IList)Activator.CreateInstance(listType)!; - isEnumerable = tuple.Item2.IsConvertType(); - } - else - { - isEnumerable = tuple.Item1.IsConvertType(); - } - #region 暂时 - //foreach (var msg in messages) - //{ - // if (tuple.Item2 != null) - // { - // if (isEnumerable) - // { - // var parameterType = parameters[0].ParameterType; - // var data=messages?.Serialize().Deserialize(parameterType); - // messageObj = data!=null? new[] { data }:null; - // break; - // } - // else - // { - // // 集合类型 - // var data = msg?.Serialize().Deserialize(tuple.Item2) /*isEnumerable ? Convert.ChangeType(msg, tuple.Item2) : msg?.Serialize().Deserialize(tuple.Item2)*/; - // if (data != null) - // list?.Add(data); - // } + var parameters = method.GetParameters(); + bool isGenericTask = method.ReturnType.IsGenericType + && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>); + bool existParameters = parameters.Length > 0; + object[]? executeParameters = null; - // } - // else - // { - // // (dynamic)Convert.ChangeType(msg, tuple.Item1) - // using (var stream = new MemoryStream(msg)) - // { - // var data1= System.Text.Json.JsonSerializer.Deserialize(stream, tuple.Item1); - // } - // var data = isEnumerable ? System.Text.Json.JsonSerializer.Deserialize(msg, tuple.Item1): msg?.ToString()?.Deserialize(tuple.Item1); - // if (data != null) - // messageObj = new[] { data }; - // } - //} - //if (tuple.Item2 != null && list != null && list.Count > 0) - //{ - // messageObj = new[] { list }; - //} - #endregion - var parameterDescriptors = method.GetParameters(); - executeParameters = new object?[parameterDescriptors.Length]; - for (var i = 0; i < parameterDescriptors.Length; i++) + if (existParameters) { - foreach (var item in messages) - { - - object? tempParameter=null; - var parameterDescriptor = parameterDescriptors[i]; - if (KafkaSerialization.IsJsonType(item)) + IList? list = null; + Tuple tuple = method.GetParameterTypeInfo(); + bool isEnumerable = false; + if (tuple.Item2 != null) + { + Type listType = typeof(List<>).MakeGenericType(tuple.Item2); + list = (IList)Activator.CreateInstance(listType)!; + isEnumerable = tuple.Item2.IsConvertType(); + } + else + { + isEnumerable = tuple.Item1.IsConvertType(); + } + #region 暂时 + //foreach (var msg in messages) + //{ + // if (tuple.Item2 != null) + // { + // if (isEnumerable) + // { + // var parameterType = parameters[0].ParameterType; + // var data=messages?.Serialize().Deserialize(parameterType); + // messageObj = data!=null? new[] { data }:null; + // break; + // } + // else + // { + // // 集合类型 + // var data = msg?.Serialize().Deserialize(tuple.Item2) /*isEnumerable ? Convert.ChangeType(msg, tuple.Item2) : msg?.Serialize().Deserialize(tuple.Item2)*/; + // if (data != null) + // list?.Add(data); + // } + + // } + // else + // { + // // (dynamic)Convert.ChangeType(msg, tuple.Item1) + // using (var stream = new MemoryStream(msg)) + // { + // var data1= System.Text.Json.JsonSerializer.Deserialize(stream, tuple.Item1); + // } + // var data = isEnumerable ? System.Text.Json.JsonSerializer.Deserialize(msg, tuple.Item1): msg?.ToString()?.Deserialize(tuple.Item1); + // if (data != null) + // messageObj = new[] { data }; + // } + //} + //if (tuple.Item2 != null && list != null && list.Count > 0) + //{ + // messageObj = new[] { list }; + //} + #endregion + var parameterDescriptors = method.GetParameters(); + executeParameters = new object?[parameterDescriptors.Length]; + for (var i = 0; i < parameterDescriptors.Length; i++) + { + foreach (var item in messages) { - tempParameter = KafkaSerialization.Deserialize(item, tuple.Item2 != null? tuple.Item2: parameterDescriptor.ParameterType); - } - else - { - - var converter = TypeDescriptor.GetConverter(parameterDescriptor.ParameterType); - if (converter.CanConvertFrom(item.GetType())) + + object? tempParameter = null; + var parameterDescriptor = parameterDescriptors[i]; + if (KafkaSerialization.IsJsonType(item)) { - tempParameter = converter.ConvertFrom(item); + tempParameter = KafkaSerialization.Deserialize(item, tuple.Item2 != null ? tuple.Item2 : parameterDescriptor.ParameterType); } else { - if (parameterDescriptor.ParameterType.IsInstanceOfType(item)) - tempParameter = item; - else - tempParameter =Convert.ChangeType(item, parameterDescriptor.ParameterType); - } - } - if (tuple.Item2 == null) - { - executeParameters[i] = tempParameter; - } - else - { - list.Add(tempParameter); - } - - } - if(list!=null && list.Count>0) - executeParameters[i] = list; - } - } - var result = method.Invoke(subscribe, executeParameters); - if (result is Task genericTask) - { - await genericTask.ConfigureAwait(false); - return genericTask.Result.Ack; + var converter = TypeDescriptor.GetConverter(parameterDescriptor.ParameterType); + if (converter.CanConvertFrom(item.GetType())) + { + tempParameter = converter.ConvertFrom(item); + } + else + { + if (parameterDescriptor.ParameterType.IsInstanceOfType(item)) + tempParameter = item; + else + tempParameter = Convert.ChangeType(item, parameterDescriptor.ParameterType); + } + } + if (tuple.Item2 == null) + { + executeParameters[i] = tempParameter; + } + else + { + list.Add(tempParameter); + } + + } + if (list != null && list.Count > 0) + executeParameters[i] = list; + } + } + + var result = method.Invoke(subscribe, executeParameters); + if (result is Task genericTask) + { + await genericTask.ConfigureAwait(false); + return genericTask.Result.Ack; + } + else if (result is Task nonGenericTask) + { + await nonGenericTask.ConfigureAwait(false); + return true; + } + else if (result is ISubscribeAck ackResult) + { + return ackResult.Ack; + } + return false; } - else if (result is Task nonGenericTask) + catch (Exception ex) { - await nonGenericTask.ConfigureAwait(false); - return true; + + throw; } - else if (result is ISubscribeAck ackResult) - { - return ackResult.Ack; - } - return false; } } diff --git a/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs b/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs index 7f9a85d..72e9096 100644 --- a/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs +++ b/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs @@ -117,17 +117,25 @@ namespace JiShe.CollectBus.Kafka.Producer /// public async Task ProduceAsync(string topic, TKey key, TValue value)where TKey : notnull where TValue : class { - var typeKey = typeof(KafkaProducer); - var producer = GetProducer(typeKey); - var message = new Message + try { - Key = key, - Value = value, - Headers = new Headers{ + var typeKey = typeof(KafkaProducer); + var producer = GetProducer(typeKey); + var message = new Message + { + Key = key, + Value = value, + Headers = new Headers{ { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } - }; - await producer.ProduceAsync(topic, message); + }; + await producer.ProduceAsync(topic, message); + } + catch (Exception ex) + { + + throw; + } } /// @@ -139,16 +147,24 @@ namespace JiShe.CollectBus.Kafka.Producer /// public async Task ProduceAsync(string topic, TValue value) where TValue : class { - var typeKey = typeof(KafkaProducer); - var producer = GetProducer(typeKey); - var message = new Message + try { - Value = value, - Headers = new Headers{ + var typeKey = typeof(KafkaProducer); + var producer = GetProducer(typeKey); + var message = new Message + { + Value = value, + Headers = new Headers{ { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } - }; - await producer.ProduceAsync(topic, message); + }; + await producer.ProduceAsync(topic, message); + } + catch (Exception ex) + { + + throw; + } } /// @@ -164,26 +180,34 @@ namespace JiShe.CollectBus.Kafka.Producer /// public async Task ProduceAsync(string topic,TKey key,TValue value,int? partition=null, Action>? deliveryHandler = null)where TKey : notnull where TValue : class { - var message = new Message + try { - Key = key, - Value = value, - Headers = new Headers{ + var message = new Message + { + Key = key, + Value = value, + Headers = new Headers{ { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } - }; - var typeKey = typeof(KafkaProducer); - var producer = GetProducer(typeKey); - if (partition.HasValue) - { - var topicPartition = new TopicPartition(topic, new Partition(partition.Value)); - producer.Produce(topicPartition, message, deliveryHandler); + }; + var typeKey = typeof(KafkaProducer); + var producer = GetProducer(typeKey); + if (partition.HasValue) + { + var topicPartition = new TopicPartition(topic, new Partition(partition.Value)); + producer.Produce(topicPartition, message, deliveryHandler); + } + else + { + producer.Produce(topic, message, deliveryHandler); + } + await Task.CompletedTask; } - else + catch (Exception ex) { - producer.Produce(topic, message, deliveryHandler); + + throw; } - await Task.CompletedTask; } @@ -199,26 +223,34 @@ namespace JiShe.CollectBus.Kafka.Producer /// public async Task ProduceAsync(string topic, TValue value, int? partition=null, Action>? deliveryHandler = null) where TValue : class { - var message = new Message + try { - Value = value, - Headers = new Headers{ + var message = new Message + { + Value = value, + Headers = new Headers{ { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } - }; - var typeKey = typeof(KafkaProducer); - var producer = GetProducer(typeKey); - if (partition.HasValue) - { - var topicPartition = new TopicPartition(topic,new Partition(partition.Value)); - //_logger.LogError($"push消息:{topic}-{partition.Value}"); - producer.Produce(topicPartition, message, deliveryHandler); + }; + var typeKey = typeof(KafkaProducer); + var producer = GetProducer(typeKey); + if (partition.HasValue) + { + var topicPartition = new TopicPartition(topic, new Partition(partition.Value)); + //_logger.LogError($"push消息:{topic}-{partition.Value}"); + producer.Produce(topicPartition, message, deliveryHandler); + } + else + { + producer.Produce(topic, message, deliveryHandler); + } + await Task.CompletedTask; } - else + catch (Exception ex) { - producer.Produce(topic, message, deliveryHandler); + + throw; } - await Task.CompletedTask; } public void Dispose() diff --git a/modules/JiShe.CollectBus.Kafka/Serialization/JsonSerializer.cs b/modules/JiShe.CollectBus.Kafka/Serialization/JsonSerializer.cs index 8034954..98fda49 100644 --- a/modules/JiShe.CollectBus.Kafka/Serialization/JsonSerializer.cs +++ b/modules/JiShe.CollectBus.Kafka/Serialization/JsonSerializer.cs @@ -19,6 +19,7 @@ namespace JiShe.CollectBus.Kafka.Serialization { DefaultIgnoreCondition = JsonIgnoreCondition.Never, WriteIndented = false,// 设置格式化输出 + IncludeFields = true,// 允许反序列化到非公共 setter 和字段 Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符 IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true, @@ -53,7 +54,7 @@ namespace JiShe.CollectBus.Kafka.Serialization { if (data.IsEmpty) return default; - return JsonSerializer.Deserialize(data, _options)!; + return JsonSerializer.Deserialize(data, _options)!; } catch (Exception ex) { @@ -102,24 +103,37 @@ namespace JiShe.CollectBus.Kafka.Serialization } public static object? Deserialize(object value, Type valueType) { - var _jsonSerializerOptions = new JsonSerializerOptions + try { - DefaultIgnoreCondition = JsonIgnoreCondition.Never, - WriteIndented = false,// 设置格式化输出 - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符 - IgnoreReadOnlyFields = true, - IgnoreReadOnlyProperties = true, - NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串 - AllowTrailingCommas = true, // 忽略尾随逗号 - ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释 - PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感 - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则 - Converters = { new DateTimeJsonConverter() } // 注册你的自定义转换器, - }; + var _jsonSerializerOptions = new JsonSerializerOptions + { + DefaultIgnoreCondition = JsonIgnoreCondition.Never, + WriteIndented = false,// 设置格式化输出 + IncludeFields = true,// 允许反序列化到非公共 setter 和字段 + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符 + IgnoreReadOnlyFields = true, + IgnoreReadOnlyProperties = true, + NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串 + AllowTrailingCommas = true, // 忽略尾随逗号 + ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释 + PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感 + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则 + Converters = { new DateTimeJsonConverter() } // 注册你的自定义转换器, + }; - if (value is JsonElement jsonElement) return jsonElement.Deserialize(valueType, _jsonSerializerOptions); + if (value is JsonElement jsonElement) + { + //return jsonElement.Deserialize(valueType, _jsonSerializerOptions); + return JsonSerializer.Deserialize(jsonElement, valueType, _jsonSerializerOptions); + } - throw new NotSupportedException("Type is not of type JsonElement"); + return null; + } + catch (Exception ex) + { + + throw; + } } } } diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs index e5511f2..7dc8e43 100644 --- a/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs @@ -46,7 +46,7 @@ namespace JiShe.CollectBus.Protocol.T1882018.SendData { var itemCodeArr = request.ItemCode.Split('_'); var c_data = itemCodeArr[0];//01 - var d_data = itemCodeArr[1];//91 或者 90 + var d_data = itemCodeArr[2];//91 或者 90 var dataUnit = new List() { "1F", d_data, "00" }; var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit); @@ -64,7 +64,7 @@ namespace JiShe.CollectBus.Protocol.T1882018.SendData { var itemCodeArr = request.ItemCode.Split('_'); var c_data = itemCodeArr[0];//01 - var d_data = itemCodeArr[1];//55 或者 99 + var d_data = itemCodeArr[2];//55 或者 99 var dataUnit = new List() { "A0", "17", "00", d_data }; var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit); diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs index 7e9f3a3..5b3044a 100644 --- a/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs @@ -92,7 +92,9 @@ namespace JiShe.CollectBus.Protocol.T1882018 List dataUnit = new List(); //数据转发场景 10H_F1 if (request.ItemCode == T37612012PacketItemCodeConst.AFN10HFN01H && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false) - { + { + //var subItemCodeArr = request.SubProtocolRequest.ItemCode.Split("_"); + var t188PacketHandlerName = $"{T1882018PacketItemCodeConst.BasicT1882018}_{request.SubProtocolRequest.ItemCode}_Send"; Telemetry1882018PacketResponse t645PacketResponse = null; diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs index c34358a..6fd96e1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -38,15 +39,15 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_00H ItemType= $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId= ammeterInfo.FocusId; + data.FocusId= deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs index f96e9dc..2e465b8 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -35,15 +36,15 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_00H ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F1_Analysis.cs index c46f935..686d027 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F1_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,16 +37,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_02H DataValue = "Login", ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F2_Analysis.cs index e9f6edd..6428063 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F2_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F2_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,16 +37,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_02H DataValue = "LogOut", ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F3_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F3_Analysis.cs index 348fc6f..1c3027b 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F3_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_02H/AFN2_F3_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,16 +37,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_02H DataValue = "Heartbeat", ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs index b990da1..5011b4e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -32,6 +33,7 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_09H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); var version = AnalysisDataUnit(input.UnitData.HexMessageList); version.AreaCode = input.A.Code?.Substring(0, 4); @@ -42,16 +44,16 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_09H DataValue = version, ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs index 3a62e56..7547662 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -29,6 +30,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_09H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); var data = new AnalysisBaseDto() { @@ -36,16 +38,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_09H DataValue = Encoding.ASCII.GetString(string.Join("", input.UnitData.HexMessageList.Skip(30).Take(20).ToList()).HexToByte()).Replace("\0", ""), ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs index c90a0a2..7e36e11 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -28,6 +29,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); Tuple> tuple = AFN10F10EntityAnalysis(input.UnitData.HexMessageList); @@ -41,16 +43,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH }, ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { @@ -90,22 +92,25 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH SerialNum = $"{sArray[1]}{sArray[0]}".HexToDec(), Point = $"{sArray[3]}{sArray[2]}".HexToDec(), RuleType= GetProtocol(sArray[5]), - ComAddress= $"{sArray[11]}{sArray[10]}{sArray[9]}{sArray[8]}{sArray[7]}{sArray[6]}", - ComPwd= $"{sArray[17]}{sArray[16]}{sArray[15]}{sArray[14]}{sArray[13]}{sArray[12]}".Substring(6, 6), - ElectricityRatesNum= sArray[18].HexToBin().Substring(2, 6).BinToDec(), - CollectorAddress = $"{sArray[25]}{sArray[24]}{sArray[23]}{sArray[22]}{sArray[21]}{sArray[20]}", + //ComAddress= $"{sArray[11]}{sArray[10]}{sArray[9]}{sArray[8]}{sArray[7]}{sArray[6]}"; + //ComPwd= $"{sArray[17]}{sArray[16]}{sArray[15]}{sArray[14]}{sArray[13]}{sArray[12]}".Substring(6, 6), + //ElectricityRatesNum= sArray[18].HexToBin().Substring(2, 6).BinToDec(), + //CollectorAddress = $"{sArray[25]}{sArray[24]}{sArray[23]}{sArray[22]}{sArray[21]}{sArray[20]}", }; - - string baudPort = sArray[4].HexToBin().PadLeft(8, '0'); //波特率和端口号放在一个字节内 + aFN10F10Entity.ComAddress = $"{sArray[11]}{sArray[10]}{sArray[9]}{sArray[8]}{sArray[7]}{sArray[6]}"; + aFN10F10Entity.ComPwd = $"{sArray[17]}{sArray[16]}{sArray[15]}{sArray[14]}{sArray[13]}{sArray[12]}".Substring(6, 6); + aFN10F10Entity.ElectricityRatesNum = sArray[18].HexTo4BinZero().Substring(2, 6).BinToDec(); + aFN10F10Entity.CollectorAddress = $"{sArray[25]}{sArray[24]}{sArray[23]}{sArray[22]}{sArray[21]}{sArray[20]}"; + string baudPort = sArray[4].HexTo4BinZero().PadLeft(8, '0'); //波特率和端口号放在一个字节内 aFN10F10Entity.BaudRate = GetBaudrate(baudPort.Substring(0, 3)); aFN10F10Entity.Port = baudPort.Substring(3, 5).BinToDec(); - string dataDigit = sArray[19].HexToBin().PadLeft(8, '0'); //有功电能示值整数位及小数位个数 + string dataDigit = sArray[19].HexTo4BinZero().PadLeft(8, '0'); //有功电能示值整数位及小数位个数 aFN10F10Entity.IntegerBitsNum = dataDigit.Substring(4, 2).BinToDec() + 4; aFN10F10Entity.DecimalPlacesNum = dataDigit.Substring(6, 2).BinToDec() + 1; - string classNo = sArray[26].HexToBin().PadLeft(8, '0');//用户大类号及用户小类号 + string classNo = sArray[26].HexTo4BinZero().PadLeft(8, '0');//用户大类号及用户小类号 aFN10F10Entity.UserCategoryNum = classNo.Substring(0, 4).BinToDec() + 1; aFN10F10Entity.UserCategoryNum = classNo.Substring(4, 4).BinToDec() + 1; aFN10F10Entitys.Add(aFN10F10Entity); diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs index 6f9562e..5305476 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -32,6 +33,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); var data = new AnalysisBaseDto() @@ -40,16 +42,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH DataValue = await GenerateFinalResult(input.UnitData.HexMessageList), ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { @@ -80,7 +82,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH public async Task GenerateFinalResult(List hexMessageList) { AFN10_F66_AnalysisDto entity = new AFN10_F66_AnalysisDto(); - var cycleBin = hexMessageList[4].HexToBin().PadLeft(8, '0'); + var cycleBin = hexMessageList[4].HexTo4BinZero().PadLeft(8, '0'); var cycleUnitBin = cycleBin.Substring(0, 2); var cycleValueBin = cycleBin.Substring(2, 6); diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs index 9636477..48aa519 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -28,6 +29,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); var data = new AnalysisBaseDto() { @@ -35,16 +37,16 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0AH DataValue = input.UnitData.HexMessageList[4].Equals("55"), ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(MeterTypeEnum.Focus.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.FocusId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.Address; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; data.DeviceType = MeterTypeEnum.Focus; - data.FocusId = ammeterInfo.FocusId; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs index 127b177..35c258f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs @@ -4,6 +4,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -34,6 +35,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); ArgumentNullException.ThrowIfNull(input.A.A3?.D1_D7); UnitDataAnalysis>> unitDataAnalysis = new UnitDataAnalysis>> @@ -55,17 +57,17 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH List> list = GenerateFinalResult(2, datas, "正向有功电能示值", input.AFN_FC.AFN, input.DT.Fn); if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code,input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs index b0685b9..3f28d97 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -33,22 +34,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); List> list = GenerateFinalResult(2, datas, "正向无功电能示值", input.AFN_FC.AFN, input.DT.Fn); if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs index 92e9b89..887e982 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -34,22 +35,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); List> list = GenerateFinalResult(2, datas, "反向有功总电能示值", input.AFN_FC.AFN, input.DT.Fn); if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs index 7fb4ec2..55ab674 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -35,23 +36,24 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; List> list = GenerateFinalResult(2, datas, "反向无功电能示值", dataType); if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs index cec80bc..13541e3 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,22 +37,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string itemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(datas, "当月正向有功最大需量及发生时间", itemType); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } - + UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { Code = input.A.Code!, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs index 355dae5..1a32132 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,21 +37,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnit(input.UnitData.HexMessageList); string itemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(datas, itemType,"上月(上一结算日)正向有功最大需量及发生时间"); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID=ammeterInfo.DatabaseBusiID; - data.DeviceAddress= ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } + UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { Code = input.A.Code!, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs index 4c36960..a95bd09 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,21 +37,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); ArgumentNullException.ThrowIfNull(input.AFN_FC.AFN); ArgumentNullException.ThrowIfNull(input.DT.Fn); string itemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(input.UnitData.HexMessageList, itemType); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } + UnitDataAnalysis> dto = new UnitDataAnalysis> { Code = input.A.Code!, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs index af324f6..e6e6096 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -37,6 +38,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List remarks = new List() { "当前总有功功率", "当前A相有功功率", "当前B相有功功率", "当前C相有功功率", "当前总无功功率", "当前A相无功功率", "当前B相无功功率", "当前C相无功功率", "当前总功率因数", "当前A相功率因数", "当前B相功率因数", "当前C相功率因数", "当前A相电压", "当前B相电压", "当前C相电压", "当前A相电流", "当前C相电流", "当前 C相电流", "当前零序电流", "当前总视在功率", "当前A相视在功率", "当前B相视在功率", "当前C相视在功率" }; List> list = new List>(); @@ -68,17 +70,17 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH } if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].ItemType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs index 234a0fc..a54db8c 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs @@ -12,6 +12,7 @@ using JiShe.CollectBus.Protocol.T37612012.AnalysisData; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; using static FreeSql.Internal.GlobalFilter; +using JiShe.CollectBus.IotSystems.Devices; namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH { @@ -36,19 +37,20 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); string itemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; var data = await GenerateFinalResultAsync(input.UnitData.HexMessageList, itemType); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs index d4ecf6c..fd7dd30 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -35,6 +36,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); int rationgCount = input.UnitData.HexMessageList!.GetRatingCount(23, 1); @@ -46,15 +48,15 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH DataValue = await AnalysisDataUnit(input.UnitData.HexMessageList, rationgCount), ItemType= $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs index 3945a8e..257a666 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -36,7 +37,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH try { ArgumentNullException.ThrowIfNull(input); - + ArgumentNullException.ThrowIfNull(input.A.Code); List data = await AnalysisDataUnitAsync(input.UnitData?.HexMessageList!); List remarks = new List() { "Uab/Ua 相位角", "Ub 相位角", "Ucb/Uc 相位角", "Ia 相位角", "Ib 相位角", "Ic 相位角" }; List> list = new List>(); @@ -64,17 +65,17 @@ namespace JiShe.CollectBus.Protocol.T37612012.AFN_0CH } if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(list[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F100_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F100_Analysis.cs index 4dc5ff0..8fbad80 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F100_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F100_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -33,27 +35,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "反向无功总电能量"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "反向无功总电能量"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -66,7 +69,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F101_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F101_Analysis.cs index 030fb1f..10f52b2 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F101_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F101_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,26 +34,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "正向有功总电能示值"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "正向有功总电能示值"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F102_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F102_Analysis.cs index bfe05b2..e40c2e8 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F102_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F102_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,6 +33,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); @@ -38,21 +41,21 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "正向无功总电能示值"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "正向无功总电能示值"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F103_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F103_Analysis.cs index 4cdba9e..ed7d4c1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F103_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F103_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,6 +34,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); @@ -39,21 +42,21 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH string itemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, itemType, "反向有功总电能示值"); + List> list = datas.GenerateFinalResultTd_c(3, density, itemType, "反向有功总电能示值"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F104_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F104_Analysis.cs index 7558385..6b0585e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F104_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F104_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,27 +34,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "反向无功总电能示值"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "反向无功总电能示值"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F105_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F105_Analysis.cs index b31dd10..78eadd8 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F105_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F105_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,27 +34,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "功率因数"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "功率因数"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F106_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F106_Analysis.cs index 7ae5776..ff5e8e6 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F106_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F106_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,27 +34,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "A相功率因数"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "A相功率因数"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F107_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F107_Analysis.cs index 1c400b5..6f26aa9 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F107_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F107_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,26 +34,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "B相功率因数"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "B相功率因数"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度,注意这里会兼容存储做判断 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F108_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F108_Analysis.cs index c3b0fd5..ced6c30 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F108_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F108_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,27 +34,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "C相功率因数"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "C相功率因数"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F11_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F11_Analysis.cs index 1bd0717..becaf19 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F11_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F11_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; using YamlDotNet.Core.Tokens; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH @@ -33,25 +35,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = GenerateFinalResult(datas,3, dataType, "抄表日冻结电能表正向有功最大需量及发生时间"); + List> list = GenerateFinalResult(datas,3, dataType, "抄表日冻结电能表正向有功最大需量及发生时间"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F145_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F145_Analysis.cs index d21fc7a..7ffa444 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F145_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F145_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,26 +34,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "一象限无功电能示值"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "一象限无功电能示值"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F146_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F146_Analysis.cs index 4e85957..e5d011f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F146_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F146_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -39,20 +41,20 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "四象限无功电能示值"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "四象限无功电能示值"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F147_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F147_Analysis.cs index 8f0f934..4ec9e9f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F147_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F147_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,26 +34,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "二象限无功电能示值"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "二象限无功电能示值"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F148_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F148_Analysis.cs index 66f4715..d10dcce 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F148_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F148_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,27 +34,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "三象限无功电能示值"); + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "三象限无功电能示值"); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F161_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F161_Analysis.cs index 582c9a1..382134e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F161_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F161_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,27 +33,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType,timeSpan, "正向有功总电能示值").IsValidData(new List() { "0D_161", "0D_161_1", "0D_161_2", "0D_161_3", "0D_161_4" }); + List> list = datas.GenerateFinalResultTd_d(3, dataType,timeSpan, "正向有功总电能示值").IsValidData(new List() { "0D_161", "0D_161_1", "0D_161_2", "0D_161_3", "0D_161_4" }); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F162_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F162_Analysis.cs index 039c4cb..90991c9 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F162_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F162_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "正向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_162", "0D_162_1", "0D_162_2", "0D_162_3", "0D_162_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "正向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_162", "0D_162_1", "0D_162_2", "0D_162_3", "0D_162_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F163_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F163_Analysis.cs index ad4d2aa..e2bb0b0 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F163_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F163_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,28 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "反向有功总电能示值").IsValidData(new List() { "0D_163", "0D_163_1", "0D_163_2", "0D_163_3", "0D_163_4" }); + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "反向有功总电能示值").IsValidData(new List() { "0D_163", "0D_163_1", "0D_163_2", "0D_163_3", "0D_163_4" }); - if (data.Count > 0) + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F164_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F164_Analysis.cs index 93f0a7c..c636e4c 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F164_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F164_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结反向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_164", "0D_164_1", "0D_164_2", "0D_164_3", "0D_164_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结反向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_164", "0D_164_1", "0D_164_2", "0D_164_3", "0D_164_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F165_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F165_Analysis.cs index 934e4fc..d69b3a1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F165_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F165_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结一象限无功电能示值").IsValidData(new List() { "0D_165", "0D_165_1", "0D_165_2", "0D_165_3", "0D_165_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结一象限无功电能示值").IsValidData(new List() { "0D_165", "0D_165_1", "0D_165_2", "0D_165_3", "0D_165_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F166_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F166_Analysis.cs index bded83e..b02c99b 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F166_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F166_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结二象限无功电能示值").IsValidData(new List() { "0D_166", "0D_166_1", "0D_166_2", "0D_166_3", "0D_166_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结二象限无功电能示值").IsValidData(new List() { "0D_166", "0D_166_1", "0D_166_2", "0D_166_3", "0D_166_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F167_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F167_Analysis.cs index a969778..fb99e97 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F167_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F167_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结三象限无功电能示值").IsValidData(new List() { "0D_167", "0D_167_1", "0D_167_2", "0D_167_3", "0D_167_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结三象限无功电能示值").IsValidData(new List() { "0D_167", "0D_167_1", "0D_167_2", "0D_167_3", "0D_167_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F168_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F168_Analysis.cs index 2696dab..4b7d39a 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F168_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F168_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,26 +33,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结四象限无功电能示值").IsValidData(new List() { "0D_168", "0D_168_1", "0D_168_2", "0D_168_3", "0D_168_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "日冻结四象限无功电能示值").IsValidData(new List() { "0D_168", "0D_168_1", "0D_168_2", "0D_168_3", "0D_168_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F177_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F177_Analysis.cs index 027d64c..e147c17 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F177_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F177_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,25 +33,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结正向有功电能示值").IsValidData(new List() { "0D_177", "0D_177_1", "0D_177_2", "0D_177_3", "0D_177_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结正向有功电能示值").IsValidData(new List() { "0D_177", "0D_177_1", "0D_177_2", "0D_177_3", "0D_177_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -61,7 +64,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F178_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F178_Analysis.cs index 3ee3193..d60bd89 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F178_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F178_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,25 +34,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结正向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_178", "0D_178_1", "0D_178_2", "0D_178_3", "0D_178_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结正向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_178", "0D_178_1", "0D_178_2", "0D_178_3", "0D_178_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F179_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F179_Analysis.cs index e0e866e..b685ec3 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F179_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F179_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,25 +34,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "反向有功总电能示值").IsValidData(new List() { "0D_179", "0D_179_1", "0D_179_2", "0D_179_3", "0D_179_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "反向有功总电能示值").IsValidData(new List() { "0D_179", "0D_179_1", "0D_179_2", "0D_179_3", "0D_179_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F180_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F180_Analysis.cs index 3cbec39..9c42518 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F180_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F180_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,25 +33,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结反向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_180", "0D_180_1", "0D_180_2", "0D_180_3", "0D_180_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结反向无功(组合无功 1)电能示值").IsValidData(new List() { "0D_180", "0D_180_1", "0D_180_2", "0D_180_3", "0D_180_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -61,7 +64,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F181_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F181_Analysis.cs index c241e2c..24c4195 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F181_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F181_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,25 +34,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结一象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_181", "0D_181_1", "0D_181_2", "0D_181_3", "0D_181_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结一象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_181", "0D_181_1", "0D_181_2", "0D_181_3", "0D_181_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F182_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F182_Analysis.cs index d5cab85..820dfc1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F182_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F182_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,25 +34,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结二象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_182", "0D_182_1", "0D_182_2", "0D_182_3", "0D_182_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结二象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_182", "0D_182_1", "0D_182_2", "0D_182_3", "0D_182_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F183_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F183_Analysis.cs index f320aa3..45307ce 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F183_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F183_Analysis.cs @@ -2,12 +2,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -31,25 +33,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结三象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_183", "0D_183_1", "0D_183_2", "0D_183_3", "0D_183_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结三象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_183", "0D_183_1", "0D_183_2", "0D_183_3", "0D_183_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -61,7 +64,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F184_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F184_Analysis.cs index 12e9e5f..7714ed2 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F184_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F184_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,25 +34,26 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-01 00:00:00"; - List> data = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结四象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_184", "0D_184_1", "0D_184_2", "0D_184_3", "0D_184_4" }); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_m(3, dataType, timeSpan, "月冻结四象限无功电能示值(总、费率 1~M)").IsValidData(new List() { "0D_184", "0D_184_1", "0D_184_2", "0D_184_3", "0D_184_4" }); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -62,7 +65,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F189_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F189_Analysis.cs index 1f406e1..c826ffb 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F189_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F189_Analysis.cs @@ -9,6 +9,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -32,26 +34,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string timeSpan = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "抄表日冻结正向有功最大需量及发生时间"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_d(3, dataType, timeSpan, "抄表日冻结正向有功最大需量及发生时间"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -63,7 +66,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F190_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F190_Analysis.cs index d11be74..d6bf837 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F190_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F190_Analysis.cs @@ -3,6 +3,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -33,21 +34,22 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(datas, "抄表日冻结正向无功最大需量及发生时间", dataType); - - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F193_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F193_Analysis.cs index 76a4e4d..f6d698e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F193_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F193_Analysis.cs @@ -11,6 +11,7 @@ using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; using static FreeSql.Internal.GlobalFilter; +using JiShe.CollectBus.IotSystems.Devices; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,21 +35,22 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(datas, "月冻结正向有功最大需量及发生时间", dataType); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F195_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F195_Analysis.cs index 0fc8ad0..ceda00c 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F195_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F195_Analysis.cs @@ -11,6 +11,7 @@ using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; using static FreeSql.Internal.GlobalFilter; +using JiShe.CollectBus.IotSystems.Devices; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,21 +35,22 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; AnalysisBaseDto data = GenerateFinalResult(datas, "月冻结反向有功最大需量及发生时间", dataType); - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F19_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F19_Analysis.cs index 4f0c5c3..531b234 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F19_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F19_Analysis.cs @@ -12,6 +12,8 @@ using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using YamlDotNet.Core.Tokens; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -35,24 +37,25 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = GenerateFinalResult(datas, dataType, "月冻结电能表正向有功最大需量及发生时间"); - if (data.Count > 0) + List> list = GenerateFinalResult(datas, dataType, "月冻结电能表正向有功最大需量及发生时间"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F3_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F3_Analysis.cs index cb456cd..7ed137e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F3_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F3_Analysis.cs @@ -12,6 +12,8 @@ using Volo.Abp.Domain.Entities; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -35,6 +37,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); @@ -42,20 +45,20 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH //冻结数据时标 var time = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; - List> data = GenerateFinalResult(datas,dataType, "日冻结正向有/无功最大需量及发生时间"); - if (data.Count > 0) + List> list = GenerateFinalResult(datas,dataType, "日冻结正向有/无功最大需量及发生时间"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -67,7 +70,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F4_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F4_Analysis.cs index 0fddd41..c99a894 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F4_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F4_Analysis.cs @@ -11,6 +11,8 @@ using AutoMapper.Internal.Mappers; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,6 +36,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); @@ -41,20 +44,20 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH //冻结数据时标 var time = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00"; - List> data = GenerateFinalResult(datas, dataType, "日冻结反向有/无功最大需量及发生时间"); - if (data.Count > 0) + List> list = GenerateFinalResult(datas, dataType, "日冻结反向有/无功最大需量及发生时间"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -66,7 +69,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = 1,//密度-间隔, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F81_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F81_Analysis.cs index b8ffddd..4bf1e2e 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F81_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F81_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -33,26 +35,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "有功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "有功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F82_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F82_Analysis.cs index c5ee665..0c4aa75 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F82_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F82_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "A相有功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "A相有功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F83_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F83_Analysis.cs index 853aeeb..ef77a80 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F83_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F83_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "B相有功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "B相有功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F84_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F84_Analysis.cs index 2d0d100..66216bc 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F84_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F84_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -33,26 +35,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "C相有功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "C相有功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F85_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F85_Analysis.cs index 6c063cd..b9103b8 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F85_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F85_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "无功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "无功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F86_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F86_Analysis.cs index af1a33e..1748a3d 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F86_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F86_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "A相无功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "A相无功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F87_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F87_Analysis.cs index 82b3b97..26dfcd1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F87_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F87_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -33,26 +35,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "B相无功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "B相无功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F88_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F88_Analysis.cs index 598f9fd..29fb978 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F88_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F88_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "C相无功功率曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "C相无功功率曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F89_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F89_Analysis.cs index 89d5f71..330cf0a 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F89_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F89_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "A相电压曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "A相电压曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F90_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F90_Analysis.cs index 7ab37b9..3033c76 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F90_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F90_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "B相电压曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "B相电压曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F91_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F91_Analysis.cs index 27cfbff..b18d244 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F91_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F91_Analysis.cs @@ -3,12 +3,14 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.T37612012.Appendix; using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -33,26 +35,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "C相电压曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "C相电压曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -64,7 +67,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F92_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F92_Analysis.cs index 7013558..1d1bff5 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F92_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F92_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "A相电流曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "A相电流曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F93_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F93_Analysis.cs index 5a86c82..bbd8f0d 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F93_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F93_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "B相电流曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "B相电流曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F94_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F94_Analysis.cs index c73619f..19e6d2f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F94_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F94_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "C相电流曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "C相电流曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F95_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F95_Analysis.cs index 3633567..842496f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F95_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F95_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "测量点零序电流曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "测量点零序电流曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F97_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F97_Analysis.cs index 1e04f6f..8ce25e1 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F97_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F97_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "正向有功总电能量曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "正向有功总电能量曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F98_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F98_Analysis.cs index c3fe639..6da01d5 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F98_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F98_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "正向无功总电能量曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "正向无功总电能量曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F99_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F99_Analysis.cs index ac93186..33b8560 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F99_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0DH/AFN13_F99_Analysis.cs @@ -10,6 +10,8 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.Devices; +using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH { @@ -34,26 +36,27 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); int density = Convert.ToInt32(Convert.ToInt32(datas[1]).GetEnumDescription(typeof(DensityEnums))); string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}"; - List> data = datas.GenerateFinalResultTd_c(3, density, dataType, "反向有功总电能量曲线"); - if (data.Count > 0) + List> list = datas.GenerateFinalResultTd_c(3, density, dataType, "反向有功总电能量曲线"); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.MeterId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.AmmerterAddress; - item.FocusId = ammeterInfo.FocusId; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; + item.FocusId = deviceInfo.FocusId; }); } } @@ -65,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH Pn = input.DA.Pn, MSA = input.A.A3!.D1_D7!, PSEQ = input.SEQ.PSEQ, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, TimeDensity = density,//密度-间隔分钟数, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0EH/AFN14_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0EH/AFN14_F1_Analysis.cs index 2c29612..7dc7275 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0EH/AFN14_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0EH/AFN14_F1_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -9,6 +10,7 @@ using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0EH { @@ -31,8 +33,9 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0EH { try { - ArgumentNullException.ThrowIfNull(nameof(input)); - ArgumentNullException.ThrowIfNull(nameof(input.UnitData.HexMessageList)); + ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); + ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); int erc = input.UnitData.HexMessageList![8].HexToDec(); bool isOnOffPower = erc.Equals(14) ? true : false; if (!isOnOffPower) @@ -42,21 +45,21 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0EH return await Task.FromResult(true); } - List> data = AnalysisDataUnit(input.UnitData.HexMessageList); - if (data.Count > 0) + List> list = AnalysisDataUnit(input.UnitData.HexMessageList); + if (list.Count > 0) { - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data[0].DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) { - data.ForEach(item => + list.ForEach(item => { - item.ProjectId = ammeterInfo.ProjectID; - item.DeviceId = ammeterInfo.FocusId; - item.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - item.DeviceAddress = ammeterInfo.Address; + item.ProjectId = deviceInfo.ProjectID; + item.DeviceId = deviceInfo.MeterId; + item.DatabaseBusiID = deviceInfo.DatabaseBusiID; + item.DeviceAddress = deviceInfo.MeterAddress; item.DeviceType = MeterTypeEnum.Focus; - item.FocusId = ammeterInfo.FocusId; + item.FocusId = deviceInfo.FocusId; }); } } @@ -66,7 +69,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0EH AFN = input.AFN_FC.AFN, Fn = input.DT.Fn, Pn = input.DA.Pn, - Data = data, + Data = list, ReceivedHexMessage = input.BaseHexMessage.HexMessageString, MessageId = input.MessageId, ReceivedTime = input.ReceivedTime, diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F101_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F101_Analysis.cs index 27bee6b..284aaab 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F101_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F101_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -30,6 +31,7 @@ namespace GatherService.WattMeter.AnalysisData.AFN_10H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageList); var data = new AnalysisBaseDto() { @@ -37,15 +39,15 @@ namespace GatherService.WattMeter.AnalysisData.AFN_10H DataValue = AnalysisDataUnit(input.UnitData.HexMessageList), ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> dto = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F1_Analysis.cs index 5f79647..d760e94 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F1_Analysis.cs @@ -1,5 +1,8 @@ using GatherService.WattMeter.AnalysisData.AFN_10H; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -21,11 +24,12 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H { private readonly ILogger _logger; private readonly AnalysisStrategyContext _analysisStrategyContext; - - public AFN16_F1_Analysis(ILogger logger, AnalysisStrategyContext analysisStrategyContext) + private readonly DataStorage _dataStorage; + public AFN16_F1_Analysis(ILogger logger, AnalysisStrategyContext analysisStrategyContext, DataStorage dataStorage) { _logger = logger; _analysisStrategyContext = analysisStrategyContext; + _dataStorage = dataStorage; } public async Task ExecuteAsync(TB3761 input, Action? result = null) @@ -33,6 +37,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.BaseHexMessage.HexMessageList); ArgumentNullException.ThrowIfNull(input.UnitData.HexMessageString); // TODO: 待定,等确认如何匹配规则 @@ -44,10 +49,45 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H { result?.Invoke(dto); }); - //else if (value.Contains(F10TranspondMatch.ReadData))//读取电表地址 - // result = "AFN16_F105_Analysis"; + else if (value.Contains(F10TranspondMatch.JumpClosingNormal) || value.Contains(F10TranspondMatch.JumpClosingError))//跳合闸 + await _analysisStrategyContext.ExecuteAsync(nameof(AFN16_F98_Analysis), input, dto => + { + result?.Invoke(dto); + }); else { + //TODO: 写入1条日志 + var data = new AnalysisBaseDto() + { + FiledDesc = "透明转发", + ItemType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}" + }; + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code); + if (deviceInfo != null) + { + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.FocusId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.FocusAddress; + data.DeviceType = MeterTypeEnum.Focus; + data.FocusId = deviceInfo.FocusId; + } + UnitDataAnalysis> dto = new UnitDataAnalysis> + { + Code = input.A.Code, + AFN = input.AFN_FC.AFN, + Fn = input.DT.Fn, + Pn = input.DA.Pn, + Data = data, + ReceivedHexMessage = input.BaseHexMessage.HexMessageString, + MessageId = input.MessageId, + ReceivedTime = input.ReceivedTime, + DensityUnit = DensityUnit.None, + TimeDensity = -1, + DataType = IOTDBDataTypeConst.Log + }; + await _dataStorage.SaveDataToIotDbAsync(dto); _logger.LogWarning($"未能找到透明传发解析方式:{input.BaseHexMessage.HexMessageString}"); } } @@ -56,7 +96,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H } catch (Exception ex) { - _logger.LogError(ex, $"10_101解析失败:{input.A?.Code}-{input.DT?.Fn ?? 0}-{input?.BaseHexMessage?.HexMessageString},{ex.Message}"); + _logger.LogError(ex, $"10_1解析失败:{input.A?.Code}-{input.DT?.Fn ?? 0}-{input?.BaseHexMessage?.HexMessageString},{ex.Message}"); } return await Task.FromResult(false); diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F97_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F97_Analysis.cs index 0da9f88..0863213 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F97_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F97_Analysis.cs @@ -1,9 +1,11 @@ -using GatherService.WattMeter.AnalysisData.AFN_10H; +using DeviceDetectorNET.Parser.Device; +using GatherService.WattMeter.AnalysisData.AFN_10H; using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; using JiShe.CollectBus.Protocol.Interfaces; @@ -38,20 +40,21 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); AnalysisBaseDto data = GenerateFinalResult(datas); - - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn, datas[1]); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { @@ -85,8 +88,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H private AnalysisBaseDto GenerateFinalResult(List data) { AnalysisBaseDto meter = new AnalysisBaseDto(); - - var errorCode = data[7].CheckErrorCode(); + meter.DeviceType = MeterTypeEnum.Ammeter; + var errorCode = data[4].CheckErrorCode(); if (errorCode != null) { meter.ValidData = false; @@ -94,7 +97,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H } else { - if(decimal.TryParse(data[7], out decimal value)) + if(decimal.TryParse(data[4], out decimal value)) meter.DataValue = value; } @@ -131,7 +134,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H string dataMark = string.Join("",dataField.GetRange(0, 4).ReduceHex33(true)); values.Add(dataMark);//数据标识 var readValue = dataField.GetRange(4, len - 4).ReduceHex33(true);//值 - await _analysisStrategyContext.ExecuteAsync>($" Appendix_{dataMark}", readValue, (value) => + await _analysisStrategyContext.ExecuteAsync>($"Appendix_{dataMark}", readValue, (value) => { values.Add(value.ToString()); }); diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F98_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F98_Analysis.cs index e54cc09..bb504e9 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F98_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_10H/AFN16_F98_Analysis.cs @@ -2,6 +2,7 @@ using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.Protocol; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; @@ -33,6 +34,7 @@ namespace GatherService.WattMeter.AnalysisData.AFN_10H try { ArgumentNullException.ThrowIfNull(input); + ArgumentNullException.ThrowIfNull(input.A.Code); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); List datas = AnalysisDataUnit(input.UnitData.HexMessageList); @@ -44,15 +46,15 @@ namespace GatherService.WattMeter.AnalysisData.AFN_10H ItemType= "10_98", }; - // 查询电表信息 - AmmeterInfo ammeterInfo = await _dataStorage.GetMeterInfoAsync(data.DeviceType.ToString(), "15"); - if (ammeterInfo != null) + // 查询设备信息 + DeviceInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn); + if (deviceInfo != null) { - data.ProjectId = ammeterInfo.ProjectID; - data.DeviceId = ammeterInfo.MeterId; - data.DatabaseBusiID = ammeterInfo.DatabaseBusiID; - data.DeviceAddress = ammeterInfo.AmmerterAddress; - data.FocusId = ammeterInfo.FocusId; + data.ProjectId = deviceInfo.ProjectID; + data.DeviceId = deviceInfo.MeterId; + data.DatabaseBusiID = deviceInfo.DatabaseBusiID; + data.DeviceAddress = deviceInfo.MeterAddress; + data.FocusId = deviceInfo.FocusId; } UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs index f4a8371..7a1bc75 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs @@ -1,26 +1,33 @@ -using JiShe.CollectBus.Common; +using FreeRedis; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Encrypt; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; +using JiShe.CollectBus.FreeRedis; using JiShe.CollectBus.IoTDB.Context; using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Options; using JiShe.CollectBus.IoTDB.Provider; using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.IotSystems.LogRecord; using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Diagnostics; using System.Diagnostics.Metrics; using System.Threading.Channels; +using TouchSocket.Core; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; +using YamlDotNet.Core.Tokens; using static FreeSql.Internal.GlobalFilter; using static JiShe.CollectBus.Common.Consts.T37612012PacketItemCodeConst; @@ -30,22 +37,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData { private readonly IGuidGenerator _guidGenerator; private readonly IIoTDbProvider _dbProvider; - private readonly ServerApplicationOptions _applicationOptions; - private readonly IoTDBRuntimeContext _runtimeContext; + private readonly ServerApplicationOptions _applicationOptions; private readonly ILogger _logger; - + private readonly IMemoryCache _imemoryCache; + private readonly IFreeRedisProvider _freeRedisProvider; + private RedisClient Instance { get; set; } public DataStorage(IIoTDbProvider dbProvider, IOptions applicationOptions, - IGuidGenerator guidGenerator, IoTDBRuntimeContext runtimeContext, ILogger logger) + IGuidGenerator guidGenerator, ILogger logger, IMemoryCache memoryCache, IFreeRedisProvider freeRedisProvider) { _dbProvider= dbProvider; _applicationOptions = applicationOptions.Value; - _guidGenerator= guidGenerator; - _runtimeContext= runtimeContext; + _guidGenerator= guidGenerator; _logger= logger; + _imemoryCache = memoryCache; + _freeRedisProvider = freeRedisProvider; + Instance = _freeRedisProvider.Instance; } - - /// /// 日志保存通道写入 /// @@ -64,21 +72,43 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData await channelWriter.WriteAsync(dataItems); } + /// - /// 获取缓存电表信息 + /// 获取缓存设备信息 /// /// /// /// - public async Task GetMeterInfoAsync(string meterType,string timeDensity="15") + public async Task GetDeviceInfoAsync(string code,int pn=1,string meterAddress=null) { - var redisCacheMeterInfoHashKeyTemp = $"{string.Format(RedisConst.CacheDeviceInfoHashKey, _applicationOptions.SystemType, _applicationOptions.ServerTagName, meterType, timeDensity)}"; - // TODO:临时写死,等确认后如何取再调整 - return await Task.FromResult(new AmmeterInfo() { - ProjectID = 10000, - MeterId=11111, - FocusId=22222 + string redisCacheDeviceInfoHashKey = $"{string.Format(RedisConst.CacheDeviceInfoHashKey, _applicationOptions.SystemType, _applicationOptions.ServerTagName)}"; + string deviceKey= $"{code}:{pn}"; + var deviceInfo= await _imemoryCache.GetOrCreateAsync(deviceKey, async entry => + { + List devices= await Instance.HGetAsync>(redisCacheDeviceInfoHashKey, code) ?? new List(); + var data = devices.Where(s => s.MeteringCode == pn).FirstOrDefault(); + if (data != null) + entry.SetSlidingExpiration(TimeSpan.FromMinutes(5)); + else + entry.SetSlidingExpiration(TimeSpan.FromSeconds(5)); + return data ?? default; }); + if (deviceInfo == null && !string.IsNullOrWhiteSpace(meterAddress)) + { + // TODO:透明转发回来的pn为0情况 + string deviceAddressKey = $"{code}:{meterAddress}"; + deviceInfo = await _imemoryCache.GetOrCreateAsync(deviceAddressKey, async entry => + { + List devices = await Instance.HGetAsync>(redisCacheDeviceInfoHashKey, code) ?? new List(); + var data = devices.Where(s => s.MeterAddress == meterAddress).FirstOrDefault(); + if (data != null) + entry.SetSlidingExpiration(TimeSpan.FromMinutes(5)); + else + entry.SetSlidingExpiration(TimeSpan.FromSeconds(5)); + return data ?? default; + }); + } + return deviceInfo; } /// @@ -127,8 +157,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData Timestamps = data.TimeSpan!.Value.GetFormatTime(analysisBaseDto.DensityUnit, analysisBaseDto.TimeDensity).GetDateTimeOffset().ToUnixTimeNanoseconds(), SingleMeasuring = (data.FiledName ?? string.Empty, data.DataValue ?? default) }; - _runtimeContext.UseTableSessionPool = true; // 使用表模型池 - var taskSendInfo = await _dbProvider.QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 }); + + var taskSendInfo = await _dbProvider.GetSessionPool(true).QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 }); var taskData = taskSendInfo?.Items.FirstOrDefault(); if (taskData != null) { @@ -172,14 +202,12 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData ScoreValue = $"{analysisBaseDto.Code}.{taskMark}".Md5Fun(), ReceivedTime = analysisBaseDto.ReceivedTime, }; - } - _runtimeContext.UseTableSessionPool = true; // 使树模型池 - await _dbProvider.InsertAsync(taskData); + } + await _dbProvider.GetSessionPool(true).InsertAsync(taskData); //如果无字段名,则不保存数据 if (!string.IsNullOrWhiteSpace(data.FiledName)) - { - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(meter); + { + await _dbProvider.GetSessionPool(false).InsertAsync(meter); } return await Task.FromResult(true); } @@ -235,9 +263,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData DataType = analysisBaseDto.DataType, Timestamps = item.TimeSpan!.Value.GetFormatTime(analysisBaseDto.DensityUnit, analysisBaseDto.TimeDensity).GetDateTimeOffset().ToUnixTimeNanoseconds(), // TODO:这里暂时格式化15分钟数据,需要进行调整 SingleMeasuring =(item.FiledName ?? string.Empty, item.DataValue ?? default) - }; - _runtimeContext.UseTableSessionPool = true; // 使用表模型池 - var taskSendInfo = await _dbProvider.QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 }); + }; + var taskSendInfo = await _dbProvider.GetSessionPool(true).QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 }); var taskData = taskSendInfo?.Items.FirstOrDefault(); if (taskData != null) { @@ -289,13 +316,11 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData treeModelSingleMeasuringEntities.Add(meter); } } - // 批量保存数据 - _runtimeContext.UseTableSessionPool = true; // 使树模型池 - await _dbProvider.BatchInsertAsync(meterReadingTelemetryPacketInfos); + // 批量保存数据 + await _dbProvider.GetSessionPool(true).BatchInsertAsync(meterReadingTelemetryPacketInfos); if (treeModelSingleMeasuringEntities.Count > 0) - { - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.BatchInsertAsync(treeModelSingleMeasuringEntities); + { + await _dbProvider.GetSessionPool(false).BatchInsertAsync(treeModelSingleMeasuringEntities); } return await Task.FromResult(true); } @@ -324,12 +349,11 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData DeviceId = $"{data.DeviceId}", DeviceType = $"{data.DeviceType}", ProjectId = $"{data.ProjectId}", - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, Timestamps = timestamps, SingleMeasuring = (data.FiledName!, data.DataValue!) - }; - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeData); + }; + await _dbProvider.GetSessionPool(false).InsertAsync(treeData); // 数据帧 var treeFrameData = new TreeModelSingleMeasuringEntity() { @@ -337,13 +361,12 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData DeviceId = $"{data.DeviceId}", DeviceType = $"{data.DeviceType}", ProjectId = $"{data.ProjectId}", - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, Timestamps = timestamps, SingleMeasuring = (ConcentratorStatusFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty) }; - - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeFrameData); + + await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData); // 时间 var treeRecordingTimeData = new TreeModelSingleMeasuringEntity() @@ -353,11 +376,10 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData DeviceType = $"{data.DeviceType}", ProjectId = $"{data.ProjectId}", Timestamps = timestamps, - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, SingleMeasuring = (ConcentratorStatusFieldConst.RecordingTime, data.TimeSpan.HasValue ? data.TimeSpan.Value : DateTime.Now) - }; - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeRecordingTimeData); + }; + await _dbProvider.GetSessionPool(true).InsertAsync(treeRecordingTimeData); // 新建 string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ); @@ -391,9 +413,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData ReceivedRemark = data.ErrorCodeMsg ?? string.Empty, ScoreValue = $"{analysisBaseDto.Code}.{taskMark}".Md5Fun(), ReceivedTime=analysisBaseDto.ReceivedTime, - }; - _runtimeContext.UseTableSessionPool = true; // 使表模型池 - await _dbProvider.InsertAsync(taskData); + }; + await _dbProvider.GetSessionPool(true).InsertAsync(taskData); return await Task.FromResult(true); } @@ -425,25 +446,23 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData DeviceId = $"{item.DeviceId}", DeviceType = $"{item.DeviceType}", ProjectId = $"{item.ProjectId}", - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, Timestamps = timestamps, SingleMeasuring = (item.FiledName!, item.DataValue!) - }; - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeData); + }; + await _dbProvider.GetSessionPool(false).InsertAsync(treeData); // 数据帧 var treeFrameData = new TreeModelSingleMeasuringEntity() { SystemName = _applicationOptions.SystemType, DeviceType = $"{item.DeviceType}", ProjectId = $"{item.ProjectId}", - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, Timestamps = timestamps, SingleMeasuring = (ConcentratorStatusFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty) }; - - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeFrameData); + + await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData); // 时间 var treeRecordingTimeData = new TreeModelSingleMeasuringEntity() @@ -451,12 +470,11 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData SystemName = _applicationOptions.SystemType, DeviceType = $"{item.DeviceType}", ProjectId = $"{item.ProjectId}", - DataType = analysisBaseDto.DataType, + DataType = IOTDBDataTypeConst.Status, Timestamps = timestamps, SingleMeasuring = (ConcentratorStatusFieldConst.RecordingTime, item.TimeSpan.HasValue ? item.TimeSpan.Value : DateTime.Now) - }; - _runtimeContext.UseTableSessionPool = false; // 使树模型池 - await _dbProvider.InsertAsync(treeRecordingTimeData); + }; + await _dbProvider.GetSessionPool(false).InsertAsync(treeRecordingTimeData); // 新建 string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ); @@ -495,9 +513,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData meterReadingTelemetryPacketInfos.Add(taskData); } if (meterReadingTelemetryPacketInfos.Count > 0) - { - _runtimeContext.UseTableSessionPool = true; // 使表模型池 - await _dbProvider.BatchInsertAsync(meterReadingTelemetryPacketInfos); + { + await _dbProvider.GetSessionPool(true).BatchInsertAsync(meterReadingTelemetryPacketInfos); } return await Task.FromResult(true); } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs index 8c71343..da699e2 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs @@ -19,18 +19,19 @@ namespace JiShe.CollectBus.Protocol.T37612012.Appendix { try { - if (data.Count != 2) - return null; - var value = string.Join(".", data); - var values= new List() { "电网频率", "10_97", "1", value }; - result?.Invoke(values); - return Task.FromResult(true); + if (data.Count == 2) + { + var value = string.Join(".", data); + //电网频率 + result?.Invoke(value); + return Task.FromResult(true); + } } catch (Exception ex) { _logger.LogError(ex, $"Appendix_02800002解析失败:{ex.Message}"); - return Task.FromResult(false); } + return Task.FromResult(false); } } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs index 8f3cec4..8a3466f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs @@ -14,7 +14,7 @@ namespace JiShe.CollectBus.Protocol.T37612012 public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddKeyedSingleton(nameof(T37612012ProtocolPlugin)); - + context.Services.AddMemoryCache(); // TODO:先用之前的策略注册方式,后续验证后采用LoadAnalysisStrategy RegisterProtocolAnalysis(context.Services); //LoadAnalysisStrategy(context.Services); diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs index f8bfa78..5540281 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Data; +using System.Reflection; using JiShe.CollectBus.Common.BuildSendDatas; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Models; @@ -55,7 +56,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -80,7 +81,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -105,7 +106,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -129,7 +130,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -154,7 +155,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -178,7 +179,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -203,7 +204,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -227,7 +228,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion @@ -252,13 +253,19 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter,request.DataUnit); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #endregion #region AFN10H 数据转发 public static Telemetry3761PacketResponse AFN10_Fn_Send(Telemetry3761PacketRequest request) { + + var baudRateValue = Build3761SendData.GetBaudreate($"{request.SubRequest.Baudrate}"); + + var dataUnit = Build3761SendData.BuildTransparentForwardingSendDataUnit(request.SubRequest.MeteringPort, baudRateValue, request.DataUnit); + dataUnit.AddRange(Build3761SendData.GetPW()); + var reqParameter = new ReqParameter2() { AFN = AFN.数据转发, @@ -275,8 +282,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.SendData Pn = request.Pn, Fn = request.Fn }; - var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter, request.DataUnit); - return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; + var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter, dataUnit); + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA,Pn = reqParameter.Pn,AFn = (int)reqParameter.AFN,Fn = reqParameter.Fn }; } #region SpecialAmmeter 特殊电表转发 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs index f02efc9..a5d8593 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs @@ -1,4 +1,6 @@ -namespace JiShe.CollectBus.Protocol.T37612012.SendData +using JiShe.CollectBus.Protocol.Models; + +namespace JiShe.CollectBus.Protocol.T37612012.SendData { /// /// 构建3761报文参数 @@ -20,8 +22,13 @@ /// public int Pn { get; set; } + /// + /// 子协议请求 + /// + public SubProtocolBuildRequest SubRequest { get; set; } + /// - /// 透明转发单元 + /// 透明转发数据单元 /// public List DataUnit { get; set; } } diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs index cd4ed6e..64c84b7 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs @@ -15,6 +15,22 @@ /// public int MSA { get; set; } + + /// + /// 帧功能域AFN + /// + public int AFn { get; set; } + + /// + /// 帧功能域FN + /// + public int Fn { get; set; } + + /// + /// 抄读计量点,也就是终端电表对应端口 + /// + public int Pn { get; set; } + /// /// 报文体 /// diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs index b69ff1a..ed82fa0 100644 --- a/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs @@ -212,7 +212,7 @@ namespace JiShe.CollectBus.Protocol.T37612012 if (_tcpService.ClientExists(issuedEventMessage.ClientId)) { await _tcpService.SendAsync(issuedEventMessage.ClientId, issuedEventMessage.Message); - _logger.LogInformation($"集中器地址{issuedEventMessage.ClientId} 登录回复下发内容:{Convert.ToHexString(bytes)}"); + _logger.LogWarning($"集中器地址{issuedEventMessage.ClientId} 登录回复下发内容:{Convert.ToHexString(bytes)}"); // await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, issuedEventMessage); } } diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs index 2d20272..61dfbaa 100644 --- a/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs @@ -47,7 +47,7 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData { var itemCodeArr = request.ItemCode.Split('_'); var c_data = itemCodeArr[0]; - var n_data = itemCodeArr[1]; + var n_data = itemCodeArr[2]; string password = request.Password; string pwdLevel = "02"; @@ -78,7 +78,7 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData { var itemCodeArr = request.ItemCode.Split('_'); var c_data = itemCodeArr[0]; - var n_data = itemCodeArr[1]; + var n_data = itemCodeArr[2]; string password = request.Password; if (!string.IsNullOrWhiteSpace(password) && password.Contains("|")) @@ -98,6 +98,29 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit); return new Telemetry6452007PacketResponse() { Data = dataList }; } - #endregion + #endregion + + #region 读数据 + + /// + /// 变量数据标识编码处理 + /// + /// + /// + public static Telemetry6452007PacketResponse C11_02_Send(Telemetry6452007PacketRequest request) + { + var itemCodeArr = request.ItemCode.Split('_');//11_02_80_00_02 + var c_data = itemCodeArr[0]; + var DI3 = itemCodeArr[1]; + var DI2 = itemCodeArr[2]; + var DI1 = itemCodeArr[3]; + var DI0 = itemCodeArr[4]; + + var dataUnit = new List() { DI3, DI2, DI1, DI0 }; + + var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit); + return new Telemetry6452007PacketResponse() { Data = dataList }; + } + #endregion } } diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketRequest.cs index c367206..b819b91 100644 --- a/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketRequest.cs +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketRequest.cs @@ -1,23 +1,12 @@ -namespace JiShe.CollectBus.Protocol.T6452007.SendData +using JiShe.CollectBus.Protocol.Models; + +namespace JiShe.CollectBus.Protocol.T6452007.SendData { /// /// 构建645报文参数 /// - public class Telemetry6452007PacketRequest + public class Telemetry6452007PacketRequest: SubProtocolBuildRequest { - /// - /// 表地址 - /// - public required string MeterAddress { get; set; } - - /// - /// 密码 - /// - public required string Password { get; set; } - - /// - /// 操作码 - /// - public required string ItemCode { get; set; } + } } diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs index a4f820b..98b1e7f 100644 --- a/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs @@ -93,7 +93,9 @@ namespace JiShe.CollectBus.Protocol.T6452007 //数据转发场景 10H_F1 if (request.ItemCode == T37612012PacketItemCodeConst.AFN10HFN01H && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false) { - var t645PacketHandlerName = $"C{request.SubProtocolRequest.ItemCode}_Send"; + var subItemCodeArr = request.SubProtocolRequest.ItemCode.Split("_"); + var t645PacketHandlerName = $"C{subItemCodeArr[0]}_{subItemCodeArr[1]}_Send";//C1C_01_Send + Telemetry6452007PacketResponse t645PacketResponse = null; if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName @@ -127,6 +129,7 @@ namespace JiShe.CollectBus.Protocol.T6452007 FocusAddress = request.FocusAddress, Fn = fn, Pn = request.Pn, + SubRequest = request.SubProtocolRequest, DataUnit = dataUnit, }); } @@ -136,7 +139,7 @@ namespace JiShe.CollectBus.Protocol.T6452007 return new ProtocolBuildResponse(); } - var result = builderResponse.Adapt(); + var result = builderResponse.Adapt(); result.IsSuccess = true; return await Task.FromResult(result); diff --git a/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs index 2819330..16243a8 100644 --- a/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs +++ b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs @@ -19,7 +19,12 @@ /// 帧功能域FN /// public int Fn { get; set; } - + + /// + /// 抄读计量点,也就是终端电表对应端口 + /// + public int Pn { get; set; } + /// /// 帧序列域SEQ /// diff --git a/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs b/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs index 09a5c55..15526e2 100644 --- a/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs +++ b/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs @@ -10,6 +10,16 @@ /// public required string MeterAddress { get; set; } + /// + /// 波特率 default(2400) + /// + public int Baudrate { get; set; } + + /// + /// 计量端口 + /// + public int MeteringPort { get; set; } + /// /// 密码 /// diff --git a/services/JiShe.CollectBus.Application.Contracts/Subscribers/IWorkerSubscriberAppService.cs b/services/JiShe.CollectBus.Application.Contracts/Subscribers/IWorkerSubscriberAppService.cs index 464537c..e899ce4 100644 --- a/services/JiShe.CollectBus.Application.Contracts/Subscribers/IWorkerSubscriberAppService.cs +++ b/services/JiShe.CollectBus.Application.Contracts/Subscribers/IWorkerSubscriberAppService.cs @@ -1,6 +1,8 @@ -using JiShe.CollectBus.IotSystems.MessageIssueds; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.IotSystems.MessageIssueds; using JiShe.CollectBus.IotSystems.MessageReceiveds; using JiShe.CollectBus.IotSystems.MeterReadingRecords; +using JiShe.CollectBus.Kafka.Attributes; using JiShe.CollectBus.Kafka.Internal; using System.Collections.Generic; using System.Threading.Tasks; @@ -17,37 +19,83 @@ namespace JiShe.CollectBus.Subscribers #region 电表消息采集 /// - /// 1分钟采集电表数据下行消息消费订阅 + /// 一分钟定时抄读任务消息消费订阅 /// + /// /// - Task AmmeterScheduledMeterOneMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo issuedEventMessage); + Task AmmeterScheduledMeterOneMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage); /// /// 5分钟采集电表数据下行消息消费订阅 /// + /// /// - Task AmmeterScheduledMeterFiveMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo issuedEventMessage); + Task AmmeterScheduledMeterFiveMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage); /// /// 15分钟采集电表数据下行消息消费订阅 /// + /// /// - Task AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo issuedEventMessage); + Task AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(List receivedMessage); /// /// 电表自动阀控下行消息消费订阅 /// + /// /// - Task AmmeterScheduledAutoValveControl(List issuedEventMessage); + Task AmmeterScheduledAutoValveControl(List receivedMessage); + + /// + /// 其他采集数据下行消息主题,日冻结,月冻结、集中器版本号、SIM卡号、定时校时等下行消息消费订阅 + /// + /// + /// + Task AmmeterScheduledOther(List receivedMessage); + + /// + /// 电表手动阀控下行消息消费订阅 + /// + /// + /// + Task AmmeterScheduledManualValveControl(MeterReadingTelemetryPacketInfo receivedMessage); + + /// + /// 电表手动抄读下行消息消费订阅 + /// + /// + /// + Task AmmeterScheduledManualValveReading(MeterReadingTelemetryPacketInfo receivedMessage); #endregion #region 水表消息采集 /// - /// 1分钟采集水表数据下行消息消费订阅 + /// 水表数据下行消息消费订阅 /// + /// /// - Task WatermeterSubscriberWorkerAutoReadingIssuedEvent(MeterReadingTelemetryPacketInfo issuedEventMessage); - + Task WatermeterScheduledAutoReading(MeterReadingTelemetryPacketInfo receivedMessage); + + /// + /// 水表自动阀控下行消息消费订阅 + /// + /// + /// + Task WatermeterScheduleAutoValveControl(MeterReadingTelemetryPacketInfo receivedMessage); + + /// + /// 水表手动阀控下行消息消费订阅 + /// + /// + /// + Task WatermeterScheduleManualValveControl(MeterReadingTelemetryPacketInfo receivedMessage); + /// + /// 水表手动抄读下行消息消费订阅 + /// + /// + /// + Task WatermeterScheduleManualValveReading(MeterReadingTelemetryPacketInfo receivedMessage); + #endregion } } diff --git a/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs b/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs index d73a174..58b5718 100644 --- a/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs +++ b/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs @@ -35,26 +35,22 @@ namespace JiShe.CollectBus.DataChannels private readonly IIoTDbProvider _dbProvider; private readonly IProducerService _producerService; private readonly KafkaOptionConfig _kafkaOptions; - private readonly ServerApplicationOptions _applicationOptions; - private readonly IoTDBRuntimeContext _runtimeContext; + private readonly ServerApplicationOptions _applicationOptions; private readonly ILogRecordRepository _logRecordRepository; public DataChannelManageService( ILogger logger, - IIoTDbProvider dbProvider, - IoTDBRuntimeContext runtimeContext, + IIoTDbProvider dbProvider, IProducerService producerService, IOptions kafkaOptions, IOptions applicationOptions, ILogRecordRepository logRecordRepository) { _logger = logger; - _dbProvider = dbProvider; - _runtimeContext = runtimeContext; + _dbProvider = dbProvider; _producerService = producerService; _kafkaOptions = kafkaOptions.Value; - _applicationOptions = applicationOptions.Value; - _runtimeContext.UseTableSessionPool = true; + _applicationOptions = applicationOptions.Value; _logRecordRepository= logRecordRepository; } @@ -74,10 +70,11 @@ namespace JiShe.CollectBus.DataChannels { const int BatchSize = 50000; const int EmptyWaitMilliseconds = 50; - var timeout = TimeSpan.FromSeconds(5); + var timeout = TimeSpan.FromMilliseconds(50); var timer = Stopwatch.StartNew(); long timeoutMilliseconds = 0; var metadata = await _dbProvider.GetMetadata(); + var timeoutStopwatch = Stopwatch.StartNew(); try { @@ -98,12 +95,12 @@ namespace JiShe.CollectBus.DataChannels } timer.Restart(); - var startTime = DateTime.Now; + timeoutStopwatch.Restart(); try { // 异步批量读取数据 - while (batch != null && batch.Count < BatchSize && (DateTime.Now - startTime) < timeout) + while (batch != null && batch.Count < BatchSize && timeoutStopwatch.Elapsed <= timeout) { try { @@ -122,6 +119,7 @@ namespace JiShe.CollectBus.DataChannels { throw; } + if (batch.Count == 0) { @@ -147,7 +145,7 @@ namespace JiShe.CollectBus.DataChannels try { // 批量写入数据库 - await _dbProvider.BatchInsertAsync(metadata, records); + await _dbProvider.GetSessionPool(true).BatchInsertAsync(metadata, records); // 限流推送Kafka await DeviceGroupBalanceControl.ProcessWithThrottleAsync( @@ -166,9 +164,8 @@ namespace JiShe.CollectBus.DataChannels batch.Clear(); timer.Stop(); + timeoutStopwatch.Stop(); timeoutMilliseconds = timeoutMilliseconds + timer.ElapsedMilliseconds; - - startTime = DateTime.Now; } } catch (Exception ex) diff --git a/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs b/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs index 049db1f..0e92ff6 100644 --- a/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs +++ b/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs @@ -16,7 +16,7 @@ using Volo.Abp.Domain.Repositories; namespace JiShe.CollectBus.Plugins { - public partial class TcpMonitor : PluginBase, ITransientDependency, ITcpReceivedPlugin, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosedPlugin + public partial class TcpMonitor : PluginBase, ITransientDependency, ITcpReceivedPlugin, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosedPlugin, ITcpClosingPlugin { private readonly IProducerService _producerService; private readonly ILogger _logger; @@ -115,5 +115,11 @@ namespace JiShe.CollectBus.Plugins await e.InvokeNext(); } + public Task OnTcpClosing(ITcpSession client, ClosingEventArgs e) + { + var tcpSessionClient = (ITcpSessionClient)client; + _logger.LogWarning($"[TCP] ID:{tcpSessionClient.Id} IP:{client.GetIPPort()}终端主动关闭"); + return Task.CompletedTask; + } } } diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index 8d9ac21..40c2db2 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -1,4 +1,6 @@ -using FreeSql.Internal.CommonProvider; +using Confluent.Kafka; +using DeviceDetectorNET.Parser.Device; +using FreeSql.Internal.CommonProvider; using JiShe.CollectBus.Ammeters; using JiShe.CollectBus.Application.Contracts; using JiShe.CollectBus.Common.Consts; @@ -53,8 +55,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS _dbContext = dbContext; _logger = logger; _redisDataCacheService = redisDataCacheService; - _producerService =producerService; - _tcpService=tcpService; + _producerService = producerService; + _tcpService = tcpService; } /// @@ -89,7 +91,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS //TableModelSingleMeasuringEntityExtension //TableModelSingleMeasuringEntityAccessor.GetSystemName(meter); //ElectricityMeterAccessor - await _iotDBProvider.InsertAsync(meter); + await _iotDBProvider.InsertAsync(meter); } /// @@ -99,7 +101,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS [HttpGet] public async Task UseTableSessionPool(DateTime time) { - var testTime = time; + var testTime = time; ElectricityMeterTreeModel meter2 = new ElectricityMeterTreeModel() { SystemName = "energy", @@ -112,9 +114,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS Timestamps = DateTimeOffset.Now.ToUnixTimeNanoseconds(), }; - await _iotDBProvider.InsertAsync(meter2); - - _dbContext.UseTableSessionPool = true; + await _iotDBProvider.GetSessionPool(false).InsertAsync(meter2); ElectricityMeter meter = new ElectricityMeter() { @@ -128,7 +128,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS CurrentdDateTime = DateTime.Now, Timestamps = DateTimeOffset.Now.ToUnixTimeNanoseconds(), }; - await _iotDBProvider.InsertAsync(meter); + await _iotDBProvider.GetSessionPool(true).InsertAsync(meter); QueryCondition conditions = new QueryCondition() { @@ -146,7 +146,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS Conditions = new List() { conditions }, }; - var pageResult = await _iotDBProvider.QueryAsync(query); + var pageResult = await _iotDBProvider.GetSessionPool(true).QueryAsync(query); } @@ -173,9 +173,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS }; await _iotDBProvider.InsertAsync(meter2); - - _dbContext.UseTableSessionPool = true; - + ElectricityMeter meter3 = new ElectricityMeter() { @@ -209,14 +207,15 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS time = DateTime.Now; //System.Reflection.PropertyInfo; //System.Reflection.FieldInfo - var meter = new TreeModelSingleMeasuringEntity() + //TreeModelSingleMeasuringEntityAccessor + var meter = new TreeModelSingleMeasuringEntity() { SystemName = "energy", DeviceId = "402440506", DeviceType = "1", ProjectId = "10059", Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(), - SingleMeasuring = (measuring, time) + SingleMeasuring = (measuring, 34.534m) }; await _iotDBProvider.InsertAsync(meter); } @@ -263,9 +262,6 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS SingleMeasuring = ("measuring", true) }; - - - QueryCondition conditions = new QueryCondition() { Field = "DeviceId", @@ -274,13 +270,13 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS }; - var query = new IoTDBQueryOptions() + var query = new IoTDBQueryOptions() { TableNameOrTreePath = meter.DevicePath, PageIndex = 1, PageSize = 1, - Conditions = new List() { conditions }, - }; + Conditions = new List() { conditions }, + }; var pageResult = await _iotDBProvider.QueryAsync(query); @@ -331,6 +327,35 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS }; _dbContext.UseTableSessionPool = true; await _iotDBProvider.InsertAsync(meter); + + var meter3 = new TableModelSingleMeasuringEntity() + { + SystemName = "energy", + DeviceId = "402440506", + DeviceType = "Ammeter", + ProjectId = "10059", + Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(), + SingleColumn = ("DeviceResult", true) + }; + _dbContext.UseTableSessionPool = true; + + QueryCondition conditions = new QueryCondition() + { + Field = "DeviceId", + Operator = "=", + Value = meter.DeviceId + }; + + + var query = new IoTDBQueryOptions() + { + TableNameOrTreePath = meter.DevicePath, + PageIndex = 1, + PageSize = 1, + Conditions = new List() { conditions }, + }; + + var pageResult = await _iotDBProvider.QueryAsync(query); } /// @@ -363,7 +388,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS //} //DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista); - + //// 打印分布统计 //DeviceGroupBalanceControl.PrintDistributionStats(); @@ -377,13 +402,13 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS /// [HttpGet] public async Task TestGetDeviceGroupBalanceControl(string deviceAddress) - { + { var groupId = DeviceGroupBalanceControl.GetDeviceGroupId(deviceAddress); Console.WriteLine(groupId); await Task.CompletedTask; } - + /// /// 测试Redis批量读取10万条数据性能 @@ -446,7 +471,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS { DateTime nextTaskTime = Convert.ToDateTime(time); - return await Task.FromResult(nextTaskTime.CalculateNextCollectionTime(timeDensity)); + return await Task.FromResult(nextTaskTime.CalculateNextCollectionTime(timeDensity)); } @@ -482,7 +507,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS [AllowAnonymous] public bool GetTestProtocol() { - var aa = LazyServiceProvider.GetKeyedService("TestProtocolPlugin"); + var aa = LazyServiceProvider.GetKeyedService("TestProtocolPlugin"); return aa == null; } @@ -491,7 +516,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS public async Task KafkaSubscribeAsync(object obj) { _logger.LogWarning($"收到订阅消息: {obj}"); - return SubscribeAck.Success(); + return SubscribeAck.Success(); } /// @@ -502,7 +527,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS [AllowAnonymous] public async Task KafkaSendAsync(KafkaSendDto input) { - ArgumentException.ThrowIfNullOrWhiteSpace(input.Address); + ArgumentException.ThrowIfNullOrWhiteSpace(input.Address); ArgumentException.ThrowIfNullOrWhiteSpace(input.Frame); input.Frame = input.Frame.Replace(" ", ""); await _producerService.ProduceAsync(ProtocolConst.TESTSENDTOPIC, input); @@ -515,7 +540,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS /// /// /// - [KafkaSubscribe(ProtocolConst.TESTSENDTOPIC)] + [KafkaSubscribe(ProtocolConst.TESTSENDTOPIC), ApiExplorerSettings(IgnoreApi = true)] public async Task KafkaSubscribeTestSendAsync(KafkaSendDto dto) { @@ -529,7 +554,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS { _logger.LogWarning($"{dto.Address}集中器未上线: {dto.Serialize()}"); } - // 测试不管是否上线都ACK + // 测试不管是否上线都ACK return SubscribeAck.Success(); } diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs index 2991fe8..a1424f9 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs @@ -8,7 +8,6 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Models; using JiShe.CollectBus.DataChannels; -using JiShe.CollectBus.DataMigration.Options; using JiShe.CollectBus.GatherItem; using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IoTDB.Model; @@ -28,6 +27,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using Volo.Abp.Guids; namespace JiShe.CollectBus.ScheduledMeterReading { @@ -41,9 +41,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading private readonly IDataChannelManageService _dataChannelManage; private readonly IRedisDataCacheService _redisDataCacheService; private readonly IProtocolService _protocolService; - private readonly DataMigrationOptions _dataMigrationOptions; private readonly KafkaOptionConfig _kafkaOptions; private readonly ServerApplicationOptions _applicationOptions; + private readonly IGuidGenerator _guidGenerator; int pageSize = 10000; @@ -53,7 +53,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading IRedisDataCacheService redisDataCacheService, IIoTDbProvider dbProvider, IProtocolService protocolService, - IOptions dataMigrationOptions, + IGuidGenerator guidGenerator, IOptions kafkaOptions, IOptions applicationOptions) { @@ -63,10 +63,11 @@ namespace JiShe.CollectBus.ScheduledMeterReading _redisDataCacheService = redisDataCacheService; _protocolService = protocolService; - _dataMigrationOptions = dataMigrationOptions.Value; _kafkaOptions = kafkaOptions.Value; _applicationOptions = applicationOptions.Value; + _guidGenerator = guidGenerator; + } /// @@ -136,99 +137,178 @@ namespace JiShe.CollectBus.ScheduledMeterReading //电表定时广播校时,一天一次。 string currentTimeStr = $"{currentTime:HH:mm:00}"; - if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时 - { - //_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间"); - //return; + //if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时 + //{ + // //_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间"); + // //return; - _ = CreateMeterPublishTask( - timeDensity: timeDensity, - nextTaskTime: currentTime, - meterType: MeterTypeEnum.Ammeter, - taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => - { - var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps); + // _ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps); - if (tempTask == null || tempTask.Count <= 0) - { - _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); - }); - } - else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取 - { - _ = CreateMeterPublishTask( - timeDensity: timeDensity, - nextTaskTime: currentTime, - meterType: MeterTypeEnum.Ammeter, - taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => - { - var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps); - if (tempTask == null || tempTask.Count <= 0) - { - _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); - }); - } - else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取 - { - _ = CreateMeterPublishTask( - timeDensity: timeDensity, - nextTaskTime: currentTime, - meterType: MeterTypeEnum.Ammeter, - taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => - { - var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps); - if (tempTask == null || tempTask.Count <= 0) - { - _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); - }); - } - else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//月冻结 - { - _ = CreateMeterPublishTask( - timeDensity: timeDensity, - nextTaskTime: currentTime, - meterType: MeterTypeEnum.Ammeter, - taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => - { - var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps); - if (tempTask == null || tempTask.Count <= 0) - { - _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); - }); - } - else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结 - { - _ = CreateMeterPublishTask( - timeDensity: timeDensity, - nextTaskTime: currentTime, - meterType: MeterTypeEnum.Ammeter, - taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => - { - var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps); - if (tempTask == null || tempTask.Count <= 0) - { - _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); - }); - } - else - { - _logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他"); - } + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + //} + //else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取 + //{ + // _ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + //} + //else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取 + //{ + // _ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + //} + //else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//月冻结 + //{ + // _ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + //} + //else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结 + //{ + // _ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + //} + //else + //{ + // _logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他"); + //} + + + //_ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps); + + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + + _ = CreateMeterPublishTask( + timeDensity: timeDensity, + nextTaskTime: currentTime, + meterType: MeterTypeEnum.Ammeter, + taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + { + var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps); + if (tempTask == null || tempTask.Count <= 0) + { + _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); + return; + } + _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + }); + + //_ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + + //_ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); + + + + //_ = CreateMeterPublishTask( + // timeDensity: timeDensity, + // nextTaskTime: currentTime, + // meterType: MeterTypeEnum.Ammeter, + // taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + // { + // var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps); + // if (tempTask == null || tempTask.Count <= 0) + // { + // _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); + // return; + // } + // _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask)); + // }); //检查任务时间节点,由于定时任务10秒钟运行一次,需要判定当前时间是否在任务时间节点内,不在则跳过 var currentTaskTime = tasksToBeIssueModel.LastTaskTime.CalculateNextCollectionTime(timeDensity);//程序启动缓存电表的时候,NextTaskTime需要格式化到下一个采集点时间。 @@ -293,15 +373,15 @@ namespace JiShe.CollectBus.ScheduledMeterReading await FreeRedisProvider.Instance.SetAsync(item, tasksToBeIssueModel); } - //电表定时阀控任务处理。 - var autoValveControlTask = await AmmeterScheduledAutoValveControl(); + ////电表定时阀控任务处理。 + //var autoValveControlTask = await AmmeterScheduledAutoValveControl(); - if (autoValveControlTask == null || autoValveControlTask.Count <= 0) - { - _logger.LogWarning($"{nameof(AmmeterScheduledAutoValveControl)}电表定时阀控没有可操作的任务"); - return; - } - _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, autoValveControlTask)); + //if (autoValveControlTask == null || autoValveControlTask.Count <= 0) + //{ + // _logger.LogWarning($"{nameof(AmmeterScheduledAutoValveControl)}电表定时阀控没有可操作的任务"); + // return; + //} + //_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, autoValveControlTask)); } #region 电表采集处理 @@ -332,34 +412,35 @@ namespace JiShe.CollectBus.ScheduledMeterReading _ = _dataChannelManage.ScheduledMeterTaskReadingAsync(DataChannelManage.TaskDataChannel.Reader); - //此处代码不要删除 -#if DEBUG - var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus2:DeviceInfo"; + // //此处代码不要删除 + //#if DEBUG + // var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus2:DeviceInfo"; - var timer1 = Stopwatch.StartNew(); - Dictionary> keyValuePairsTemps = FreeRedisProvider.Instance.HGetAll>(redisCacheDeviceInfoHashKeyTemp); - List meterInfos = new List(); - List focusAddressDataLista = new List(); - foreach (var item in keyValuePairsTemps) - { - foreach (var subItem in item.Value) - { - if (subItem.MeterType == MeterTypeEnum.Ammeter && subItem.TimeDensity == 15) - { - meterInfos.Add(subItem); - focusAddressDataLista.Add(subItem.MeterId.ToString()); - } - } - } + // var timer1 = Stopwatch.StartNew(); + // Dictionary> keyValuePairsTemps = FreeRedisProvider.Instance.HGetAll>(redisCacheDeviceInfoHashKeyTemp); + // List meterInfos = new List(); + // List focusAddressDataLista = new List(); + // foreach (var item in keyValuePairsTemps) + // { + // foreach (var subItem in item.Value) + // { + // if (subItem.MeterType == MeterTypeEnum.Ammeter && subItem.TimeDensity == 15) + // { + // meterInfos.Add(subItem); + // focusAddressDataLista.Add(subItem.MeterId.ToString()); + // } + // } + // } - timer1.Stop(); - _logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒"); - DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions); - return; -#else - var meterInfos = await GetAmmeterInfoList(gatherCode); -#endif + // timer1.Stop(); + // _logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒"); + // DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions); + // return; + //#else + // var meterInfos = await GetAmmeterInfoList(gatherCode); + //#endif + var meterInfos = await GetAmmeterInfoList(gatherCode); if (meterInfos == null || meterInfos.Count <= 0) { _logger.LogError($"{nameof(InitAmmeterCacheData)} 初始化电表缓存数据时,电表数据为空"); @@ -457,6 +538,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading } } + ammeter.ItemCodes = "10_97"; + if (!keyValuePairs.ContainsKey(ammeter.FocusAddress)) { keyValuePairs[ammeter.FocusAddress] = new List() { ammeter.Adapt() }; @@ -722,17 +805,27 @@ namespace JiShe.CollectBus.ScheduledMeterReading //var aFN = (AFN)aFNStr.HexToDec(); //var fn = int.Parse(itemCodeArr[1]); + var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(tempItem); + //TODO:特殊表 ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() { FocusAddress = ammeterInfo.FocusAddress, Pn = ammeterInfo.MeteringCode, - ItemCode = tempItem, + ItemCode = itemCodeInfo.Item1, DataTimeMark = new Protocol.DataTimeMark() { Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值 Point = 1, DataTime = timestamps, + }, + SubProtocolRequest = new SubProtocolBuildRequest() + { + MeterAddress = ammeterInfo.MeterAddress, + Password = ammeterInfo.Password, + MeteringPort = ammeterInfo.MeteringPort, + Baudrate = ammeterInfo.Baudrate, + ItemCode = itemCodeInfo.Item2, //10_97 => 11_02_80_00_02 } }); if (builderResponse == null || builderResponse.Data.Length <= 0) @@ -749,7 +842,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: null, pendingCopyReadTime: timestamps, creationTime: currentTime, - packetType: (TelemetryPacketTypeEnum)timeDensity); + packetType: (TelemetryPacketTypeEnum)timeDensity, + _guidGenerator); taskList.Add(meterReadingRecords); } @@ -809,7 +903,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105"); return null; } - + ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() { FocusAddress = ammeterInfo.FocusAddress, @@ -831,7 +925,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: subItemCode, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.AmmeterAutomaticVerificationTime); + packetType: TelemetryPacketTypeEnum.AmmeterAutomaticVerificationTime, + _guidGenerator); taskList.Add(meterReadingRecords); if (taskList == null || taskList.Count <= 0) @@ -900,7 +995,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: null, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.AmmeterDayFreeze); + packetType: TelemetryPacketTypeEnum.AmmeterDayFreeze, + _guidGenerator); taskList.Add(meterReadingRecords); } @@ -970,7 +1066,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: null, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.AmmeterMonthFreeze); + packetType: TelemetryPacketTypeEnum.AmmeterMonthFreeze, + _guidGenerator); taskList.Add(meterReadingRecords); } @@ -1096,7 +1193,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading List deviceIds = new List();//用于处理Kafka主题分区数据的分发和处理。 //根据采集频率分组,获得采集频率分组 - var meterInfoGroupByTimeDensity = meterInfos.Select(d=>d.TimeDensity).GroupBy(d => d); + var meterInfoGroupByTimeDensity = meterInfos.Select(d => d.TimeDensity).GroupBy(d => d); var currentTime = DateTime.Now; if (_applicationOptions.FirstCollectionTime.HasValue == false) { @@ -1143,7 +1240,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading - await _redisDataCacheService.BatchInsertDataAsync( + await _redisDataCacheService.BatchInsertDataAsync( redisCacheDeviceGroupSetIndexKey, redisCacheDeviceInfoHashKey, keyValuePairs); @@ -1328,12 +1425,15 @@ namespace JiShe.CollectBus.ScheduledMeterReading try { +#if DEBUG +#else //判断是否是自动获取版本号时间 if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase)) { _logger.LogInformation($"{nameof(ConcentratorScheduledAutomaticGetTerminalVersion)} 集中器自动获取版本号,非自动处理时间"); return null; } +#endif List taskList = new List(); @@ -1369,7 +1469,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: null, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.TerminalVersion); + packetType: TelemetryPacketTypeEnum.TerminalVersion, + _guidGenerator); taskList.Add(meterReadingRecords); @@ -1437,7 +1538,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: null, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.TelematicsModule); + packetType: TelemetryPacketTypeEnum.TelematicsModule, + _guidGenerator); taskList.Add(meterReadingRecords); @@ -1455,7 +1557,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading throw; } } - #endregion +#endregion #region 公共处理方法 @@ -1534,7 +1636,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading //} Dictionary> keyValuePairs = FreeRedisProvider.Instance.HGetAll>(redisCacheDeviceInfoHashKey); - + timer.Stop(); _logger.LogError($"{nameof(CreateMeterPublishTask)} 构建采集待下发任务,缓存获取信息共花费{timer.ElapsedMilliseconds}毫秒"); @@ -1545,7 +1647,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading { foreach (var subItem in item.Value) { - if (subItem.MeterType == meterType && subItem.TimeDensity == timeDensity) + if (subItem.MeterType == meterType && subItem.TimeDensity == timeDensity) { meterInfos.Add(subItem); } @@ -1641,8 +1743,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading /// 待采集时间,定时采集频率才是特殊情况,其他默认当前时间戳 /// 数据创建时间戳 /// 数据包类型 + /// Guid生成器 /// - protected MeterReadingTelemetryPacketInfo CreateAmmeterPacketInfo(DeviceInfo ammeterInfo, long timestamps, ProtocolBuildResponse builderResponse, string itemCode, string subItemCode, DateTime pendingCopyReadTime, DateTime creationTime, TelemetryPacketTypeEnum packetType) + protected MeterReadingTelemetryPacketInfo CreateAmmeterPacketInfo(DeviceInfo ammeterInfo, long timestamps, ProtocolBuildResponse builderResponse, string itemCode, string subItemCode, DateTime pendingCopyReadTime, DateTime creationTime, TelemetryPacketTypeEnum packetType, IGuidGenerator guidGenerator) { try { @@ -1671,17 +1774,17 @@ namespace JiShe.CollectBus.ScheduledMeterReading IsSend = false, ManualOrNot = false, Pn = ammeterInfo.MeteringCode, - IssuedMessageId = Guid.NewGuid().ToString(), + IssuedMessageId = guidGenerator.Create().ToString(), IssuedMessageHexString = Convert.ToHexString(builderResponse.Data), IsReceived = false, ScoreValue = $"{ammeterInfo.FocusAddress}.{taskMark}".Md5Fun(), }; } catch (Exception ex) - { + { throw ex; } - } + } #endregion } diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs index 57eb3ec..c1fd4e4 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs @@ -1,22 +1,17 @@ using JiShe.CollectBus.Application.Contracts; using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.DeviceBalanceControl; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.DataChannels; -using JiShe.CollectBus.DataMigration.Options; using JiShe.CollectBus.FreeSql; using JiShe.CollectBus.GatherItem; -using JiShe.CollectBus.IoTDB.Context; using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.IotSystems.Devices; using JiShe.CollectBus.IotSystems.MeterReadingRecords; -using JiShe.CollectBus.IotSystems.Watermeter; using JiShe.CollectBus.Kafka.Internal; -using JiShe.CollectBus.Kafka.Producer; using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.Models; using Microsoft.AspNetCore.Authorization; @@ -26,6 +21,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Volo.Abp.Guids; namespace JiShe.CollectBus.ScheduledMeterReading @@ -41,6 +37,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading string serverTagName = string.Empty; private readonly ILogger _logger; private readonly IProtocolService _protocolService; + private readonly IGuidGenerator _guidGenerator; public EnergySystemScheduledMeterReadingService( ILogger logger, @@ -48,7 +45,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading IRedisDataCacheService redisDataCacheService, IIoTDbProvider dbProvider, IProtocolService protocolService, - IOptions dataMigrationOptions, + IGuidGenerator guidGenerator, IOptions kafkaOptions, IOptions applicationOptions) : base(logger, @@ -56,7 +53,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading redisDataCacheService, dbProvider, protocolService, - dataMigrationOptions, + guidGenerator, kafkaOptions, applicationOptions) { @@ -64,6 +61,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading systemType = applicationOptions.Value.SystemType; _logger = logger; _protocolService = protocolService; + _guidGenerator = guidGenerator; } public sealed override string SystemType => systemType; @@ -98,79 +96,170 @@ namespace JiShe.CollectBus.ScheduledMeterReading //[Route($"ammeter/list")] public override async Task> GetAmmeterInfoList(string gatherCode = "V4-Gather-8890") { + //#if DEBUG + // var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus109:DeviceInfo"; - //List ammeterInfos = new List(); - //ammeterInfos.Add(new DeviceInfo() - //{ - // Baudrate = 2400, - // FocusAddress = "402440506", - // Name = "张家祠工务(三相电表)", - // FocusId = 95780, - // DatabaseBusiID = 1, - // MeteringCode = 1, - // MeterAddress = "402410040506", - // MeterId = 127035, - // TypeName = 3, - // DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679", - // TimeDensity = 15, - // BrandType = "DDS1980", - //}); + // List ammeterInfos = FreeRedisProvider.Instance.Get>(redisCacheDeviceInfoHashKeyTemp);//542400504 - //ammeterInfos.Add(new DeviceInfo() - //{ - // Baudrate = 2400, - // FocusAddress = "542400504", - // Name = "五号配(长芦二所四排)(单相电表)", - // FocusId = 69280, - // DatabaseBusiID = 1, - // MeteringCode = 2, - // MeterAddress = "542410000504", - // MeterId = 95594, - // TypeName = 1, - // DataTypes = "581,589,592,597,601", - // TimeDensity = 15, - // BrandType = "DDS1980", - //}); + // if (ammeterInfos == null || ammeterInfos.Count <= 0) + // { + // ammeterInfos = new List(); + // //ammeterInfos.Add(new DeviceInfo() + // //{ + // // Baudrate = 2400, + // // FocusAddress = "442400040", + // // Name = "保利单箱电表1", + // // FocusId = 95780, + // // DatabaseBusiID = 1, + // // MeteringCode = 0, + // // MeterAddress = "442405000040", + // // MeterId = 127035, + // // TypeName = 1, + // // DataTypes = "581,589,592,597,601", + // // TimeDensity = 15, + // // BrandType = "DTS1980", + // // MeterType = MeterTypeEnum.Ammeter, + // // ProjectID = 1, + // // MeteringPort = MeteringPortConst.MeteringPortTwo, + // // Password = "000000", + // //}); + + // //ammeterInfos.Add(new DeviceInfo() + // //{ + // // Baudrate = 2400, + // // FocusAddress = "442400039", + // // Name = "保利单箱电表2", + // // FocusId = 69280, + // // DatabaseBusiID = 1, + // // MeteringCode = 0, + // // MeterAddress = "442405000039", + // // MeterId = 95594, + // // TypeName = 1, + // // DataTypes = "581,589,592,597,601", + // // TimeDensity = 15, + // // BrandType = "DTS1980", + // // MeterType = MeterTypeEnum.Ammeter, + // // ProjectID = 1, + // // MeteringPort = MeteringPortConst.MeteringPortTwo, + // // Password = "000000", + // //}); + + // //ammeterInfos.Add(new DeviceInfo() + // //{ + // // Baudrate = 2400, + // // FocusAddress = "402440506", + // // Name = "中环半导体9#冷却泵-220KW(三相电表)", + // // FocusId = 106857, + // // DatabaseBusiID = 1, + // // MeteringCode = 0, + // // MeterAddress = "402410040506", + // // MeterId = 139059, + // // TypeName = 3, + // // DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679", + // // TimeDensity = 15, + // // BrandType = "DTS1980", + // // Password = "000000", + // // ProjectID = 1, + // // MeterType = MeterTypeEnum.Ammeter, + // // MeteringPort = MeteringPortConst.MeteringPortTwo, + // //}); + + + // ammeterInfos.Add(new DeviceInfo() + // { + // Baudrate = 2400, + // FocusAddress = "942411321", + // Name = "DDS1980-T4(5-60) ML307A 长稳 942408011321", + // FocusId = 57682, + // DatabaseBusiID = 1, + // MeteringCode = 0, + // MeterAddress = "942408011321", + // MeterId = 78970, + // TypeName = 3, + // DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679", + // TimeDensity = 15, + // BrandType = "DTS1980", + // Password = "000000", + // ProjectID = 1, + // MeterType = MeterTypeEnum.Ammeter, + // MeteringPort = MeteringPortConst.MeteringPortTwo, + // }); + + + // ammeterInfos.Add(new DeviceInfo() + // { + // Baudrate = 2400, + // FocusAddress = "942411319", + // Name = "DDS1980-T4(5-60) ML307A 长稳 942408011319", + // FocusId = 57685, + // DatabaseBusiID = 1, + // MeteringCode = 0, + // MeterAddress = "942408011319", + // MeterId = 78973, + // TypeName = 3, + // DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679", + // TimeDensity = 15, + // BrandType = "DTS1980", + // Password = "000000", + // ProjectID = 1, + // MeterType = MeterTypeEnum.Ammeter, + // MeteringPort = MeteringPortConst.MeteringPortTwo, + // }); + + + // FreeRedisProvider.Instance.Set(redisCacheDeviceInfoHashKeyTemp, ammeterInfos); + // } + + // return ammeterInfos; + //#else + + + //#endif - //return ammeterInfos; try { string sql = $@"SELECT - C.ID as MeterId, - C.Name, - C.FocusID as FocusId, - C.SingleRate, - C.MeteringCode, - C.Code AS BrandType, - C.Baudrate, - C.Password, - C.MeteringPort, - C.[Address] AS MeterAddress, - C.TypeName, - C.Protocol, - C.TripState, - C.[State], - B.[Address], - B.AreaCode, - B.AutomaticReport, - D.DataTypes, - B.TimeDensity, - A.GatherCode, - C.Special, - C.[ProjectID], - B.AbnormalState, - B.LastTime, - 1 as MeterType, - CONCAT(B.AreaCode, B.[Address]) AS FocusAddress, - (select top 1 DatabaseBusiID from TB_Project where ID = B.ProjectID) AS DatabaseBusiID - FROM TB_GatherInfo(NOLOCK) AS A - INNER JOIN TB_FocusInfo(NOLOCK) AS B ON A.ID = B.GatherInfoID AND B.RemoveState >= 0 AND B.State>=0 - INNER JOIN TB_AmmeterInfo(NOLOCK) AS C ON B.ID = C.FocusID AND C.State>= 0 AND C.State<100 - INNER JOIN TB_AmmeterGatherItem(NOLOCK) AS D ON C.ID = D.AmmeterID AND D.State>=0 - WHERE 1=1 and C.Special = 0 "; + C.ID as MeterId, + C.Name, + C.FocusID as FocusId, + C.SingleRate, + C.MeteringCode, + C.Code AS BrandType, + C.Baudrate, + C.Password, + C.MeteringPort, + C.[Address] AS MeterAddress, + C.TypeName, + C.Protocol, + C.TripState, + C.[State], + B.[Address], + B.AreaCode, + B.AutomaticReport, + D.DataTypes, + B.TimeDensity, + A.GatherCode, + C.Special, + C.[ProjectID], + B.AbnormalState, + B.LastTime, + 1 as MeterType, + CONCAT(B.AreaCode, B.[Address]) AS FocusAddress, + (select top 1 DatabaseBusiID from TB_Project where ID = B.ProjectID) AS DatabaseBusiID + FROM TB_GatherInfo(NOLOCK) AS A + INNER JOIN TB_FocusInfo(NOLOCK) AS B ON A.ID = B.GatherInfoID AND B.RemoveState >= 0 AND B.State>=0 + INNER JOIN TB_AmmeterInfo(NOLOCK) AS C ON B.ID = C.FocusID AND C.State>= 0 AND C.State<100 + INNER JOIN TB_AmmeterGatherItem(NOLOCK) AS D ON C.ID = D.AmmeterID AND D.State>=0 + WHERE 1=1 and C.Special = 0 "; //TODO 记得移除特殊表过滤 + + #if DEBUG + //// sql = $@"{sql} and c.Address in('542410000504','442405000040','442405000039','402410040506')"; + sql = $@"{sql} and c.Address in('402410040506')"; +#endif + if (!string.IsNullOrWhiteSpace(gatherCode)) { sql = $@"{sql} AND A.GatherCode = '{gatherCode}'"; @@ -180,9 +269,10 @@ namespace JiShe.CollectBus.ScheduledMeterReading .QueryAsync(sql); } catch (Exception ex) - { + { throw ex; } + } @@ -231,17 +321,122 @@ namespace JiShe.CollectBus.ScheduledMeterReading try { +#if DEBUG + //电表自动阀控缓存 + string redisCacheDeviceSettingInfoHashKey = $"redisCacheDeviceSettingInfoHashKey_{SystemType}_{ServerTagName}"; + + var settingInfos = FreeRedisProvider.Instance.Get>(redisCacheDeviceSettingInfoHashKey); + if (settingInfos == null || settingInfos.Count <= 0) + { + settingInfos = new List(); + //settingInfos.Add(new AmmeterAutoValveControlSetting() + //{ + // MeterType = MeterTypeEnum.Ammeter, + // AmmerterAddress = "442405000040", + // FocusAddress = "442400040", + // FocusId = 57683, + // ProjectID = 1, + // TripType = "on", + // TripTime = $"{DateTime.Now:HH:mm}", + // MeterId = 78971, + // LoopType = "EachDay", + // EachDayWithout = "周六,周日", + // TimeDensity = 15, + //}); + //settingInfos.Add(new AmmeterAutoValveControlSetting() + //{ + // MeterType = MeterTypeEnum.Ammeter, + // AmmerterAddress = "442405000039", + // FocusAddress = "442400039", + // FocusId = 57684, + // ProjectID = 1, + // TripType = "on", + // TripTime = $"{DateTime.Now:HH:mm}", + // MeterId = 78972, + // LoopType = "EachDay", + // EachDayWithout = "周六,周日", + // TimeDensity = 15, + //}); + + //settingInfos.Add(new AmmeterAutoValveControlSetting() + //{ + // MeterType = MeterTypeEnum.Ammeter, + // AmmerterAddress = "542410000504", + // FocusAddress = "542400504", + // FocusId = 57686, + // ProjectID = 1, + // TripType = "on", + // TripTime = $"{DateTime.Now:HH:mm}", + // MeterId = 78974, + // LoopType = "EachDay", + // EachDayWithout = "周六,周日", + // TimeDensity = 15, + //}); + + //settingInfos.Add(new AmmeterAutoValveControlSetting() + //{ + // MeterType = MeterTypeEnum.Ammeter, + // AmmerterAddress = "402410040506", + // FocusAddress = "402440506", + // FocusId = 57685, + // ProjectID = 1, + // TripType = "on", + // TripTime = $"{DateTime.Now:HH:mm}", + // MeterId = 78973, + // LoopType = "EachDay", + // EachDayWithout = "周六,周日", + // TimeDensity = 15, + //}); + + settingInfos.Add(new AmmeterAutoValveControlSetting() + { + MeterType = MeterTypeEnum.Ammeter, + AmmerterAddress = "402410040506", + FocusAddress = "402440506", + FocusId = 57685, + ProjectID = 1, + TripType = "on", + TripTime = $"{DateTime.Now:HH:mm}", + MeterId = 78973, + LoopType = "EachDay", + EachDayWithout = "周六", + TimeDensity = 15, + }); + + FreeRedisProvider.Instance.Set(redisCacheDeviceSettingInfoHashKey, settingInfos); + } + + List meterInfos = await GetAmmeterInfoList(); +#else //获取电表阀控配置 var settingInfos = await GetAmmeterAutoValveControlSetting(currentTimeStr); - if (settingInfos == null || settingInfos.Count <= 0) { _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 电表自动阀控时,阀控数据为空, -101"); return null; } - //批量获取对应的缓存电表信息 - var ammeterInfos = new List(); + //设备hash缓存key + string redisCacheDeviceInfoHashKey = $"{string.Format(RedisConst.CacheDeviceInfoHashKey, SystemType, ServerTagName)}"; + + Dictionary> keyValuePairsTemps = FreeRedisProvider.Instance.HGetAll>(redisCacheDeviceInfoHashKey); + List meterInfos = new List(); + List focusAddressDataLista = new List(); + foreach (var item in keyValuePairsTemps) + { + foreach (var subItem in item.Value) + { + if (subItem.MeterType == MeterTypeEnum.Ammeter && subItem.TimeDensity == 15) + { + meterInfos.Add(subItem); + focusAddressDataLista.Add(subItem.MeterId.ToString()); + } + } + } +#endif + + + List taskList = new List(); foreach (var settingInfo in settingInfos) @@ -269,25 +464,31 @@ namespace JiShe.CollectBus.ScheduledMeterReading } //获取对应的缓存电表信息 - var ammeterInfo = ammeterInfos.First(); + var ammeterInfo = meterInfos.Where(d => d.MeterId == settingInfo.MeterId).FirstOrDefault(); + if (ammeterInfo == null) + { + _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 电表自动阀控时,未找到对应电表信息,电表Id={settingInfo.MeterId}, -102"); + continue; + } + bool tripStateResult = false; string itemCode = T37612012PacketItemCodeConst.AFN10HFN01H; string subItemCode = string.Empty; - if (settingInfo.TripType.Equals("on")) + if (settingInfo.TripType.Equals("on"))//当前电表断闸,需要合闸 { ammeterInfo.TripState = 0; tripStateResult = true; - subItemCode = T6452007PacketItemCodeConst.C1C01C; - if (ammeterInfo.TypeName != 1) + subItemCode = T6452007PacketItemCodeConst.C1C011C; + if (ammeterInfo.TypeName > 3) { - subItemCode = T6452007PacketItemCodeConst.C1C01B; + subItemCode = T6452007PacketItemCodeConst.C1C011B; } } - else if (settingInfo.TripType.Equals("off")) + else if (settingInfo.TripType.Equals("off"))//当前电表合闸,需要断闸 { ammeterInfo.TripState = 1; tripStateResult = false; - subItemCode = T6452007PacketItemCodeConst.C1C01A; + subItemCode = T6452007PacketItemCodeConst.C1C011A; } else { @@ -314,6 +515,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading MeterAddress = ammeterInfo.MeterAddress, Password = ammeterInfo.Password, ItemCode = subItemCode, + Baudrate = ammeterInfo.Baudrate, + MeteringPort = ammeterInfo.MeteringPort } }); @@ -326,7 +529,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading subItemCode: subItemCode, pendingCopyReadTime: currentTime, creationTime: currentTime, - packetType: TelemetryPacketTypeEnum.AmmeterAutoValveControl); + packetType: TelemetryPacketTypeEnum.AmmeterAutoValveControl, + _guidGenerator); taskList.Add(meterReadingRecords); } if (taskList == null || taskList.Count <= 0) diff --git a/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs index 9d22468..d17b921 100644 --- a/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs +++ b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs @@ -42,458 +42,458 @@ namespace JiShe.CollectBus.Subscribers _protocolService = protocolService; } - /// - /// 解析AFN00H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN00HReceivedEventNameTemp)] - public async Task ReceivedAFN00Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data==null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN00H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN00HReceivedEventNameTemp)] + //public async Task ReceivedAFN00Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data==null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN01H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN01HReceivedEventNameTemp)] - public async Task ReceivedAFN01Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN01H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN01HReceivedEventNameTemp)] + //public async Task ReceivedAFN01Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN02H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN02HReceivedEventNameTemp)] - public async Task ReceivedAFN02Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN02H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN02HReceivedEventNameTemp)] + //public async Task ReceivedAFN02Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data, (result) => - { - var ssss = (UnitDataAnalysis>)result; - _logger.LogInformation($"解析AFN02H数据:{ssss.Serialize()}"); - }); - return SubscribeAck.Success(); - } - return SubscribeAck.Fail(); + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data, (result) => + // { + // var ssss = (UnitDataAnalysis>)result; + // _logger.LogInformation($"解析AFN02H数据:{ssss.Serialize()}"); + // }); + // return SubscribeAck.Success(); + // } + // return SubscribeAck.Fail(); - } + //} - /// - /// 解析AFN03H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN03HReceivedEventNameTemp)] - public async Task ReceivedAFN03Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN03H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN03HReceivedEventNameTemp)] + //public async Task ReceivedAFN03Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN04H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN04HReceivedEventNameTemp)] - public async Task ReceivedAFN04Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN04H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN04HReceivedEventNameTemp)] + //public async Task ReceivedAFN04Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN05H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN05HReceivedEventNameTemp)] - public async Task ReceivedAFN05Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN05H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN05HReceivedEventNameTemp)] + //public async Task ReceivedAFN05Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN09H - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN09HReceivedEventNameTemp)] - public async Task ReceivedAFN09Event(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN09H + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN09HReceivedEventNameTemp)] + //public async Task ReceivedAFN09Event(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN0AH - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN0AHReceivedEventNameTemp)] - public async Task ReceivedAFN0AEvent(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN0AH + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN0AHReceivedEventNameTemp)] + //public async Task ReceivedAFN0AEvent(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN0BH - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN0BHReceivedEventNameTemp)] - public async Task ReceivedAFN0BEvent(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN0BH + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN0BHReceivedEventNameTemp)] + //public async Task ReceivedAFN0BEvent(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN0CH - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN0CHReceivedEventNameTemp)] - public async Task ReceivedAFN0CEvent(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN0CH + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN0CHReceivedEventNameTemp)] + //public async Task ReceivedAFN0CEvent(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN0DH - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN0DHReceivedEventNameTemp)] - public async Task ReceivedAFN0DEvent(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN0DH + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN0DHReceivedEventNameTemp)] + //public async Task ReceivedAFN0DEvent(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} - /// - /// 解析AFN0EH - /// - /// - /// - [KafkaSubscribe(ProtocolConst.SubscriberAFN0EHReceivedEventNameTemp)] - public async Task ReceivedAFN0EEvent(MessageProtocolAnalysis receivedMessage) - { - var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - if (receivedMessage.Data == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); + ///// + ///// 解析AFN0EH + ///// + ///// + ///// + //[KafkaSubscribe(ProtocolConst.SubscriberAFN0EHReceivedEventNameTemp)] + //public async Task ReceivedAFN0EEvent(MessageProtocolAnalysis receivedMessage) + //{ + // var protocolPlugin = await _protocolService.GetProtocolServiceAsync(receivedMessage.DeviceNo); + // if (protocolPlugin == null) + // { + // _logger.LogError("协议不存在!"); + // } + // else + // { + // if (receivedMessage.Data == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // if (receivedMessage.Data.DT == null || receivedMessage.Data.AFN_FC == null) + // { + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + // } + // string serverName = $"AFN{receivedMessage.Data.AFN_FC.AFN}_F{receivedMessage.Data.DT.Fn}_Analysis"; + // //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - await executor.ExecuteAsync(serverName, receivedMessage.Data); - return SubscribeAck.Success(); - } + // //var data = await analysisStrategy.ExecuteAsync>(tB3761); + // var executor = _serviceProvider.GetRequiredService(); + // await executor.ExecuteAsync(serverName, receivedMessage.Data); + // return SubscribeAck.Success(); + // } - return SubscribeAck.Fail(); - } + // return SubscribeAck.Fail(); + //} /// diff --git a/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs b/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs index f661842..ee5f646 100644 --- a/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs +++ b/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs @@ -1,4 +1,5 @@ using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.Kafka.Attributes; @@ -8,6 +9,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using TouchSocket.Sockets; +using static FreeSql.Internal.GlobalFilter; namespace JiShe.CollectBus.Subscribers { @@ -46,7 +48,7 @@ namespace JiShe.CollectBus.Subscribers [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerOneMinuteIssuedEventName)] public async Task AmmeterScheduledMeterOneMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage) { - _logger.LogInformation("1分钟采集电表数据下行消息消费队列开始处理"); + _logger.LogError($"1分钟采集电表数据下行消息消费队列开始处理:{receivedMessage.Serialize()}"); return await SendMessagesAsync(receivedMessage); } @@ -56,10 +58,10 @@ namespace JiShe.CollectBus.Subscribers /// /// /// - [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName)] + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFiveMinuteIssuedEventName, EnableBatch = true, BatchSize = 500)] public async Task AmmeterScheduledMeterFiveMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage) { - _logger.LogInformation("5分钟采集电表数据下行消息消费队列开始处理"); + _logger.LogError($"5分钟采集电表数据下行消息消费队列开始处理:{receivedMessage.Serialize()}"); return await SendMessagesAsync(receivedMessage); } @@ -68,11 +70,16 @@ namespace JiShe.CollectBus.Subscribers /// /// /// - //[KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName)] - public async Task AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage) + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, EnableBatch = true, TaskCount = 30, BatchSize = 500)] + public async Task AmmeterScheduledMeterFifteenMinuteReadingIssuedEvent(List receivedMessage) { - _logger.LogInformation("15分钟采集电表数据下行消息消费队列开始处理"); - return await SendMessagesAsync(receivedMessage); + + foreach (var item in receivedMessage) + { + _logger.LogError($"15分钟采集电表数据下行消息消费队列开始处理_ItemCode_{item.ItemCode}_{item.Serialize()}"); + await SendMessagesAsync(item); + } + return SubscribeAck.Success(); } /// @@ -80,14 +87,60 @@ namespace JiShe.CollectBus.Subscribers /// /// /// - [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName,EnableBatch =true,TaskCount=30,BatchSize =500)] + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, EnableBatch = true, BatchSize = 500)] public async Task AmmeterScheduledAutoValveControl(List receivedMessage) { //todo 如果是时段自动阀控,需要检查当前的时间,如果时间在自动阀控时间段内,则发送自动阀控报文,否则不发送,尤其是消息队列阻塞或者延时过长的时候。以免造成生产事故。 - //_logger.LogInformation("电表自动阀控下行消息消费队列开始处理"); - _logger.LogWarning($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + foreach (var item in receivedMessage) + { + _logger.LogError($"电表自动阀控下行消息消费队列开始处理:{item.Serialize()}"); + await SendMessagesAsync(item); + } + return SubscribeAck.Success(); + } + + /// + /// 其他采集数据下行消息主题,日冻结,月冻结、集中器版本号、SIM卡号、定时校时等下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, EnableBatch = true, BatchSize = 500)] + public async Task AmmeterScheduledOther(List receivedMessage) + { + foreach (var item in receivedMessage) + { + _logger.LogError($"其他采集数据下行消息消费队列开始处理:{item.Serialize()}"); + await SendMessagesAsync(item); + } + return SubscribeAck.Success(); + } + + /// + /// 电表手动阀控下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerManualValveControlIssuedEventName)] + public async Task AmmeterScheduledManualValveControl(MeterReadingTelemetryPacketInfo receivedMessage) + { + _logger.LogError($"电表手动阀控下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); + return SubscribeAck.Success(); + } + + /// + /// 电表手动抄读下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName)] + public async Task AmmeterScheduledManualValveReading(MeterReadingTelemetryPacketInfo receivedMessage) + { + _logger.LogError($"电表手动抄读下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); return SubscribeAck.Success(); - //return await SendMessagesAsync(receivedMessage); } /// @@ -110,7 +163,7 @@ namespace JiShe.CollectBus.Subscribers // 增加·发送次数和重试开始时间 receivedMessage.SendNum += 1; receivedMessage.NextSendTime = DateTime.Now.AddHours(1); - await _dbProvider.InsertAsync(receivedMessage); + await _dbProvider.GetSessionPool(true).InsertAsync(receivedMessage); // TODO: 第4次的时候会推送到地方预警处理 } // 由于有3次重试机会,故每次消息都会被确认 @@ -132,9 +185,54 @@ namespace JiShe.CollectBus.Subscribers /// /// [KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerAutoReadingIssuedEventName)] - public async Task WatermeterSubscriberWorkerAutoReadingIssuedEvent(MeterReadingTelemetryPacketInfo receivedMessage) + public async Task WatermeterScheduledAutoReading(MeterReadingTelemetryPacketInfo receivedMessage) { - return await SendMessagesAsync(receivedMessage); + _logger.LogError($"水表数据下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); + return SubscribeAck.Success(); + } + + /// + /// 水表自动阀控下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerAutoValveControlIssuedEventName)] + public async Task WatermeterScheduleAutoValveControl(MeterReadingTelemetryPacketInfo receivedMessage) + { + _logger.LogError($"水表自动阀控下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); + return SubscribeAck.Success(); + } + + /// + /// 水表手动阀控下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerManualValveControlIssuedEventName)] + public async Task WatermeterScheduleManualValveControl(MeterReadingTelemetryPacketInfo receivedMessage) + { + _logger.LogError($"水表手动阀控下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); + return SubscribeAck.Success(); + } + + /// + /// 水表手动抄读下行消息消费订阅 + /// + /// + /// + [KafkaSubscribe(ProtocolConst.WatermeterSubscriberWorkerManualValveReadingIssuedEventName)] + public async Task WatermeterScheduleManualValveReading(MeterReadingTelemetryPacketInfo receivedMessage) + { + _logger.LogError($"水表手动抄读下行消息消费队列开始处理:{receivedMessage.Serialize()}"); + + await SendMessagesAsync(receivedMessage); + return SubscribeAck.Success(); } #endregion @@ -156,7 +254,7 @@ namespace JiShe.CollectBus.Subscribers // 增加·发送次数和重试开始时间 receivedMessage.SendNum += 1; receivedMessage.NextSendTime = DateTime.Now.AddHours(1); - await _dbProvider.InsertAsync(receivedMessage); + await _dbProvider.GetSessionPool(true).InsertAsync(receivedMessage); return SubscribeAck.Success(); } diff --git a/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceDataInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTableModelDataInfo.cs similarity index 93% rename from services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceDataInfo.cs rename to services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTableModelDataInfo.cs index a3a0e21..4ced50b 100644 --- a/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceDataInfo.cs +++ b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTableModelDataInfo.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace JiShe.CollectBus.IotSystems.Devices { /// - /// 设备树模型数据信息 + /// 设备表型数据信息 /// [SourceAnalyzers(EntityTypeEnum.TableModel)] public class DeviceTreeModelDataInfo: IoTEntity diff --git a/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTreeModelDataInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTreeModelDataInfo.cs new file mode 100644 index 0000000..27a59c7 --- /dev/null +++ b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceTreeModelDataInfo.cs @@ -0,0 +1,22 @@ +using JiShe.CollectBus.Analyzers.Shared; +using JiShe.CollectBus.IoTDB.Attributes; +using JiShe.CollectBus.IoTDB.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.IotSystems.Devices +{ + /// + /// 设备树模型数据信息 + /// + [SourceAnalyzers(EntityTypeEnum.TableModel)] + public class DeviceTableModelDataInfo : IoTEntity + { + + [FIELDColumn] + public bool xfdsa { get; set; } + } +} diff --git a/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationApplicationContractsModule.cs b/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationApplicationContractsModule.cs new file mode 100644 index 0000000..756ba99 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationApplicationContractsModule.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; +using Volo.Abp.Authorization; + +namespace JiShe.CollectBus.Migration; + +[DependsOn( + typeof(CollectBusDomainSharedModule), + typeof(AbpDddApplicationContractsModule), + typeof(AbpAuthorizationModule) + )] +public class CollectBusMigrationApplicationContractsModule : AbpModule +{ + +} diff --git a/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationRemoteServiceConsts.cs b/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationRemoteServiceConsts.cs new file mode 100644 index 0000000..cc0c233 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/CollectBusMigrationRemoteServiceConsts.cs @@ -0,0 +1,8 @@ +namespace JiShe.CollectBus.Migration; + +public class CollectBusMigrationRemoteServiceConsts +{ + public const string RemoteServiceName = "CollectBus"; + + public const string ModuleName = "collectBus"; +} diff --git a/services/JiShe.CollectBus.Application.Contracts/DataMigration/IDataMigrationService.cs b/services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/IDataMigrationService.cs similarity index 90% rename from services/JiShe.CollectBus.Application.Contracts/DataMigration/IDataMigrationService.cs rename to services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/IDataMigrationService.cs index bbfa581..c6fbb96 100644 --- a/services/JiShe.CollectBus.Application.Contracts/DataMigration/IDataMigrationService.cs +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/IDataMigrationService.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace JiShe.CollectBus.DataMigration +namespace JiShe.CollectBus.Migration { /// /// 数据迁移服务 diff --git a/services/JiShe.CollectBus.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs b/services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs similarity index 95% rename from services/JiShe.CollectBus.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs rename to services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs index db6cfcc..6e70531 100644 --- a/services/JiShe.CollectBus.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/DataMigration/Options/DataMigrationOptions.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace JiShe.CollectBus.DataMigration.Options +namespace JiShe.CollectBus.Migration { /// /// 数据迁移配置 diff --git a/services/JiShe.CollectBus.Migration.Application.Contracts/FodyWeavers.xml b/services/JiShe.CollectBus.Migration.Application.Contracts/FodyWeavers.xml new file mode 100644 index 0000000..1715698 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/services/JiShe.CollectBus.Migration.Application.Contracts/ICollectWorker.cs b/services/JiShe.CollectBus.Migration.Application.Contracts/ICollectWorker.cs new file mode 100644 index 0000000..e2c4fa8 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/ICollectWorker.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Migration +{ + public interface ICollectWorker + { + } +} diff --git a/services/JiShe.CollectBus.Migration.Application.Contracts/JiShe.CollectBus.Migration.Application.Contracts.csproj b/services/JiShe.CollectBus.Migration.Application.Contracts/JiShe.CollectBus.Migration.Application.Contracts.csproj new file mode 100644 index 0000000..f3ef574 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application.Contracts/JiShe.CollectBus.Migration.Application.Contracts.csproj @@ -0,0 +1,34 @@ + + + + + + net8.0 + enable + JiShe.CollectBus.Migration + True + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationAppService.cs b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationAppService.cs new file mode 100644 index 0000000..5ec9a4c --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationAppService.cs @@ -0,0 +1,20 @@ +using JiShe.CollectBus.FreeRedis; +using JiShe.CollectBus.FreeSql; +using JiShe.CollectBus.Localization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Application.Services; + +namespace JiShe.CollectBus.Migration; + +[ApiExplorerSettings(GroupName = CollectBusDomainSharedConsts.Business)] +public abstract class CollectBusMigrationAppService : ApplicationService +{ + public IFreeSqlProvider SqlProvider => LazyServiceProvider.LazyGetRequiredService(); + protected IFreeRedisProvider FreeRedisProvider => LazyServiceProvider.LazyGetService()!; + + protected CollectBusMigrationAppService() + { + LocalizationResource = typeof(CollectBusResource); + ObjectMapperContext = typeof(CollectBusMigrationApplicationModule); + } +} diff --git a/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationApplicationModule.cs b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationApplicationModule.cs new file mode 100644 index 0000000..8a82b7e --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationApplicationModule.cs @@ -0,0 +1,70 @@ +using JiShe.CollectBus.FreeRedis; +using JiShe.CollectBus.FreeSql; +using JiShe.CollectBus.IoTDB; +using Microsoft.Extensions.DependencyInjection; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace JiShe.CollectBus.Migration; + +[DependsOn( + typeof(CollectBusDomainModule), + typeof(CollectBusMigrationApplicationContractsModule), + typeof(AbpDddApplicationModule), + typeof(AbpAutoMapperModule), + typeof(CollectBusFreeRedisModule), + typeof(CollectBusFreeSqlModule), + typeof(CollectBusIoTDbModule) +)] +public class CollectBusMigrationApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + context.Services.AddAutoMapperObjectMapper(); + Configure(options => { options.AddMaps(true); }); + + } + + public override async Task OnApplicationInitializationAsync( + ApplicationInitializationContext context) + { + //var assembly = Assembly.GetExecutingAssembly(); + //var types = assembly.GetTypes().Where(t => typeof(ICollectWorker).IsAssignableFrom(t) && !t.IsInterface) + // .ToList(); + //foreach (var type in types) await context.AddBackgroundWorkerAsync(type); + + //Task.Run(() => + //{ + // //默认初始化表计信息 + // var dbContext = context.ServiceProvider.GetRequiredService(); + // dbContext.InitAmmeterCacheData(); + // //await dbContext.InitWatermeterCacheData(); + //}).ConfigureAwait(false); + + ////下发任务通道构建 + //DataChannelManage.TaskDataChannel = Channel.CreateUnbounded>>(); + + + //// 日志存储通道构建 + //DataChannelManage.LogSaveChannel = Channel.CreateUnbounded(); + + //// 日志刷新通道构建 + //DataChannelManage.LogRefreshChannel = Channel.CreateUnbounded(); + + //// 启动通道任务 + //var _dataChannelManage = context.ServiceProvider.GetRequiredService(); + //_ = _dataChannelManage.LogSaveAsync(DataChannelManage.LogSaveChannel.Reader); + + ////默认初始化表计信息 + //var dbContext = context.ServiceProvider.GetRequiredService(); + //await dbContext.InitAmmeterCacheData(); + } +} \ No newline at end of file diff --git a/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationlicationAutoMapperProfile.cs b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationlicationAutoMapperProfile.cs new file mode 100644 index 0000000..4e1a5c6 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application/CollectBusMigrationlicationAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; + +namespace JiShe.CollectBus; + +public class CollectBusMigrationlicationAutoMapperProfile : Profile +{ + public CollectBusMigrationlicationAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + } +} diff --git a/services/JiShe.CollectBus.Application/DataMigration/DataMigrationService.cs b/services/JiShe.CollectBus.Migration.Application/DataMigration/DataMigrationService.cs similarity index 96% rename from services/JiShe.CollectBus.Application/DataMigration/DataMigrationService.cs rename to services/JiShe.CollectBus.Migration.Application/DataMigration/DataMigrationService.cs index f1f0c9b..b85d5b0 100644 --- a/services/JiShe.CollectBus.Application/DataMigration/DataMigrationService.cs +++ b/services/JiShe.CollectBus.Migration.Application/DataMigration/DataMigrationService.cs @@ -1,5 +1,4 @@ -using JiShe.CollectBus.DataMigration.Options; -using JiShe.CollectBus.IotSystems.MeterReadingRecords; +using JiShe.CollectBus.IotSystems.MeterReadingRecords; using LiteDB; using Microsoft.Extensions.Options; using System; @@ -9,12 +8,12 @@ using System.Threading.Channels; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; -namespace JiShe.CollectBus.DataMigration +namespace JiShe.CollectBus.Migration.DataMigration { /// /// 数据迁移服务 /// - public class DataMigrationService: CollectBusAppService, IDataMigrationService + public class DataMigrationService: CollectBusMigrationAppService, IDataMigrationService { private readonly IRepository _meterReadingRecordsRepository; private readonly DataMigrationOptions _options; diff --git a/services/JiShe.CollectBus.Migration.Application/FodyWeavers.xml b/services/JiShe.CollectBus.Migration.Application/FodyWeavers.xml new file mode 100644 index 0000000..1715698 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/services/JiShe.CollectBus.Migration.Application/JiShe.CollectBus.Migration.Application.csproj b/services/JiShe.CollectBus.Migration.Application/JiShe.CollectBus.Migration.Application.csproj new file mode 100644 index 0000000..bce2a34 --- /dev/null +++ b/services/JiShe.CollectBus.Migration.Application/JiShe.CollectBus.Migration.Application.csproj @@ -0,0 +1,35 @@ + + + + + + net8.0 + enable + JiShe.CollectBus.Migration + True + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/JiShe.CollectBus.Common/BuildSendDatas/Build3761SendData.cs b/shared/JiShe.CollectBus.Common/BuildSendDatas/Build3761SendData.cs index 76f6b88..2d815da 100644 --- a/shared/JiShe.CollectBus.Common/BuildSendDatas/Build3761SendData.cs +++ b/shared/JiShe.CollectBus.Common/BuildSendDatas/Build3761SendData.cs @@ -1362,7 +1362,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas /// 等待报文超时时间/s /// 等待字节超时时间/ms /// - private static List BuildTransparentForwardingSendDataUnit(int port, int baudRate, List datas, StopBit stopBit = StopBit.Stop1, Parity parity = Parity.Even, DataBit dataBit = DataBit.D8, + public static List BuildTransparentForwardingSendDataUnit(int port, int baudRate, List datas, StopBit stopBit = StopBit.Stop1, Parity parity = Parity.Even, DataBit dataBit = DataBit.D8, int waitContentTimeout = 100, int waitByteTimeout = 100) { var dataUnit = new List(); @@ -1591,7 +1591,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas //AUX=消息认证码字段(PW,16个字节) - private static List GetPW() + public static List GetPW() { var str = "00"; var pWList = Enumerable.Repeat(str, pWLen).ToList(); diff --git a/shared/JiShe.CollectBus.Common/Consts/MeteringPortConst.cs b/shared/JiShe.CollectBus.Common/Consts/MeteringPortConst.cs new file mode 100644 index 0000000..c65b027 --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Consts/MeteringPortConst.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Consts +{ + /// + /// 计量端口常量 + /// + public class MeteringPortConst + { + /// + /// 计量端口1 + /// + public const int MeteringPortOne = 1; + + /// + /// 计量端口2 + /// + public const int MeteringPortTwo = 2; + } +} diff --git a/shared/JiShe.CollectBus.Common/Consts/T37612012PacketItemCodeConst.cs b/shared/JiShe.CollectBus.Common/Consts/T37612012PacketItemCodeConst.cs index 2f16084..47f053d 100644 --- a/shared/JiShe.CollectBus.Common/Consts/T37612012PacketItemCodeConst.cs +++ b/shared/JiShe.CollectBus.Common/Consts/T37612012PacketItemCodeConst.cs @@ -19,6 +19,12 @@ namespace JiShe.CollectBus.Common.Consts /// public const string AFN10HFN01H = $"10_01"; + + /// + /// 电网频率 + /// + public const string AFN10HFN97H = $"10_97"; + /// /// 读取终端信息 /// @@ -181,5 +187,19 @@ namespace JiShe.CollectBus.Common.Consts } #endregion + + /// + /// 特殊645编码关系映射 + /// + /// + /// + public static (string,string) MappingItemCodeTo645SubCodeRelationship(string itemCode) + { + return itemCode switch + { + AFN10HFN97H => (AFN10HFN01H,T6452007PacketItemCodeConst.C1102800002), + _=> (itemCode,""), + }; + } } } diff --git a/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs b/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs index 92da5ba..734bc7a 100644 --- a/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs +++ b/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs @@ -16,37 +16,37 @@ namespace JiShe.CollectBus.Common.Consts /// /// 跳闸 /// - public const string C1C01A = "1C_1A"; + public const string C1C011A = "1C_01_1A"; /// - /// 单相合闸 + /// 合闸允许 /// - public const string C1C01B = "1C_1B"; + public const string C1C011B = "1C_01_1B"; /// - /// 三相合闸 + /// 合闸 /// - public const string C1C01C = "1C_1C"; - + public const string C1C011C = "1C_01_1C"; + /// /// 触发报警 /// - public const string C1C02A = "1C_2A"; + public const string C1C021A = "1C_01_2A"; /// /// 报警解除 /// - public const string C1C02B = "1C_2B"; + public const string C1C012B = "1C_01_2B"; /// /// 保电开始 /// - public const string C1C03A = "1C_3A"; + public const string C1C033A = "1C_03_3A"; /// /// 保电结束 /// - public const string C1C03B = "1C_3B"; + public const string C1C033B = "1C_03_3B"; #endregion #region 广播校时 @@ -56,6 +56,16 @@ namespace JiShe.CollectBus.Common.Consts /// public const string C08 = "08"; #endregion + + #region 读数据 + + + /// + /// 电网频率 + /// + public const string C1102800002 = "11_02_80_00_02"; + #endregion + #endregion } } diff --git a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs index 7d3fc4a..e6cbafd 100644 --- a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs +++ b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs @@ -835,6 +835,11 @@ namespace JiShe.CollectBus.Common.Helpers /// public static bool JudgeIsGenerate_Day(string eachDayWithout, DateTime curTime) { + if (string.IsNullOrWhiteSpace(eachDayWithout)) + { + return false; + } + var weekName = strWeeks[(int)curTime.DayOfWeek]; var arr = eachDayWithout.Split(','); return !arr.Contains(weekName); diff --git a/shared/JiShe.CollectBus.Domain.Shared/CollectBusDomainSharedConsts.cs b/shared/JiShe.CollectBus.Domain.Shared/CollectBusDomainSharedConsts.cs index 8c06a44..63ab843 100644 --- a/shared/JiShe.CollectBus.Domain.Shared/CollectBusDomainSharedConsts.cs +++ b/shared/JiShe.CollectBus.Domain.Shared/CollectBusDomainSharedConsts.cs @@ -14,7 +14,7 @@ namespace JiShe.CollectBus public const string DefaultCultureName = "zh-Hans"; public const string Basic = "Basic"; - public const string Business = "Business"; + public const string Business = "Business"; } } diff --git a/web/JiShe.CollectBus.Host/Pages/Monitor.cshtml b/web/JiShe.CollectBus.Host/Pages/Monitor.cshtml index 8674d67..4e13d71 100644 --- a/web/JiShe.CollectBus.Host/Pages/Monitor.cshtml +++ b/web/JiShe.CollectBus.Host/Pages/Monitor.cshtml @@ -6,7 +6,7 @@ @{ Layout = null; } - + @@ -16,6 +16,7 @@ 后端服务 + diff --git a/web/JiShe.CollectBus.Host/appsettings.json b/web/JiShe.CollectBus.Host/appsettings.json index a3ed9de..64893f2 100644 --- a/web/JiShe.CollectBus.Host/appsettings.json +++ b/web/JiShe.CollectBus.Host/appsettings.json @@ -35,13 +35,13 @@ "CorsOrigins": "http://localhost:4200,http://localhost:3100" }, "ConnectionStrings": { - "Default": "mongodb://mongo_PmEeF3:lixiao1980@192.168.1.9:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000", - "Kafka": "192.168.1.9:29092,192.168.1.9:39092,192.168.1.9:49092", + "Default": "mongodb://mongo_PmEeF3:lixiao1980@192.168.5.9:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000", + "Kafka": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092", "PrepayDB": "server=118.190.144.92;database=jishe.sysdb;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False", - "EnergyDB": "server=rm-wz9hw529i3j1e3b5fbo.sqlserver.rds.aliyuncs.com,3433;database=db_energy;uid=yjdb;pwd=Kdjdhf+9*7ad222LL;Encrypt=False;Trust Server Certificate=False" + "EnergyDB": "server=118.190.144.92;database=db_energy;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False" }, "Redis": { - "Configuration": "192.168.1.9:6380,password=1q2w3e!@#,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true", + "Configuration": "192.168.5.9:6380,password=1q2w3e!@#,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true", "MaxPoolSize": "50", "DefaultDB": "14", "HangfireDB": "13" @@ -71,7 +71,7 @@ } ], "Kafka": { - "BootstrapServers": "192.168.1.9:29092,192.168.1.9:39092,192.168.1.9:49092", + "BootstrapServers": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092", "EnableFilter": true, "EnableAuthorization": false, "SecurityProtocol": "SaslPlaintext", @@ -85,10 +85,10 @@ "IoTDBOptions": { "UserName": "root", "Password": "root", - "ClusterList": [ "192.168.1.9:6667" ], + "ClusterList": [ "192.168.5.9:6667" ], "PoolSize": 32, "DataBaseName": "energy", - "OpenDebugMode": false, + "OpenDebugMode": true, "UseTableSessionPoolByDefault": false }, "Cassandra": { @@ -103,19 +103,19 @@ }, "Nodes": [ { - "Host": "192.168.1.9", + "Host": "192.168.5.9", "Port": 9042, "DataCenter": "dc1", "Rack": "RAC1" }, { - "Host": "192.168.1.9", + "Host": "192.168.5.9", "Port": 9043, "DataCenter": "dc1", "Rack": "RAC2" }, { - "Host": "192.168.1.9", + "Host": "192.168.5.9", "Port": 9044, "DataCenter": "dc1", "Rack": "RAC2" @@ -141,7 +141,7 @@ } }, "ServerApplicationOptions": { - "ServerTagName": "JiSheCollectBus999", + "ServerTagName": "JiSheCollectBus8", "SystemType": "Energy", "FirstCollectionTime": "2025-04-28 15:07:00", "AutomaticVerificationTime": "16:07:00", @@ -153,6 +153,6 @@ }, "PlugInFolder": "", "TCP": { - "ClientPort": 10502 + "ClientPort": 10500 } } \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostConst.cs b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostConst.cs new file mode 100644 index 0000000..d710275 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostConst.cs @@ -0,0 +1,40 @@ +namespace JiShe.CollectBus.Migration.Host +{ + /// + /// CollectBusMigrationHostConst + /// + public static class CollectBusMigrationHostConst + { + /// + /// 跨域策略名 + /// + public const string DefaultCorsPolicyName = "Default"; + + /// + /// Cookies名称 + /// + public const string DefaultCookieName = "JiShe.CollectBus.Migration.Host"; + + /// + /// SwaggerUi 端点 + /// + public const string SwaggerUiEndPoint = "/swagger"; + + /// + /// Hangfire 端点 + /// + public const string HangfireDashboardEndPoint = "/hangfire"; + + /// + /// 健康检查 端点 + /// + public const string HealthEndPoint = "/health"; + + /// + /// 健康检查 端点 + /// + public const string HealthDashboardEndPoint = "/health-ui"; + + + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.Configure.cs b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.Configure.cs new file mode 100644 index 0000000..33c2b3a --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.Configure.cs @@ -0,0 +1,266 @@ +//using Hangfire; +//using Hangfire.Redis.StackExchange; +using JiShe.CollectBus.Migration.Host.Hangfire; +using JiShe.CollectBus.Migration.Host.HealthChecks; +using JiShe.CollectBus.Migration.Host.Swaggers; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; +using StackExchange.Redis; +using System.Text; +using Volo.Abp.AspNetCore.Auditing; +using Volo.Abp.Auditing; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Caching; +using Volo.Abp.Modularity; + + +namespace JiShe.CollectBus.Migration.Host +{ + public partial class CollectBusMigrationHostModule + { + /// + /// Configures the hangfire. + /// + /// The context. + //private void ConfigureHangfire(ServiceConfigurationContext context) + //{ + // var redisStorageOptions = new RedisStorageOptions() + // { + // Db = context.Services.GetConfiguration().GetValue("Redis:HangfireDB") + // }; + + // Configure(options => { options.IsJobExecutionEnabled = false; }); + + // context.Services.AddHangfire(config => + // { + // config.UseRedisStorage( + // context.Services.GetConfiguration().GetValue("Redis:Configuration"), redisStorageOptions) + // .WithJobExpirationTimeout(TimeSpan.FromDays(7)); + // var delaysInSeconds = new[] { 10, 60, 60 * 3 }; // 重试时间间隔 + // const int Attempts = 3; // 重试次数 + // config.UseFilter(new AutomaticRetryAttribute() { Attempts = Attempts, DelaysInSeconds = delaysInSeconds }); + // //config.UseFilter(new AutoDeleteAfterSuccessAttribute(TimeSpan.FromDays(7))); + // config.UseFilter(new JobRetryLastFilter(Attempts)); + // }); + // context.Services.AddHangfireServer(); + //} + + /// + /// Configures the JWT authentication. + /// + /// The context. + /// The configuration. + private void ConfigureJwtAuthentication(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => + { + options.TokenValidationParameters = + new TokenValidationParameters() + { + // 是否开启签名认证 + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ClockSkew = TimeSpan.Zero, + ValidIssuer = configuration["Jwt:Issuer"], + ValidAudience = configuration["Jwt:Audience"], + IssuerSigningKey = + new SymmetricSecurityKey( + Encoding.ASCII.GetBytes(configuration["Jwt:SecurityKey"])) + }; + + options.Events = new JwtBearerEvents + { + OnMessageReceived = currentContext => + { + var path = currentContext.HttpContext.Request.Path; + if (path.StartsWithSegments("/login")) + { + return Task.CompletedTask; + } + + var accessToken = string.Empty; + if (currentContext.HttpContext.Request.Headers.ContainsKey("Authorization")) + { + accessToken = currentContext.HttpContext.Request.Headers["Authorization"]; + if (!string.IsNullOrWhiteSpace(accessToken)) + { + accessToken = accessToken.Split(" ").LastOrDefault(); + } + } + + if (string.IsNullOrWhiteSpace(accessToken)) + { + accessToken = currentContext.Request.Query["access_token"].FirstOrDefault(); + } + + if (string.IsNullOrWhiteSpace(accessToken)) + { + accessToken = currentContext.Request.Cookies[@CollectBusMigrationHostConst.DefaultCookieName]; + } + + currentContext.Token = accessToken; + currentContext.Request.Headers.Remove("Authorization"); + currentContext.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); + + return Task.CompletedTask; + } + }; + }); + } + + /// + /// Configures the cache. + /// + /// The context. + private void ConfigureCache(ServiceConfigurationContext context) + { + Configure( + options => { options.KeyPrefix = "CollectBus:"; }); + var configuration = context.Services.GetConfiguration(); + var redis = ConnectionMultiplexer.Connect($"{configuration.GetValue("Redis:Configuration")},defaultdatabase={configuration.GetValue("Redis:DefaultDB")}"); + context.Services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "CollectBus-Protection-Keys"); + } + + /// + /// Configures the swagger services. + /// + /// The context. + /// The configuration. + private void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddSwaggerGen( + options => + { + configuration.GetSection("SwaggerConfig").Get>()?.ForEach(group => + { + options.SwaggerDoc(group.GroupName, + new OpenApiInfo { Title = group.Title, Version = group.Version }); + }); + + options.DocInclusionPredicate((docName, apiDes) => + { + if (docName == "Basic" && string.IsNullOrWhiteSpace(apiDes.GroupName)) return true; + return docName == apiDes.GroupName; + }); + + options.EnableAnnotations(); + options.DocumentFilter(); + options.SchemaFilter(); + var xmlPaths = Directory.GetFiles(AppContext.BaseDirectory, "*.xml") + .Where(a => a.EndsWith("Application.xml") || + a.EndsWith("Application.Contracts.xml") || + a.EndsWith("httpApi.xml") || + a.EndsWith("Host.xml")) + .Distinct() + .ToList(); + foreach (var xml in xmlPaths) options.IncludeXmlComments(xml, true); + }); + } + + /// + /// Configures the audit log. + /// + /// The context. + private void ConfigureAuditLog(ServiceConfigurationContext context) + { + Configure + ( + options => + { + options.IsEnabled = true; + options.EntityHistorySelectors.AddAllEntities(); + options.ApplicationName = "JiShe.CollectBus.Migration"; + } + ); + + Configure( + options => + { + options.IgnoredUrls.Add("/AuditLogs/page"); + options.IgnoredUrls.Add("/hangfire/stats"); + options.IgnoredUrls.Add("/hangfire/recurring/trigger"); + options.IgnoredUrls.Add("/cap"); + options.IgnoredUrls.Add("/"); + }); + } + + + /// + /// Configures the custom. + /// + /// The context. + /// The configuration. + private void ConfigureCustom(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddSingleton(); + } + + /// + /// Configures the network. + /// + /// The context. + /// The configuration. + public void ConfigureNetwork(ServiceConfigurationContext context, IConfiguration configuration) + { + //context.Services.AddTcpService(config => + //{ + // config.SetListenIPHosts(int.Parse(configuration["TCP:ClientPort"] ?? "10500")) + // //.SetTcpDataHandlingAdapter(()=>new StandardFixedHeaderDataHandlingAdapter()) + // //.SetGetDefaultNewId(() => Guid.NewGuid().ToString())//定义ClientId的生成策略 + // .ConfigurePlugins(a => + // { + // a.Add(); + // a.Add(); + // a.Add(); + // }); + //}); + + //context.Services.AddUdpSession(config => + //{ + // config.SetBindIPHost(int.Parse(configuration["UDP:ClientPort"] ?? "10500")) + // .ConfigurePlugins(a => + // { + // a.Add(); + // a.Add(); + // }) + // .UseBroadcast() + // .SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter()); + //}); + } + + /// + /// 健康检查 + /// + /// + /// + private void ConfigureHealthChecks(ServiceConfigurationContext context, IConfiguration configuration) + { + if (!configuration.GetValue("HealthChecks:IsEnable")) return; + context.Services.AddHealthChecks() + .AddRedis(configuration.GetValue("Redis:Configuration") ?? string.Empty, "Redis", + HealthStatus.Unhealthy) + .AddCheck("IoTDB"); + + context.Services + .AddHealthChecksUI(options => + { + options.AddHealthCheckEndpoint("JiSheCollectBusMigration", "/health"); // 映射本地端点 + }) + .AddInMemoryStorage(); + + + } + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.cs b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.cs new file mode 100644 index 0000000..0f90aa7 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/CollectBusMigrationHostModule.cs @@ -0,0 +1,109 @@ +using Hangfire; +using JiShe.CollectBus.Common; +using JiShe.CollectBus.Migration.Host.HealthChecks; +using JiShe.CollectBus.Migration.Host.Swaggers; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Swashbuckle.AspNetCore.SwaggerUI; +using Volo.Abp; +using Volo.Abp.AspNetCore; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.BackgroundWorkers.Hangfire; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Modularity; +using Volo.Abp.Swashbuckle; +using Volo.Abp.Timing; + +namespace JiShe.CollectBus.Migration.Host +{ + /// + /// + /// + [DependsOn(typeof(CollectBusMigrationHttpApiModule), + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpSwashbuckleModule), + typeof(AbpTimingModule), + typeof(CollectBusMigrationApplicationModule), + typeof(AbpCachingStackExchangeRedisModule) + )] + public partial class CollectBusMigrationHostModule : AbpModule + { + /// + /// ConfigureServices + /// + /// + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + ConfigureCache(context); + ConfigureSwaggerServices(context, configuration); + //ConfigureNetwork(context, configuration); + ConfigureJwtAuthentication(context, configuration); + //ConfigureHangfire(context); + ConfigureAuditLog(context); + ConfigureCustom(context, configuration); + ConfigureHealthChecks(context, configuration); + Configure(options => { options.Kind = DateTimeKind.Local; }); + + Configure(options => + { + configuration.GetSection(nameof(ServerApplicationOptions)).Bind(options); + }); + + } + + + /// + /// OnApplicationInitialization + /// + /// + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var configuration = context.GetConfiguration(); + var env = context.GetEnvironment(); + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(CollectBusMigrationHostConst.DefaultCorsPolicyName); + app.UseAuthentication(); + app.UseAuthorization(); + if (env.IsDevelopment()) + { + app.UseSwagger(); + app.UseAbpSwaggerUI(options => + { + configuration.GetSection("SwaggerConfig").Get>()?.ForEach(group => + { + options.SwaggerEndpoint($"/swagger/{group.GroupName}/swagger.json", group.Title); //分组显示 + }); + options.DocExpansion(DocExpansion.None); + options.DefaultModelsExpandDepth(-1); + }); + } + //app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseUnitOfWork(); + //app.UseHangfireDashboard("/hangfire", new DashboardOptions + //{ + // IgnoreAntiforgeryToken = true + //}); + app.UseConfiguredEndpoints(endpoints => + { + if (!configuration.GetValue("HealthChecks:IsEnable")) return; + endpoints.MapHealthChecks("/health", new HealthCheckOptions + { + Predicate = _ => true, + ResponseWriter = HealthCheckResponse.Writer + }); + endpoints.MapHealthChecksUI(options => + { + options.UIPath = "/health-ui"; + }); + }); + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Controllers/HomeController.cs b/web/JiShe.CollectBus.Migration.Host/Controllers/HomeController.cs new file mode 100644 index 0000000..be4c1c6 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Controllers/HomeController.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace JiShe.CollectBus.Migration.Host.Controllers +{ + public class HomeController : AbpController + { + public ActionResult Index() + { + return Redirect("/Monitor"); + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Extensions/CustomApplicationBuilderExtensions.cs b/web/JiShe.CollectBus.Migration.Host/Extensions/CustomApplicationBuilderExtensions.cs new file mode 100644 index 0000000..6dab344 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Extensions/CustomApplicationBuilderExtensions.cs @@ -0,0 +1,10 @@ +namespace JiShe.CollectBus.Migration.Host.Extensions +{ + public static class CustomApplicationBuilderExtensions + { + public static IApplicationBuilder UseProtocolPlugin(this IApplicationBuilder app) + { + return app; + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Extensions/ServiceCollections/ServiceCollectionExtensions.cs b/web/JiShe.CollectBus.Migration.Host/Extensions/ServiceCollections/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..9351c45 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Extensions/ServiceCollections/ServiceCollectionExtensions.cs @@ -0,0 +1,49 @@ +using System.Reflection; +using Volo.Abp.Modularity; + +// ReSharper disable once CheckNamespace +namespace Microsoft.Extensions.DependencyInjection +{ + public static class ServiceCollectionExtensions + { + public static void AddPluginApplications(this IServiceCollection services, string pluginPath = "") + { + if (string.IsNullOrWhiteSpace(pluginPath)) + { + pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"); + } + var assemblies = GetAssembliesFromFolder(pluginPath); + + foreach (var assembly in assemblies) + { + var applicationServiceType = assembly.GetTypes() + .FirstOrDefault(a => a.IsClass && !a.IsAbstract && typeof(AbpModule).IsAssignableFrom(a)); + services.AddApplication(applicationServiceType); + } + } + + private static IEnumerable GetAssembliesFromFolder(string folderPath) + { + var directory = new DirectoryInfo(folderPath); + if (!directory.Exists) return []; + + var files = directory.GetFiles("*.dll"); + + var assemblies = new List(); + foreach (var file in files) + { + try + { + var assembly = Assembly.LoadFrom(file.FullName); + assemblies.Add(assembly); + } + catch (Exception ex) + { + Console.WriteLine($"Error loading assembly from {file.FullName}: {ex.Message}"); + } + } + + return assemblies; + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Hangfire/JobRetryLastFilter.cs b/web/JiShe.CollectBus.Migration.Host/Hangfire/JobRetryLastFilter.cs new file mode 100644 index 0000000..83d68ae --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Hangfire/JobRetryLastFilter.cs @@ -0,0 +1,29 @@ +using Hangfire.Common; +using Hangfire.States; +using Serilog; + +namespace JiShe.CollectBus.Migration.Host.Hangfire +{ + /// + /// 重试最后一次 + /// + public class JobRetryLastFilter : JobFilterAttribute, IElectStateFilter + { + private int RetryCount { get; } + + public JobRetryLastFilter(int retryCount) + { + RetryCount = retryCount; + } + + + public void OnStateElection(ElectStateContext context) + { + var retryAttempt = context.GetJobParameter("RetryCount"); + if (RetryCount == retryAttempt) + { + Log.Error("最后一次重试"); + } + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/HealthChecks/HealthCheckResponse.cs b/web/JiShe.CollectBus.Migration.Host/HealthChecks/HealthCheckResponse.cs new file mode 100644 index 0000000..d15a5da --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/HealthChecks/HealthCheckResponse.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Newtonsoft.Json; + +namespace JiShe.CollectBus.Migration.Host.HealthChecks +{ + public class HealthCheckResponse + { + public static Task Writer(HttpContext context, HealthReport healthReport) + { + context.Response.ContentType = "application/json"; + + var result = JsonConvert.SerializeObject(new + { + status = healthReport.Status.ToString(), + errors = healthReport.Entries.Select(e => new + { + key = e.Key, + value = e.Value.Status.ToString() + }) + }); + return context.Response.WriteAsync(result); + + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/HealthChecks/IoTDBHealthCheck.cs b/web/JiShe.CollectBus.Migration.Host/HealthChecks/IoTDBHealthCheck.cs new file mode 100644 index 0000000..31956d9 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/HealthChecks/IoTDBHealthCheck.cs @@ -0,0 +1,47 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace JiShe.CollectBus.Migration.Host.HealthChecks +{ + /// + /// IoTDBHealthCheck + /// + /// + public class IoTdbHealthCheck : IHealthCheck + { + private readonly IConfiguration _configuration; + + /// + /// Initializes a new instance of the class. + /// + /// The configuration. + public IoTdbHealthCheck(IConfiguration configuration) + { + _configuration = configuration; + } + + /// + /// Runs the health check, returning the status of the component being checked. + /// + /// A context object associated with the current execution. + /// A that can be used to cancel the health check. + /// + /// A that completes when the health check has finished, yielding the status of the component being checked. + /// + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + try + { + // todo 此处需要单独创建连接,并需要在连接打开以后立即关闭,否则会影响整个连接的使用。 + //var ioTDbOptions = new IoTDbOptions(); + //_configuration.GetSection("IoTDBOptions").Bind(ioTDbOptions); + //var pool = new SessionPoolAdapter(ioTDbOptions); + //await pool.OpenAsync(); + return HealthCheckResult.Healthy($"IoTDB is healthy."); + } + catch (Exception ex) + { + return new HealthCheckResult(context.Registration.FailureStatus, $"IoTDB不健康: {ex.Message}", ex); + } + } + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/JiShe.CollectBus.Migration.Host.csproj b/web/JiShe.CollectBus.Migration.Host/JiShe.CollectBus.Migration.Host.csproj new file mode 100644 index 0000000..d201582 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/JiShe.CollectBus.Migration.Host.csproj @@ -0,0 +1,67 @@ + + + + net8.0 + enable + enable + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml b/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml new file mode 100644 index 0000000..9bd1e80 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml @@ -0,0 +1,188 @@ +@page +@using JiShe.CollectBus.Migration.Host +@model JiShe.CollectBus.Migration.Host.Pages.Monitor + + +@{ + Layout = null; +} + + + + + + + + + + 后端服务 + + + + +
+ +
+
+
+ + + +
+

+ SwaggerUI +

+
+
+
+ +
+
+ + + +
+

+ Hangfire面板 +

+
+
+
+
+
+ + + +
+

+ 健康检查API | + UI +

+
+
+
+ @*
+
+ + + +
+

+ 了解更多... +

+
+
+
*@ +
+
+ + + \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml.cs b/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml.cs new file mode 100644 index 0000000..feab3b1 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Pages/Monitor.cshtml.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace JiShe.CollectBus.Migration.Host.Pages +{ + public class Monitor : PageModel + { + + public void OnGet() + { + + } + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/Program.cs b/web/JiShe.CollectBus.Migration.Host/Program.cs new file mode 100644 index 0000000..a9bd5b9 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Program.cs @@ -0,0 +1,47 @@ +using Microsoft.Extensions.Configuration; +using Serilog; +using Volo.Abp.Modularity.PlugIns; + +namespace JiShe.CollectBus.Migration.Host; + +/// +/// Program +/// +public class Program +{ + /// + /// Main + /// + /// + /// + public static async Task Main(string[] args) + { + //var builder = WebApplication.CreateBuilder(args); + //builder.Host + // .UseContentRoot(Directory.GetCurrentDirectory()) + // .UseSerilog((context, loggerConfiguration) => + // { + // loggerConfiguration.ReadFrom.Configuration(context.Configuration); + // }) + // .UseAutofac(); + //var app = builder.Build(); + //await app.InitializeApplicationAsync(); + //await app.RunAsync(); + + var builder = WebApplication.CreateBuilder(args); + builder.Host.UseContentRoot(Directory.GetCurrentDirectory()) + .UseSerilog((context, loggerConfiguration) => + { + loggerConfiguration.ReadFrom.Configuration(context.Configuration); + }) + .UseAutofac(); + var configuration = builder.Configuration; + await builder.AddApplicationAsync(options => + { + //options.PlugInSources.AddFolder((configuration["PlugInFolder"].IsNullOrWhiteSpace() ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins") : configuration["PlugInFolder"]) ?? string.Empty); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/Properties/launchSettings.json b/web/JiShe.CollectBus.Migration.Host/Properties/launchSettings.json new file mode 100644 index 0000000..642958f --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "JiShe.CollectBus.Migration.Host": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "http://localhost:44316", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/Swaggers/EnumSchemaFilter.cs b/web/JiShe.CollectBus.Migration.Host/Swaggers/EnumSchemaFilter.cs new file mode 100644 index 0000000..f06c6ab --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Swaggers/EnumSchemaFilter.cs @@ -0,0 +1,24 @@ +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace JiShe.CollectBus.Migration.Host.Swaggers +{ + /// + /// swagger 枚举映射, + /// 原因:前端代理生成枚举是数字 + /// + public class EnumSchemaFilter : ISchemaFilter + { + public void Apply(OpenApiSchema schema, SchemaFilterContext context) + { + if (!context.Type.IsEnum) + return; + OpenApiArray openApiArray = new OpenApiArray(); + openApiArray.AddRange((IEnumerable)Enum.GetNames(context.Type).Select(n => new OpenApiString(n))); + schema.Extensions.Add("x-enumNames", openApiArray); + schema.Extensions.Add("x-enum-varnames", openApiArray); + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Swaggers/HiddenAbpDefaultApiFilter.cs b/web/JiShe.CollectBus.Migration.Host/Swaggers/HiddenAbpDefaultApiFilter.cs new file mode 100644 index 0000000..a5ae689 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Swaggers/HiddenAbpDefaultApiFilter.cs @@ -0,0 +1,54 @@ +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace JiShe.CollectBus.Migration.Host.Swaggers +{ + /// + /// 在使用nswag的时候,原生默认的api导致生产的代理类存在问题 + /// 所有隐藏原生的api,重写路由 + /// + public class HiddenAbpDefaultApiFilter : IDocumentFilter + { + public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + { + foreach (ApiDescription apiDescription in context.ApiDescriptions) + { + if (apiDescription.TryGetMethodInfo(out MethodInfo _)) + { + string key = "/" + apiDescription.RelativePath; + if (IsHidden(key)) + swaggerDoc.Paths.Remove(key); + } + } + } + + private bool IsHidden(string key) + { + foreach (string hiddenAbpDefaultApi in GetHiddenAbpDefaultApiList()) + { + if (key.Contains(hiddenAbpDefaultApi)) + return true; + } + return false; + } + + private List GetHiddenAbpDefaultApiList() + { + return new List() + { + "/api/abp/multi-tenancy/tenants", + "/api/account", + "/api/feature-management/features", + "/api/permission-management/permissions", + "/api/identity/my-profile", + "/api/identity", + "/api/multi-tenancy/tenants", + "/api/setting-management/emailing", + "/configuration", + "/outputcache" + }; + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/Swaggers/SwaggerConfig.cs b/web/JiShe.CollectBus.Migration.Host/Swaggers/SwaggerConfig.cs new file mode 100644 index 0000000..a363ebb --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/Swaggers/SwaggerConfig.cs @@ -0,0 +1,11 @@ +namespace JiShe.CollectBus.Migration.Host.Swaggers +{ + public class SwaggerConfig + { + public string GroupName { get; set; } + + public string Title { get; set; } + + public string Version { get; set; } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/appsettings.Development.json b/web/JiShe.CollectBus.Migration.Host/appsettings.Development.json new file mode 100644 index 0000000..bcdd3fc --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/web/JiShe.CollectBus.Migration.Host/appsettings.Production.json b/web/JiShe.CollectBus.Migration.Host/appsettings.Production.json new file mode 100644 index 0000000..9c7d2e0 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/appsettings.Production.json @@ -0,0 +1,84 @@ +{ + "ConnectionStrings": { + "Default": "mongodb://admin:4mFmPTTB8tn6aI@47.110.62.104:27017,47.110.53.196:27017,47.110.60.222:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000", + "PrepayDB": "server=118.190.144.92;database=jishe.sysdb;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False", + "EnergyDB": "server=118.190.144.92;database=db_energy;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False" + }, + "Redis": { + "Configuration": "47.110.60.222:6379,password=3JBGfyhTaD46nS,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true", + "MaxPoolSize": "50", + "DefaultDB": "14", + "HangfireDB": "13" + }, + "Kafka": { + "BootstrapServers": "47.110.62.104:9092,47.110.53.196:9092,47.110.60.222:9092", + "EnableFilter": true, + "EnableAuthorization": false, + "SecurityProtocol": "SaslPlaintext", + "SaslMechanism": "Plain", + "SaslUserName": "lixiao", + "SaslPassword": "lixiao1980", + "KafkaReplicationFactor": 3, + "NumPartitions": 30, + "ServerTagName": "JiSheCollectBus100", + "FirstCollectionTime": "2025-04-22 16:07:00" + }, + "IoTDBOptions": { + "UserName": "root", + "Password": "Yp2eU6MVdIjXCL", + "ClusterList": [ "47.110.53.196:6667", "47.110.60.222:6667", "47.110.62.104:6667" ], + "PoolSize": 2, + "DataBaseName": "energy", + "OpenDebugMode": true, + "UseTableSessionPoolByDefault": false + }, + "Cassandra": { + "ReplicationStrategy": { + "Class": "NetworkTopologyStrategy", //策略为NetworkTopologyStrategy时才会有多个数据中心,SimpleStrategy用在只有一个数据中心的情况下 + "DataCenters": [ + { + "Name": "dc1", + "ReplicationFactor": 3 + } + ] + }, + "Nodes": [ + { + "Host": "121.42.175.177", + "Port": 19042, + "DataCenter": "dc1", + "Rack": "RAC1" + }, + { + "Host": "121.42.175.177", + "Port": 19043, + "DataCenter": "dc1", + "Rack": "RAC2" + }, + { + "Host": "121.42.175.177", + "Port": 19044, + "DataCenter": "dc1", + "Rack": "RAC2" + } + ], + "Username": "admin", + "Password": "lixiao1980", + "Keyspace": "jishecollectbus", + "ConsistencyLevel": "Quorum", + "PoolingOptions": { + "CoreConnectionsPerHost": 4, + "MaxConnectionsPerHost": 8, + "MaxRequestsPerConnection": 2000 + }, + "SocketOptions": { + "ConnectTimeoutMillis": 10000, + "ReadTimeoutMillis": 20000 + }, + "QueryOptions": { + "ConsistencyLevel": "Quorum", + "SerialConsistencyLevel": "Serial", + "DefaultIdempotence": true + } + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/appsettings.json b/web/JiShe.CollectBus.Migration.Host/appsettings.json new file mode 100644 index 0000000..d7ebf50 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/appsettings.json @@ -0,0 +1,158 @@ +{ + "Serilog": { + "Using": [ + "Serilog.Sinks.Console", + "Serilog.Sinks.File" + ], + "MinimumLevel": { + "Default": "Warning", + "Override": { + "Microsoft": "Warning", + "Volo.Abp": "Warning", + "Hangfire": "Warning", + "DotNetCore.CAP": "Warning", + "Serilog.AspNetCore": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.AspNetCore": "Warning", + "Microsoft.AspNetCore.Diagnostics.HealthChecks": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console" + }, + { + "Name": "File", + "Args": { + "path": "logs/logs-.txt", + "rollingInterval": "Day" + } + } + ] + }, + "App": { + "SelfUrl": "http://localhost:44315", + "CorsOrigins": "http://localhost:4200,http://localhost:3100" + }, + "ConnectionStrings": { + "Default": "mongodb://mongo_PmEeF3:lixiao1980@192.168.5.9:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000", + "Kafka": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092", + "PrepayDB": "server=118.190.144.92;database=jishe.sysdb;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False", + "EnergyDB": "server=118.190.144.92;database=db_energy;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False" + }, + "Redis": { + "Configuration": "192.168.5.9:6380,password=1q2w3e!@#,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true", + "MaxPoolSize": "50", + "DefaultDB": "14", + "HangfireDB": "13" + }, + "Jwt": { + "Audience": "JiShe.CollectBus", + "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=", + "Issuer": "JiShe.CollectBus", + "ExpirationTime": 2 + }, + "HealthChecks": { + "IsEnable": true, + "HealthCheckDatabaseName": "HealthChecks", + "EvaluationTimeInSeconds": 10, + "MinimumSecondsBetweenFailureNotifications": 60 + }, + "SwaggerConfig": [ + { + "GroupName": "Basic", + "Title": "【后台管理】基础模块", + "Version": "V1" + }, + { + "GroupName": "Business", + "Title": "【后台管理】业务模块", + "Version": "V1" + } + ], + "Kafka": { + "BootstrapServers": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092", + "EnableFilter": true, + "EnableAuthorization": false, + "SecurityProtocol": "SaslPlaintext", + "SaslMechanism": "Plain", + "SaslUserName": "lixiao", + "SaslPassword": "lixiao1980", + "KafkaReplicationFactor": 3, + "NumPartitions": 30, + "FirstCollectionTime": "2025-04-22 16:07:00" + }, + "IoTDBOptions": { + "UserName": "root", + "Password": "root", + "ClusterList": [ "192.168.5.9:6667" ], + "PoolSize": 32, + "DataBaseName": "energy", + "OpenDebugMode": false, + "UseTableSessionPoolByDefault": false + }, + "Cassandra": { + "ReplicationStrategy": { + "Class": "NetworkTopologyStrategy", //策略为NetworkTopologyStrategy时才会有多个数据中心,SimpleStrategy用在只有一个数据中心的情况下 + "DataCenters": [ + { + "Name": "dc1", + "ReplicationFactor": 3 + } + ] + }, + "Nodes": [ + { + "Host": "192.168.5.9", + "Port": 9042, + "DataCenter": "dc1", + "Rack": "RAC1" + }, + { + "Host": "192.168.5.9", + "Port": 9043, + "DataCenter": "dc1", + "Rack": "RAC2" + }, + { + "Host": "192.168.5.9", + "Port": 9044, + "DataCenter": "dc1", + "Rack": "RAC2" + } + ], + "Username": "admin", + "Password": "lixiao1980", + "Keyspace": "jishecollectbus", + "ConsistencyLevel": "Quorum", + "PoolingOptions": { + "CoreConnectionsPerHost": 4, + "MaxConnectionsPerHost": 8, + "MaxRequestsPerConnection": 2000 + }, + "SocketOptions": { + "ConnectTimeoutMillis": 10000, + "ReadTimeoutMillis": 20000 + }, + "QueryOptions": { + "ConsistencyLevel": "Quorum", + "SerialConsistencyLevel": "Serial", + "DefaultIdempotence": true + } + }, + "ServerApplicationOptions": { + "ServerTagName": "JiSheCollectBus8", + "SystemType": "Energy", + "FirstCollectionTime": "2025-04-28 15:07:00", + "AutomaticVerificationTime": "16:07:00", + "AutomaticTerminalVersionTime": "17:07:00", + "AutomaticTelematicsModuleTime": "17:30:00", + "AutomaticDayFreezeTime": "02:30:00", + "AutomaticMonthFreezeTime": "03:30:00", + "DefaultProtocolPlugin": "T37612012ProtocolPlugin" + }, + "PlugInFolder": "", + "TCP": { + "ClientPort": 10500 + } +} \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/images/cap.png b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/cap.png new file mode 100644 index 0000000..76c667e Binary files /dev/null and b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/cap.png differ diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/images/hangfire.png b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/hangfire.png new file mode 100644 index 0000000..5cdeb40 Binary files /dev/null and b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/hangfire.png differ diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/images/miniprofiler.png b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/miniprofiler.png new file mode 100644 index 0000000..244c702 Binary files /dev/null and b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/miniprofiler.png differ diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/images/more.png b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/more.png new file mode 100644 index 0000000..55c056f Binary files /dev/null and b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/more.png differ diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/images/swagger.png b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/swagger.png new file mode 100644 index 0000000..7bcbd43 Binary files /dev/null and b/web/JiShe.CollectBus.Migration.Host/wwwroot/images/swagger.png differ diff --git a/web/JiShe.CollectBus.Migration.Host/wwwroot/libs/bootstrap/css/bootstrap.min.css b/web/JiShe.CollectBus.Migration.Host/wwwroot/libs/bootstrap/css/bootstrap.min.css new file mode 100644 index 0000000..ed3905e --- /dev/null +++ b/web/JiShe.CollectBus.Migration.Host/wwwroot/libs/bootstrap/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.HttpApi/CollectBusController.cs b/web/JiShe.CollectBus.Migration.HttpApi/CollectBusController.cs new file mode 100644 index 0000000..fb10997 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.HttpApi/CollectBusController.cs @@ -0,0 +1,12 @@ +using JiShe.CollectBus.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace JiShe.CollectBus.Migration; + +public abstract class CollectBusController : AbpControllerBase +{ + protected CollectBusController() + { + LocalizationResource = typeof(CollectBusResource); + } +} diff --git a/web/JiShe.CollectBus.Migration.HttpApi/CollectBusMigrationHttpApiModule.cs b/web/JiShe.CollectBus.Migration.HttpApi/CollectBusMigrationHttpApiModule.cs new file mode 100644 index 0000000..c02a3a9 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.HttpApi/CollectBusMigrationHttpApiModule.cs @@ -0,0 +1,40 @@ +using Localization.Resources.AbpUi; +using JiShe.CollectBus.Localization; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; + +namespace JiShe.CollectBus.Migration; + +[DependsOn( + typeof(CollectBusMigrationApplicationModule), + typeof(CollectBusMigrationApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule) + )] +public class CollectBusMigrationHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(CollectBusMigrationHttpApiModule).Assembly); + }); + + Configure(options => + { + options.ConventionalControllers + .Create(typeof(CollectBusMigrationApplicationModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + } +} diff --git a/web/JiShe.CollectBus.Migration.HttpApi/FodyWeavers.xml b/web/JiShe.CollectBus.Migration.HttpApi/FodyWeavers.xml new file mode 100644 index 0000000..1715698 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/web/JiShe.CollectBus.Migration.HttpApi/JiShe.CollectBus.Migration.HttpApi.csproj b/web/JiShe.CollectBus.Migration.HttpApi/JiShe.CollectBus.Migration.HttpApi.csproj new file mode 100644 index 0000000..5047d92 --- /dev/null +++ b/web/JiShe.CollectBus.Migration.HttpApi/JiShe.CollectBus.Migration.HttpApi.csproj @@ -0,0 +1,30 @@ + + + + + + net8.0 + enable + JiShe.CollectBus + True + + + + + + + + + + + + + + + + + + + + +