diff --git a/JiShe.CollectBus.sln b/JiShe.CollectBus.sln index 6bc2bee..3252e73 100644 --- a/JiShe.CollectBus.sln +++ b/JiShe.CollectBus.sln @@ -19,10 +19,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.Host", "we EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.Common", "shared\JiShe.CollectBus.Common\JiShe.CollectBus.Common.csproj", "{AD2F1928-4411-4511-B564-5FB996EC08B9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.Protocol", "protocols\JiShe.CollectBus.Protocol\JiShe.CollectBus.Protocol.csproj", "{C62EFF95-5C32-435F-BD78-6977E828F894}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.Protocol.Contracts", "protocols\JiShe.CollectBus.Protocol.Contracts\JiShe.CollectBus.Protocol.Contracts.csproj", "{38C1808B-009A-418B-B17B-AB3626341B5D}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.DbMigrator", "services\JiShe.CollectBus.DbMigrator\JiShe.CollectBus.DbMigrator.csproj", "{8BA01C3D-297D-42DF-BD63-EF07202A0A67}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.FreeSql", "modules\JiShe.CollectBus.FreeSql\JiShe.CollectBus.FreeSql.csproj", "{FE0457D9-4038-4A17-8808-DCAD06CFC0A0}" @@ -51,7 +47,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Kafka.Test EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.External", "6.External", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.PluginFileWatcher", "external\JiShe.CollectBus.PluginFileWatcher\JiShe.CollectBus.PluginFileWatcher.csproj", "{F767D1C3-6807-4AE3-996A-3A28FE8124C2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol.T1882018", "protocols\JiShe.CollectBus.Protocol.T1882018\JiShe.CollectBus.Protocol.T1882018.csproj", "{430D298B-377E-49B8-83AA-ADC7C0EBDB0F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol.T37612012", "protocols\JiShe.CollectBus.Protocol.T37612012\JiShe.CollectBus.Protocol.T37612012.csproj", "{8A61DF78-069B-40B5-8811-614E2960443E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol", "protocols\JiShe.CollectBus.Protocol\JiShe.CollectBus.Protocol.csproj", "{E27377CC-E2D3-4237-060F-96EA214D3129}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol.T6452007", "protocols\JiShe.CollectBus.Protocol.T6452007\JiShe.CollectBus.Protocol.T6452007.csproj", "{75B7D419-C261-577D-58D6-AA3ACED9129F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.PluginFileWatcher", "external\JiShe.CollectBus.PluginFileWatcher\JiShe.CollectBus.PluginFileWatcher.csproj", "{0F67A493-A4DF-550E-AB4D-95F55144C706}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -91,14 +95,6 @@ Global {AD2F1928-4411-4511-B564-5FB996EC08B9}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD2F1928-4411-4511-B564-5FB996EC08B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {AD2F1928-4411-4511-B564-5FB996EC08B9}.Release|Any CPU.Build.0 = Release|Any CPU - {C62EFF95-5C32-435F-BD78-6977E828F894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C62EFF95-5C32-435F-BD78-6977E828F894}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C62EFF95-5C32-435F-BD78-6977E828F894}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C62EFF95-5C32-435F-BD78-6977E828F894}.Release|Any CPU.Build.0 = Release|Any CPU - {38C1808B-009A-418B-B17B-AB3626341B5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {38C1808B-009A-418B-B17B-AB3626341B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {38C1808B-009A-418B-B17B-AB3626341B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {38C1808B-009A-418B-B17B-AB3626341B5D}.Release|Any CPU.Build.0 = Release|Any CPU {8BA01C3D-297D-42DF-BD63-EF07202A0A67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8BA01C3D-297D-42DF-BD63-EF07202A0A67}.Debug|Any CPU.Build.0 = Debug|Any CPU {8BA01C3D-297D-42DF-BD63-EF07202A0A67}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -131,10 +127,26 @@ Global {6D6A2A58-7406-9C8C-7B23-3E442CCE3E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D6A2A58-7406-9C8C-7B23-3E442CCE3E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D6A2A58-7406-9C8C-7B23-3E442CCE3E6B}.Release|Any CPU.Build.0 = Release|Any CPU - {F767D1C3-6807-4AE3-996A-3A28FE8124C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F767D1C3-6807-4AE3-996A-3A28FE8124C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F767D1C3-6807-4AE3-996A-3A28FE8124C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F767D1C3-6807-4AE3-996A-3A28FE8124C2}.Release|Any CPU.Build.0 = Release|Any CPU + {430D298B-377E-49B8-83AA-ADC7C0EBDB0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {430D298B-377E-49B8-83AA-ADC7C0EBDB0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {430D298B-377E-49B8-83AA-ADC7C0EBDB0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {430D298B-377E-49B8-83AA-ADC7C0EBDB0F}.Release|Any CPU.Build.0 = Release|Any CPU + {8A61DF78-069B-40B5-8811-614E2960443E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A61DF78-069B-40B5-8811-614E2960443E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A61DF78-069B-40B5-8811-614E2960443E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A61DF78-069B-40B5-8811-614E2960443E}.Release|Any CPU.Build.0 = Release|Any CPU + {E27377CC-E2D3-4237-060F-96EA214D3129}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E27377CC-E2D3-4237-060F-96EA214D3129}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E27377CC-E2D3-4237-060F-96EA214D3129}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E27377CC-E2D3-4237-060F-96EA214D3129}.Release|Any CPU.Build.0 = Release|Any CPU + {75B7D419-C261-577D-58D6-AA3ACED9129F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75B7D419-C261-577D-58D6-AA3ACED9129F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75B7D419-C261-577D-58D6-AA3ACED9129F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75B7D419-C261-577D-58D6-AA3ACED9129F}.Release|Any CPU.Build.0 = Release|Any CPU + {0F67A493-A4DF-550E-AB4D-95F55144C706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F67A493-A4DF-550E-AB4D-95F55144C706}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F67A493-A4DF-550E-AB4D-95F55144C706}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F67A493-A4DF-550E-AB4D-95F55144C706}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -148,8 +160,6 @@ Global {077AA5F8-8B61-420C-A6B5-0150A66FDB34} = {A02F7D8A-04DC-44D6-94D4-3F65712D6B94} {35829A15-4127-4F69-8BDE-9405DEAACA9A} = {A02F7D8A-04DC-44D6-94D4-3F65712D6B94} {AD2F1928-4411-4511-B564-5FB996EC08B9} = {EBF7C01F-9B4F-48E6-8418-2CBFDA51EB0B} - {C62EFF95-5C32-435F-BD78-6977E828F894} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} - {38C1808B-009A-418B-B17B-AB3626341B5D} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} {8BA01C3D-297D-42DF-BD63-EF07202A0A67} = {BA4DA3E7-9AD0-47AD-A0E6-A0BB6700DA23} {FE0457D9-4038-4A17-8808-DCAD06CFC0A0} = {2E0FE301-34C3-4561-9CAE-C7A9E65AEE59} {C06C4082-638F-2996-5FED-7784475766C1} = {2E0FE301-34C3-4561-9CAE-C7A9E65AEE59} @@ -158,7 +168,11 @@ Global {A377955E-7EA1-6F29-8CF7-774569E93925} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} {443B4549-0AC0-4493-8F3E-49C83225DD76} = {2E0FE301-34C3-4561-9CAE-C7A9E65AEE59} {6D6A2A58-7406-9C8C-7B23-3E442CCE3E6B} = {2E0FE301-34C3-4561-9CAE-C7A9E65AEE59} - {F767D1C3-6807-4AE3-996A-3A28FE8124C2} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} + {430D298B-377E-49B8-83AA-ADC7C0EBDB0F} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} + {8A61DF78-069B-40B5-8811-614E2960443E} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} + {E27377CC-E2D3-4237-060F-96EA214D3129} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} + {75B7D419-C261-577D-58D6-AA3ACED9129F} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC} + {0F67A493-A4DF-550E-AB4D-95F55144C706} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} diff --git a/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs b/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs index d4a62db..7f8c31c 100644 --- a/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs +++ b/modules/JiShe.CollectBus.Kafka/Consumer/ConsumerService.cs @@ -1,4 +1,5 @@ using Confluent.Kafka; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Serialization; @@ -30,6 +31,8 @@ namespace JiShe.CollectBus.Kafka.Consumer private readonly KafkaOptionConfig _kafkaOptionConfig; + private readonly ServerApplicationOptions _applicationOptions; + private readonly KafkaPollyPipeline _kafkaPollyPipeline; /// @@ -37,10 +40,11 @@ namespace JiShe.CollectBus.Kafka.Consumer /// /// /// - public ConsumerService(ILogger logger, IOptions kafkaOptionConfig, KafkaPollyPipeline kafkaPollyPipeline) + public ConsumerService(ILogger logger, IOptions kafkaOptionConfig, KafkaPollyPipeline kafkaPollyPipeline, IOptions applicationOptions) { _logger = logger; _kafkaOptionConfig = kafkaOptionConfig.Value; + _applicationOptions = applicationOptions.Value; _kafkaPollyPipeline = kafkaPollyPipeline; } @@ -67,7 +71,7 @@ namespace JiShe.CollectBus.Kafka.Consumer var config = new ConsumerConfig { BootstrapServers = _kafkaOptionConfig.BootstrapServers, - GroupId = groupId ?? _kafkaOptionConfig.ServerTagName, + GroupId = groupId ?? _applicationOptions.ServerTagName, AutoOffsetReset = AutoOffsetReset.Earliest, EnableAutoCommit = false, // 禁止AutoCommit EnablePartitionEof = true, // 启用分区末尾标记 @@ -161,7 +165,7 @@ namespace JiShe.CollectBus.Kafka.Consumer } if (_kafkaOptionConfig.EnableFilter) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } }; + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; // 检查 Header 是否符合条件 if (!headersFilter.Match(result.Message.Headers)) { @@ -244,7 +248,7 @@ namespace JiShe.CollectBus.Kafka.Consumer } if (_kafkaOptionConfig.EnableFilter) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } }; + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; // 检查 Header 是否符合条件 if (!headersFilter.Match(result.Message.Headers)) { @@ -348,7 +352,7 @@ namespace JiShe.CollectBus.Kafka.Consumer { if (_kafkaOptionConfig.EnableFilter) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } }; + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; // 检查 Header 是否符合条件 if (!headersFilter.Match(result.Message.Headers)) { @@ -485,7 +489,7 @@ namespace JiShe.CollectBus.Kafka.Consumer { if (_kafkaOptionConfig.EnableFilter) { - var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } }; + var headersFilter = new HeadersFilter { { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } }; // 检查 Header 是否符合条件 if (!headersFilter.Match(result.Message.Headers)) { diff --git a/modules/JiShe.CollectBus.Kafka/Internal/KafkaOptionConfig.cs b/modules/JiShe.CollectBus.Kafka/Internal/KafkaOptionConfig.cs index 3bea5f1..38c9482 100644 --- a/modules/JiShe.CollectBus.Kafka/Internal/KafkaOptionConfig.cs +++ b/modules/JiShe.CollectBus.Kafka/Internal/KafkaOptionConfig.cs @@ -8,12 +8,7 @@ public class KafkaOptionConfig /// kafka地址 /// public string BootstrapServers { get; set; } = null!; - - /// - /// 服务器标识 - /// - public string ServerTagName { get; set; } = "KafkaFilterKey"; - + /// /// kafka主题副本数量 /// @@ -54,8 +49,4 @@ public class KafkaOptionConfig /// public string? SaslPassword { get; set; } - /// - /// 首次采集时间 - /// - public DateTime? FirstCollectionTime { get; set; } } \ No newline at end of file diff --git a/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs b/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs index 16499b5..50df423 100644 --- a/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs +++ b/modules/JiShe.CollectBus.Kafka/Producer/ProducerService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Confluent.Kafka; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Kafka.Consumer; using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Serialization; @@ -23,18 +24,19 @@ namespace JiShe.CollectBus.Kafka.Producer private readonly ConcurrentDictionary _producerCache = new(); private class KafkaProducer where TKey : notnull where TValue : class { } private readonly KafkaOptionConfig _kafkaOptionConfig; - + private readonly ServerApplicationOptions _applicationOptions; /// /// ProducerService /// /// /// /// - public ProducerService(IConfiguration configuration,ILogger logger, IOptions kafkaOptionConfig) + public ProducerService(IConfiguration configuration,ILogger logger, IOptions kafkaOptionConfig, IOptions applicationOptions) { _configuration = configuration; _logger = logger; _kafkaOptionConfig = kafkaOptionConfig.Value; + _applicationOptions = applicationOptions.Value; } #region private 私有方法 @@ -119,7 +121,7 @@ namespace JiShe.CollectBus.Kafka.Producer Key = key, Value = value, Headers = new Headers{ - { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } + { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } }; await producer.ProduceAsync(topic, message); @@ -141,7 +143,7 @@ namespace JiShe.CollectBus.Kafka.Producer //Key= _kafkaOptionConfig.ServerTagName, Value = value, Headers = new Headers{ - { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } + { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } }; await producer.ProduceAsync(topic, message); @@ -165,7 +167,7 @@ namespace JiShe.CollectBus.Kafka.Producer Key = key, Value = value, Headers = new Headers{ - { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } + { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } }; var typeKey = typeof(KafkaProducer); @@ -200,7 +202,7 @@ namespace JiShe.CollectBus.Kafka.Producer //Key = _kafkaOptionConfig.ServerTagName, Value = value, Headers = new Headers{ - { "route-key", Encoding.UTF8.GetBytes(_kafkaOptionConfig.ServerTagName) } + { "route-key", Encoding.UTF8.GetBytes(_applicationOptions.ServerTagName) } } }; var typeKey = typeof(KafkaProducer); diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/ProtocolPlugin.cs deleted file mode 100644 index 6b63538..0000000 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/ProtocolPlugin.cs +++ /dev/null @@ -1,388 +0,0 @@ -using System; -using System.Reflection; -using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.FreeRedis; -using JiShe.CollectBus.IotSystems.Protocols; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using TouchSocket.Sockets; -using Volo.Abp.Domain.Repositories; - -namespace JiShe.CollectBus.Protocol.Contracts.Abstracts -{ - public abstract class ProtocolPlugin:IProtocolPlugin - { - //头部字节长度 - public const int hearderLen = 6; - - public const int tPLen = 6; - - public const string errorData = "EE"; - - private readonly ILogger _logger; - private readonly IRepository _protocolInfoRepository; - private readonly IFreeRedisProvider _redisProvider; - - public ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger) - { - _logger = logger; - _protocolInfoRepository = serviceProvider.GetRequiredService>(); - _redisProvider = serviceProvider.GetRequiredService(); - } - - - public abstract ProtocolInfo Info { get; } - - public virtual async Task GetAsync() => await Task.FromResult(Info); - - public virtual async Task LoadAsync() - { - if (Info == null) - { - throw new ArgumentNullException(nameof(Info)); - } - - await _protocolInfoRepository.DeleteDirectAsync(a => a.Name == Info.Name); - await _protocolInfoRepository.InsertAsync(Info); - await _redisProvider.Instance.HDelAsync($"{RedisConst.ProtocolKey}", Info.Name); - await _redisProvider.Instance.HSetAsync($"{RedisConst.ProtocolKey}", Info.Name, Info); - } - - public abstract Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? receivedAction = null) where T :class; - - - /// - /// 解析376.1帧 - /// - /// - /// - public virtual TB3761? Analysis3761(string messageReceived) - { - try - { - var hexStringList = messageReceived.StringToPairs(); - // 初步校验 - if (hexStringList.Count < 6 || hexStringList.FirstOrDefault() != "68" || hexStringList.Skip(5).Take(1).FirstOrDefault() != "68" || hexStringList.Count < 18 || hexStringList.LastOrDefault() != "16") - { - _logger.LogError($"解析Analysis3761校验不通过,报文:{messageReceived}"); - } - else - { - TB3761 tB3761 = new TB3761 - { - BaseHexMessage = new BaseHexMessage - { - HexMessageString = messageReceived, - HexMessageList = hexStringList - }, - C = Analysis_C(hexStringList), - A = Analysis_A(hexStringList), - AFN_FC = Analysis_AFN_FC(hexStringList), - SEQ = Analysis_SEQ(hexStringList), - UnitData = Analysis_UnitData(hexStringList), - DA = Analysis_DA(hexStringList), - DT = Analysis_DT(hexStringList) - }; - return tB3761; - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis3761错误,报文:{messageReceived},异常:{ex.Message}"); - } - return null; - } - - /// - /// 控制域C解析 - /// - /// - public virtual C Analysis_C(List hexStringList) - { - C c = new C(); - try - { - if (hexStringList.Count > 6) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(6, 1) // 控制域 1字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - if (baseHexMessage.HexMessageList.Count == 0) - return null; - string binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); - c = new C - { - BaseHexMessage = baseHexMessage, - FC = binStr.Substring(binStr.Length - 4, 4).BinToDec(), - FCV = binStr.Substring(3, 1).BinToDec(), - FCB = binStr.Substring(2, 1).BinToDec(), - PRM = binStr.Substring(1, 1).BinToDec(), - DIR = binStr.Substring(0, 1).BinToDec() - }; - return c; - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_C错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - - return c; - } - - /// - /// 地址域A解析 - /// - /// - /// - public virtual A Analysis_A(List hexStringList) - { - A a = new A(); - try - { - if (hexStringList.Count > 7) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(7, 5) // 地址域 5个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - a = new A - { - BaseHexMessage = baseHexMessage, - A1 = baseHexMessage.HexMessageList.ListReverseToStr(0, 2),//.DataConvert(10);//行政区划码A1 - A2 = baseHexMessage.HexMessageList.ListReverseToStr(2, 2).PadLeft(5, '0').HexToDec(),//终端地址A2 - A3 = Analysis_A3(baseHexMessage.HexMessageList) //主站地址和组地址标志A3 - }; - a.Code = $"{a.A1.PadLeft(4, '0')}{a.A2.ToString()!.PadLeft(5, '0')}"; - - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_A错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - - return a; - - } - - /// - /// 站地址和组地址标志A3 - /// - /// 地址域A集合 - /// - public virtual A3 Analysis_A3(List hexAList) - { - A3 a3 = new A3(); - try - { - if (hexAList.Count != 0) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexAList.GetRange(4, 1) // 站地址和组地址标志A3 1个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); - a3 = new A3 - { - BaseHexMessage = baseHexMessage, - D0 = binStr.Substring(binStr.Length - 1, 1).BinToDec(), - D1_D7 = binStr.Substring(0, binStr.Length - 1).BinToDec() - }; - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_A3错误,报文:{string.Join("", hexAList)},异常:{ex.Message}"); - } - - return a3; - } - - /// - /// AFN_FC功能码 - /// - /// - public virtual AFN_FC Analysis_AFN_FC(List hexStringList) - { - AFN_FC aFN_FC = new AFN_FC(); - try - { - if (hexStringList.Count == 0) - { - - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(12, 1) //AFN功能码 1个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - - aFN_FC = new AFN_FC - { - BaseHexMessage = baseHexMessage, - AFN = baseHexMessage.HexMessageString.HexToDec(), - }; - } - - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_AFN_FC错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - - return aFN_FC; - } - - /// - /// 解析帧序列域SEQ - /// - /// - public virtual SEQ Analysis_SEQ(List hexStringList) - { - SEQ seq = new SEQ(); - try - { - if (hexStringList.Count != 0) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(13, 1) //帧序列域 SEQ 1个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); - seq = new SEQ - { - PSEQ = binStr.Substring(binStr.Length - 4, 4).BinToDec(), - CON = binStr.Substring(3, 1).BinToDec(), - FIN = binStr.Substring(2, 1).BinToDec(), - FIR = binStr.Substring(1, 1).BinToDec(), - TpV = binStr.Substring(0, 1).BinToDec() - }; - } - - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_SEQ错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - return seq; - } - - - /// - /// 数据单元标识及数据单元数据 - /// - public virtual UnitData Analysis_UnitData(List hexStringList) - { - UnitData unitData = new UnitData(); - try - { - if (hexStringList.Count != 0) - { - unitData = new UnitData - { - HexMessageList = hexStringList.GetRange(14, hexStringList.Count - 14 - 2) //总数字节数-固定长度报文头-控制域C-地址域A-校验和CS-结束字符(16H) - }; - unitData.HexMessageString = string.Join("", unitData.HexMessageList); - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_UnitData错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - return unitData; - } - - /// - /// 信息点DA Pn - /// - /// - public virtual DA Analysis_DA(List hexStringList) - { - DA da = new DA(); - try - { - if (hexStringList.Count != 0) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(14, 2) //信息点DA Pn 2个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - var da1 = baseHexMessage.HexMessageList[0]; - var da2 = baseHexMessage.HexMessageList[1]; - da = new DA() - { - BaseHexMessage = baseHexMessage, - Pn = CalculatePn(da1, da2) - }; - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_DA错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - return da; - } - - /// - /// 信息类DT Fn - /// - /// - public virtual DT Analysis_DT(List hexStringList) - { - DT dt = new DT(); - try - { - if (hexStringList.Count != 0) - { - BaseHexMessage baseHexMessage = new BaseHexMessage - { - HexMessageList = hexStringList.GetRange(16, 2) //信息类DT Fn 2个字节 - }; - baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); - var dt1 = baseHexMessage.HexMessageList[0]; - var dt2 = baseHexMessage.HexMessageList[1]; - dt = new DT() - { - BaseHexMessage = baseHexMessage, - Fn = CalculateFn(dt1, dt2) - }; - } - } - catch (Exception ex) - { - _logger.LogError($"解析Analysis_DT错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); - } - - return dt; - - } - - - /// - /// 计算Pn - /// - /// - /// - /// - public static int CalculatePn(string da1, string da2) => (da2.HexToDec() - 1) * 8 + (8 - da1.HexTo4BinZero().IndexOf(da1.Equals("00") ? "0" : "1")); - - - /// - /// 计算Fn - /// - /// - /// - /// - public static int CalculateFn(string dt1, string dt2) => dt2.HexToDec() * 8 + (8 - dt1.HexTo4BinZero().IndexOf("1")); - - } -} diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IAnalysisStrategy.cs b/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IAnalysisStrategy.cs deleted file mode 100644 index dcd12fb..0000000 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IAnalysisStrategy.cs +++ /dev/null @@ -1,15 +0,0 @@ -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Dto; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JiShe.CollectBus.Protocol.Contracts.Interfaces -{ - public interface IAnalysisStrategy - { - Task ExecuteAsync(TInput input); - } -} diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj b/protocols/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj deleted file mode 100644 index 495dbf1..0000000 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - - - - - - - - diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/CJT 188-2018 户用计量仪表数据传输技术条件.pdf b/protocols/JiShe.CollectBus.Protocol.T1882018/CJT 188-2018 户用计量仪表数据传输技术条件.pdf new file mode 100644 index 0000000..ce3fb6a Binary files /dev/null and b/protocols/JiShe.CollectBus.Protocol.T1882018/CJT 188-2018 户用计量仪表数据传输技术条件.pdf differ diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/JiShe.CollectBus.Protocol.T1882018.csproj b/protocols/JiShe.CollectBus.Protocol.T1882018/JiShe.CollectBus.Protocol.T1882018.csproj new file mode 100644 index 0000000..4866985 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/JiShe.CollectBus.Protocol.T1882018.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs new file mode 100644 index 0000000..4a5aec8 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs @@ -0,0 +1,31 @@ +using JiShe.CollectBus.Protocol.Contracts; +using JiShe.CollectBus.Protocol.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System.Reflection; +using Volo.Abp; +using Volo.Abp.Modularity; + +namespace JiShe.CollectBus.Protocol +{ + public class JiSheCollectBusProtocolT1882018Module : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddKeyedSingleton(nameof(T1882018ProtocolPlugin)); + } + + public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + Console.WriteLine($"{nameof(T1882018ProtocolPlugin)} OnApplicationInitializationAsync"); + var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(T1882018ProtocolPlugin)); + await standardProtocol.LoadAsync(); + } + + public override void OnApplicationShutdown(ApplicationShutdownContext context) + { + Console.WriteLine($"{nameof(T1882018ProtocolPlugin)} OnApplicationShutdown"); + base.OnApplicationShutdown(context); + } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs new file mode 100644 index 0000000..eaa9ca8 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs @@ -0,0 +1,79 @@ +using FreeSql; +using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Models; +using System.Reflection; + +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 构建188-2018下发报文 + /// + public static class Telemetry1882018PacketBuilder + { + /// + /// 构建报文的委托 + /// + /// + /// + public delegate Telemetry1882018PacketResponse T1882018Delegate(Telemetry1882018PacketRequest request); + + /// + /// 编码与方法的映射表 + /// + public static readonly Dictionary T1882018ControlHandlers = new(); + + static Telemetry1882018PacketBuilder() + { + // 初始化时自动注册所有符合命名规则的方法 + var methods = typeof(Telemetry1882018PacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public); + foreach (var method in methods) + { + if (method.Name.StartsWith("CTR") && method.Name.EndsWith("_Send")) + { + string code = method.Name; + var delegateInstance = (T1882018Delegate)Delegate.CreateDelegate(typeof(T1882018Delegate), method); + T1882018ControlHandlers[code] = delegateInstance; + } + } + } + + #region 读数据 + + /// + /// 读取计量数据 + /// + /// + /// + public static Telemetry1882018PacketResponse CTR_01_Send(Telemetry1882018PacketRequest request) + { + var itemCodeArr = request.ItemCode.Split('_'); + var c_data = itemCodeArr[0];//01 + var d_data = itemCodeArr[1];//91 或者 90 + var dataUnit = new List() { "1F", d_data, "00" }; + var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit); + + return new Telemetry1882018PacketResponse() { Data = dataList }; + } + #endregion + + #region 写数据 + /// + /// 阀控 + /// + /// + /// + public static Telemetry1882018PacketResponse CTR_04_Send(Telemetry1882018PacketRequest request) + { + var itemCodeArr = request.ItemCode.Split('_'); + var c_data = itemCodeArr[0];//01 + var d_data = itemCodeArr[1];//55 或者 99 + var dataUnit = new List() { "A0", "17", "00", d_data }; + var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit); + + return new Telemetry1882018PacketResponse() { Data = dataList }; + } + #endregion + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs new file mode 100644 index 0000000..ef51ea1 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs @@ -0,0 +1,23 @@ +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 构建645报文参数 + /// + public class Telemetry1882018PacketRequest + { + /// + /// 表地址 + /// + 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.T1882018/SendData/Telemetry1882018PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketResponse.cs new file mode 100644 index 0000000..90e6e62 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketResponse.cs @@ -0,0 +1,13 @@ +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 返回645报文结果 + /// + public class Telemetry1882018PacketResponse + { + /// + /// 报文体 + /// + public List Data { get; set; } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs new file mode 100644 index 0000000..de7b44a --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs @@ -0,0 +1,147 @@ +using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Helpers; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.Enums; +using JiShe.CollectBus.IotSystems.Devices; +using JiShe.CollectBus.IotSystems.MessageReceiveds; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Kafka.Producer; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol.SendData; +using Mapster; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using TouchSocket.Sockets; +using Volo.Abp.Domain.Repositories; + +namespace JiShe.CollectBus.Protocol +{ + /// + /// T1882018协议插件 + /// + public class T1882018ProtocolPlugin : T37612012ProtocolPlugin + { + private readonly ILogger _logger; + + public readonly Dictionary T188ControlHandlers; + + /// + /// Initializes a new instance of the class. + /// + /// The service provider. + public T1882018ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger, tcpService) + { + _logger = logger; + T188ControlHandlers = Telemetry1882018PacketBuilder.T1882018ControlHandlers; + } + + public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "376.1/188-2018", "TCP", "376.1/188-2018协议", "HJ-LXS-15 DN15"); + + public override async Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null) + { + //TB3761? tB3761 = Analysis3761(messageReceived); + //if (tB3761 != null) + //{ + // if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测) + // { + // if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null) + // { + // _logger.LogError($"解析AFN.链路接口检测报文失败,报文:{messageReceived},TB3761:{tB3761.Serialize()}"); + // } + // else + // { + // if (tB3761.DT?.Fn == (int)FN.登录) + // { + // // 登录回复 + // if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认) + // await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + // } + // else if (tB3761.DT?.Fn == (int)FN.心跳) + // { + // // 心跳回复 + // //心跳帧有两种情况: + // //1. 集中器先有登录帧,再有心跳帧 + // //2. 集中器没有登录帧,只有心跳帧 + // await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + // } + // } + + // } + // await OnTcpNormalReceived(client, tB3761); + //} + //return (tB3761 as T)!; + + return null; + } + + /// + /// 组装报文 + /// + /// 报文构建参数 + /// + public override async Task BuildAsync(ProtocolBuildRequest request) + { + if (request == null) + { + _logger.LogError($"{nameof(T1882018ProtocolPlugin)} 报文构建失败,参数为空"); + return new ProtocolBuildResponse(); + } + var itemCodeArr = request.ItemCode.Split('_'); + var aFNStr = itemCodeArr[0]; + var aFN = (AFN)aFNStr.HexToDec(); + var fn = int.Parse(itemCodeArr[1]); + + Telemetry3761PacketResponse builderResponse = null; + + List dataUnit = new List(); + //数据转发场景 10H_F1 + if (aFNStr == "10" && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false) + { + var t188PacketHandlerName = $"{T1882018PacketItemCodeConst.BasicT1882018}_{request.SubProtocolRequest.ItemCode}_Send"; + Telemetry1882018PacketResponse t645PacketResponse = null; + + if (T188ControlHandlers != null && T188ControlHandlers.TryGetValue(t188PacketHandlerName + , out var t645PacketHandler)) + { + t645PacketResponse = t645PacketHandler(new Telemetry1882018PacketRequest() + { + MeterAddress = request.SubProtocolRequest.MeterAddress, + Password = request.SubProtocolRequest.Password, + ItemCode = request.SubProtocolRequest.ItemCode, + }); + } + + if (t645PacketResponse != null) + { + dataUnit = t645PacketResponse.Data; + } + } + + string afnMethonCode = $"AFN{aFNStr}_Fn_Send"; + if (base.T3761AFNHandlers != null && base.T3761AFNHandlers.TryGetValue(afnMethonCode + , out var handler)) + { + builderResponse = handler(new Telemetry3761PacketRequest() + { + FocusAddress = request.FocusAddress, + Fn = fn, + Pn = request.Pn, + DataUnit = dataUnit, + }); + } + + if (builderResponse == null) + { + return new ProtocolBuildResponse(); + } + + var result = builderResponse.Adapt(); + result.IsSuccess = true; + + return await Task.FromResult(result); + } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs similarity index 61% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs index d1249b7..406beb9 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs @@ -1,15 +1,7 @@ -using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using Microsoft.IdentityModel.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_00H { @@ -32,16 +24,17 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_00H ArgumentNullException.ThrowIfNull(nameof(tB3761)); UnitDataAnalysis dto = new UnitDataAnalysis { - Code = tB3761.A?.Code, - AFN = tB3761.AFN_FC?.AFN ?? 0, - Fn = tB3761.DT?.Fn ?? 0, - Pn = tB3761.DA?.Pn ?? 0 + Code = tB3761.A.Code, + AFN = tB3761.AFN_FC.AFN, + Fn = tB3761.DT.Fn, + Pn = tB3761.DA.Pn, + Data= true }; return Task.FromResult(dto); } catch (Exception ex) { - _logger.LogError(ex, $"00_1解析失败:{tB3761.A?.Code}-{tB3761.DT?.Fn ?? 0}-{tB3761?.BaseHexMessage?.HexMessageString},{ex.Message}"); + _logger.LogError(ex, $"00_1解析失败:{tB3761.A.Code}-{tB3761.DT.Fn}-{tB3761.BaseHexMessage.HexMessageString},{ex.Message}"); return null; } } diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs similarity index 79% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs index 364542a..0871607 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs @@ -1,13 +1,7 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; -using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_00H { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs similarity index 89% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs index 2e76ae5..60ededf 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs @@ -1,18 +1,10 @@ -using DeviceDetectorNET.Class; -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.AnalysisData.AFN_00H; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; -using TouchSocket.Core; -using YamlDotNet.Core; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_09H { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs similarity index 83% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs index fefe177..ca64928 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs @@ -1,15 +1,9 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.AnalysisData.AFN_00H; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_09H { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs index 9f2e384..b410abe 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs @@ -1,16 +1,9 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.AnalysisData.AFN_09H; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0AH { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs similarity index 92% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs index ce2cf12..ced9573 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs @@ -1,10 +1,10 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.Contracts; using JiShe.CollectBus.Protocol.Contracts.Abstracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0AH @@ -71,8 +71,8 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0AH for (int i = 0; i < count; i++) { var pnfnArr = dataArr.GetRange(0, 4); - var tempPn = ProtocolPlugin.CalculatePn(pnfnArr[0], pnfnArr[1]); - var tempFn = ProtocolPlugin.CalculateFn(pnfnArr[2], pnfnArr[3]); + var tempPn = T37612012ProtocolPlugin.CalculatePn(pnfnArr[0], pnfnArr[1]); + var tempFn = T37612012ProtocolPlugin.CalculateFn(pnfnArr[2], pnfnArr[3]); entity.Details.Add(new SetAutoItemCodeDetails() { Fn = tempFn, Pn = tempPn }); dataArr.RemoveRange(0, 4); } diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs similarity index 81% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs index 8b32e24..f87aaf3 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs @@ -1,13 +1,7 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; -using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0AH { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs similarity index 70% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs index e857bcd..2568aab 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs @@ -1,10 +1,15 @@ -using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Encrypt; +using JiShe.CollectBus.Common.Helpers; +using JiShe.CollectBus.IoTDB.Interface; +using JiShe.CollectBus.IoTDB.Options; +using JiShe.CollectBus.IoTDB.Provider; +using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH @@ -16,11 +21,13 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH { private readonly ILogger _logger; private readonly AnalysisStrategyContext _analysisStrategyContext; + private readonly IIoTDbProvider _dbProvider; - public AFN12_F129_Analysis(ILogger logger, AnalysisStrategyContext analysisStrategyContext) + public AFN12_F129_Analysis(ILogger logger, AnalysisStrategyContext analysisStrategyContext, IIoTDbProvider dbProvider) { _logger = logger; _analysisStrategyContext = analysisStrategyContext; + _dbProvider= dbProvider; } public async Task>> ExecuteAsync(TB3761 input) @@ -29,16 +36,34 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH { ArgumentNullException.ThrowIfNull(input); ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList); - List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); - List list = GenerateFinalResult(2, datas, "正向有功电能示值", input.AFN_FC.AFN, input.DT.Fn); + ArgumentNullException.ThrowIfNull(input.A.A3?.D1_D7); UnitDataAnalysis> unitDataAnalysis = new UnitDataAnalysis> { - Code = input.A.Code, + Code = input.A.Code!, AFN = input.AFN_FC.AFN, Fn = input.DT.Fn, Pn = input.DA.Pn, - Data = list + MSA= input.A.A3.D1_D7, + PSEQ= input.SEQ.PSEQ, }; + string taskMark = CommonHelper.GetTaskMark(unitDataAnalysis.AFN, unitDataAnalysis.Fn, unitDataAnalysis.Pn, unitDataAnalysis.MSA, unitDataAnalysis.PSEQ); + string scoreValue = $"{unitDataAnalysis.Code}.{taskMark}".Md5Fun(); + + var conditions = new List(); + conditions.Add(new QueryCondition() + { + Field = "ScoreValue", + Operator = "=", + IsNumber = false, + Value = scoreValue + }); + var taskSendInfo = await _dbProvider.QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions,PageIndex=0,PageSize=1}); + + + + List datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList); + List list = GenerateFinalResult(2, datas, "正向有功电能示值", input.AFN_FC.AFN, input.DT.Fn); + unitDataAnalysis.Data= list; return await Task.FromResult(unitDataAnalysis); } @@ -98,6 +123,13 @@ namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH return list; } - + ///// + ///// 生成最终结果 + ///// + ///// + //public Task SaveIotDbAsync() + //{ + + //} } } diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs index 0afadc6..a7c65a9 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs @@ -1,9 +1,9 @@ using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs index c52e7e3..977b8f0 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs @@ -1,9 +1,9 @@ using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs index 85c3f88..c6a0fc7 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs @@ -1,9 +1,9 @@ using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs index 6a3d126..a718674 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs @@ -1,10 +1,10 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs similarity index 96% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs index 986d52b..a79ed99 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs @@ -1,13 +1,11 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs similarity index 96% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs index 45f455d..2d2b0c8 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs @@ -1,9 +1,9 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs index f3fd66b..94b1085 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs @@ -1,17 +1,11 @@ -using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; -using YamlDotNet.Core.Tokens; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs similarity index 96% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs index bd034c6..f636e92 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs @@ -1,10 +1,10 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs similarity index 96% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs index 12d49fc..054c2c2 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs @@ -1,12 +1,10 @@ -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.AnalysisData.Appendix; +using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH { diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs index 14b46ad..e6e42ec 100644 --- a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs @@ -1,10 +1,10 @@ using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Protocol.AnalysisData.Appendix; using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.AFN_0CH diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs new file mode 100644 index 0000000..574a207 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData +{ + public class DataStorage:ITransientDependency + { + public DataStorage() + { + + } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_02800002.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs similarity index 79% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_02800002.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs index c197e04..1c6372b 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_02800002.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_02800002.cs @@ -1,10 +1,5 @@ -using JiShe.CollectBus.Protocol.AnalysisData.AFN_09H; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000201.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000201.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000201.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000201.cs index 9cc7b92..c56d7fc 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000201.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000201.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000202.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000202.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000202.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000202.cs index 2fbe5d5..465d461 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000202.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000202.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000203.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000203.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000203.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000203.cs index e3d2248..f35f34f 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000203.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000203.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000204.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000204.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000204.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000204.cs index 99ba631..ee012f0 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000204.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04000204.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010000.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010000.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010000.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010000.cs index 69e7a5c..cbbb021 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010000.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010000.cs @@ -1,4 +1,4 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010001.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010001.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010001.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010001.cs index c6aa07f..4e3ecd4 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010001.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010001.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010002.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010002.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010002.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010002.cs index f7ac153..31a5f45 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010002.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010002.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010003.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010003.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010003.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010003.cs index 39c32f6..d4588d7 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010003.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010003.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010004.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010004.cs similarity index 80% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010004.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010004.cs index fa5958c..f16bf26 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010004.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010004.cs @@ -1,8 +1,5 @@ -using JiShe.CollectBus.Protocol.AnalysisData.AFN_09H; -using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Contracts; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010005.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010005.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010005.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010005.cs index 0905d45..ebeb20e 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010005.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010005.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010006.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010006.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010006.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010006.cs index f97be46..6660605 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010006.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010006.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010007.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010007.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010007.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010007.cs index 7546af9..50220f9 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010007.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010007.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010008.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010008.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010008.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010008.cs index 2ca689c..c6da235 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010008.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_04010008.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A1.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A1.cs similarity index 91% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A1.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A1.cs index cd17247..22127e3 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A1.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A1.cs @@ -1,6 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A11.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A11.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A11.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A11.cs index 9989bf4..16655ec 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A11.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A11.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A13.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A13.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A13.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A13.cs index ca45b2b..47d8413 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A13.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A13.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A14.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A14.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A14.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A14.cs index d4179c6..4ffb948 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A14.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A14.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A15.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A15.cs similarity index 86% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A15.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A15.cs index c2c3859..c8049cd 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A15.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A15.cs @@ -1,5 +1,4 @@ -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A17.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A17.cs similarity index 73% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A17.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A17.cs index 2753afd..e2b40e6 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A17.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A17.cs @@ -1,6 +1,4 @@ -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using Microsoft.Extensions.Logging; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A23.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A23.cs similarity index 97% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A23.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A23.cs index a8415e4..f63bb10 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A23.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A23.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A25.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A25.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A25.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A25.cs index 4401502..38b39ae 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A25.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A25.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A5.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A5.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A5.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A5.cs index daebff2..05847d1 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A5.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A5.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A7.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A7.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A7.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A7.cs index a305fa2..9e7a8ad 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A7.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A7.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A9.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A9.cs similarity index 95% rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A9.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A9.cs index f290932..9f99a80 100644 --- a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A9.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Appendix/Appendix_A9.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; namespace JiShe.CollectBus.Protocol.AnalysisData.Appendix { diff --git a/protocols/JiShe.CollectBus.Protocol/JiSheCollectBusProtocolModule.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs similarity index 74% rename from protocols/JiShe.CollectBus.Protocol/JiSheCollectBusProtocolModule.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs index dab94d8..f3e24f7 100644 --- a/protocols/JiShe.CollectBus.Protocol/JiSheCollectBusProtocolModule.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs @@ -1,40 +1,31 @@ -using JiShe.CollectBus.Kafka.Internal; -using JiShe.CollectBus.Protocol.AnalysisData; -using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Abstracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Dto; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; -using Serilog.Core; -using System; using System.Reflection; using Volo.Abp; using Volo.Abp.Modularity; -namespace JiShe.CollectBus.Protocol +namespace JiShe.CollectBus.Protocol.Contracts { - public class JiSheCollectBusProtocolModule : AbpModule + public class CollectBusProtocolT37612012Module : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.AddKeyedSingleton(nameof(StandardProtocolPlugin)); + context.Services.AddKeyedSingleton(nameof(T37612012ProtocolPlugin)); //RegisterProtocolAnalysis(context.Services); LoadAnalysisStrategy(context.Services); } public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { - Console.WriteLine("StandardProtocolPlugin OnApplicationInitializationAsync"); - var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(StandardProtocolPlugin)); + Console.WriteLine($"{nameof(T37612012ProtocolPlugin)} OnApplicationInitializationAsync"); + var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(T37612012ProtocolPlugin)); await standardProtocol.LoadAsync(); } public override void OnApplicationShutdown(ApplicationShutdownContext context) { - Console.WriteLine("StandardProtocolPlugin OnApplicationShutdown"); + Console.WriteLine($"{nameof(T37612012ProtocolPlugin)} OnApplicationShutdown"); base.OnApplicationShutdown(context); } @@ -45,7 +36,7 @@ namespace JiShe.CollectBus.Protocol foreach (var analysisStrategyType in analysisStrategyTypes) { var service = analysisStrategyType.GetInterfaces().First(); - services.AddKeyedSingleton(service, analysisStrategyType.Name,analysisStrategyType); + services.AddKeyedSingleton(service, analysisStrategyType.Name, analysisStrategyType); } } @@ -61,7 +52,7 @@ namespace JiShe.CollectBus.Protocol { return; } - var dllFiles = Directory.GetFiles(Path.Combine(assemblyPath, "Plugins") , "*.dll"); + var dllFiles = Directory.GetFiles(Path.Combine(assemblyPath, "Plugins"), "*.dll"); foreach (var file in dllFiles) { // 跳过已加载的程序集 @@ -70,21 +61,19 @@ namespace JiShe.CollectBus.Protocol .FirstOrDefault(a => a.GetName().FullName == assemblyName.FullName); var assembly = existingAssembly ?? Assembly.LoadFrom(file); // 实现IAnalysisStrategy接口 - var analysisStrategyTypes = assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAnalysisStrategy<,>))); + var analysisStrategyTypes = assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAnalysisStrategy<,>))); if (!analysisStrategyTypes.Any()) continue; foreach (var analysisStrategyType in analysisStrategyTypes) { // 通过反射获取静态元数据 var strategyType = analysisStrategyType.Name; - var genericArgs = analysisStrategyType.GetInterface($"IAnalysisStrategy`2")!.GetGenericArguments(); + var genericArgs = analysisStrategyType.GetInterface($"IAnalysisStrategy`2")!.GetGenericArguments(); var inputType = genericArgs[0]; var resultType = genericArgs[1]; // 注册策略实现 services.AddTransient(analysisStrategyType); strategyMetadata[(strategyType, inputType, resultType)] = analysisStrategyType; - - } } @@ -101,7 +90,7 @@ namespace JiShe.CollectBus.Protocol } else { - var logger= provider.GetRequiredService>(); + var logger = provider.GetRequiredService>(); logger.LogWarning($"未能找到解析策略:{name}-{inputType}-{resultType}"); return null; } @@ -111,3 +100,6 @@ namespace JiShe.CollectBus.Protocol } } } + + + diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/JiShe.CollectBus.Protocol.T37612012.csproj b/protocols/JiShe.CollectBus.Protocol.T37612012/JiShe.CollectBus.Protocol.T37612012.csproj new file mode 100644 index 0000000..e83c165 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/JiShe.CollectBus.Protocol.T37612012.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol3761Extensions.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol3761Extensions.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol/Protocol3761Extensions.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol3761Extensions.cs diff --git a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs similarity index 73% rename from shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketBuilder.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs index 5db0dd7..1aa2a22 100644 --- a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketBuilder.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs @@ -1,51 +1,42 @@ -using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Models; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; -using System.Net; using System.Reflection; -using System.Text; -using System.Threading.Tasks; -namespace JiShe.CollectBus.Common.BuildSendDatas +namespace JiShe.CollectBus.Protocol.Contracts.SendData { /// - /// 构建下发报文,只适用与定时抄读 + /// 构建3761下发报文 /// - public static class TelemetryPacketBuilder + public static class Telemetry3761PacketBuilder { /// /// 构建报文的委托 - /// - /// - /// - /// - public delegate TelemetryPacketResponse AFNDelegate(TelemetryPacketRequest request); + /// + public delegate Telemetry3761PacketResponse T3761Delegate(Telemetry3761PacketRequest request); /// /// 编码与方法的映射表 /// - public static readonly Dictionary AFNHandlersDictionary = new(); + public static readonly Dictionary T3761AFNHandlers = new(); - static TelemetryPacketBuilder() + static Telemetry3761PacketBuilder() { // 初始化时自动注册所有符合命名规则的方法 - var methods = typeof(TelemetryPacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public); + var methods = typeof(Telemetry3761PacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (var method in methods) { if (method.Name.StartsWith("AFN") && method.Name.EndsWith("_Fn_Send")) { string code = method.Name; - var delegateInstance = (AFNDelegate)Delegate.CreateDelegate(typeof(AFNDelegate), method); - AFNHandlersDictionary[code] = delegateInstance; + var delegateInstance = (T3761Delegate)Delegate.CreateDelegate(typeof(T3761Delegate), method); + T3761AFNHandlers[code] = delegateInstance; } } } #region AFN_00H 确认∕否认 - public static TelemetryPacketResponse AFN00_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN00_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -64,13 +55,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_01H 复位命令 - public static TelemetryPacketResponse AFN01_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN01_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -89,13 +80,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_02H 链路接口检测 - public static TelemetryPacketResponse AFN02_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN02_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -114,12 +105,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_04H 设置参数 - public static TelemetryPacketResponse AFN04_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN04_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -138,13 +129,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_05H 控制命令 - public static TelemetryPacketResponse AFN05_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN05_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -163,12 +154,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_09H 请求终端配置及信息 - public static TelemetryPacketResponse AFN09_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN09_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -187,13 +178,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_0AH 查询参数 - public static TelemetryPacketResponse AFN0A_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN0A_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -212,12 +203,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_0CH 请求一类数据 - public static TelemetryPacketResponse AFN0C_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN0C_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -236,12 +227,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN_0DH 请求二类数据 - public static TelemetryPacketResponse AFN0D_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN0D_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -260,12 +251,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #endregion #region AFN10H 数据转发 - public static TelemetryPacketResponse AFN10_Fn_Send(TelemetryPacketRequest request) + public static Telemetry3761PacketResponse AFN10_Fn_Send(Telemetry3761PacketRequest request) { var reqParameter = new ReqParameter2() { @@ -284,7 +275,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas Fn = request.Fn }; var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter, request.DataUnit); - return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, }; + return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, }; } #region SpecialAmmeter 特殊电表转发 diff --git a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs similarity index 59% rename from shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketRequest.cs rename to protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs index d22f923..df12e09 100644 --- a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketRequest.cs +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs @@ -1,20 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JiShe.CollectBus.Common.BuildSendDatas +namespace JiShe.CollectBus.Protocol.Contracts.SendData { /// - /// 报文构建参数 + /// 构建3761报文参数 /// - public class TelemetryPacketRequest + public class Telemetry3761PacketRequest { /// /// 集中器地址 /// - public string FocusAddress { get; set; } + public required string FocusAddress { get; set; } /// /// 抄读功能码 @@ -24,7 +18,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas /// /// 抄读计量点,也就是终端电表对应端口 /// - public int Pn { get; set; } + public int Pn { get; set; } /// /// 透明转发单元 diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs new file mode 100644 index 0000000..c27906f --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs @@ -0,0 +1,23 @@ +namespace JiShe.CollectBus.Protocol.Contracts.SendData +{ + /// + /// 返回3761报文结果 + /// + public class Telemetry3761PacketResponse + { + /// + /// 帧序列域SEQ + /// + public int Seq { get; set; } + + /// + /// 地址域A3的主站地址MSA + /// + public int MSA { get; set; } + + /// + /// 报文体 + /// + public byte[] Data { get; set; } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs new file mode 100644 index 0000000..7c6175f --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs @@ -0,0 +1,836 @@ +using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Helpers; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.Enums; +using JiShe.CollectBus.IotSystems.Devices; +using JiShe.CollectBus.IotSystems.MessageReceiveds; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Kafka.Producer; +using JiShe.CollectBus.Protocol.Contracts.Abstracts; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol3761; +using Mapster; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using TouchSocket.Sockets; +using Volo.Abp.Domain.Repositories; + +namespace JiShe.CollectBus.Protocol +{ + public class T37612012ProtocolPlugin : ProtocolPlugin + { + private readonly ILogger _logger; + + private readonly IProducerService _producerService; + + private readonly IRepository _deviceRepository; + private readonly ITcpService _tcpService; + + public readonly Dictionary T3761AFNHandlers; + + /// + /// Initializes a new instance of the class. + /// + /// The service provider. + public T37612012ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger) + { + _logger = logger; + //_logger = serviceProvider.GetRequiredService>(); + _producerService = serviceProvider.GetRequiredService(); + _deviceRepository = serviceProvider.GetRequiredService>(); + _tcpService = tcpService; + T3761AFNHandlers = Telemetry3761PacketBuilder.T3761AFNHandlers; + } + + public override ProtocolInfo Info => new(nameof(T37612012ProtocolPlugin), "376.1", "TCP", "376.1协议", "DTS1980"); + + public override async Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null) + { + TB3761? tB3761 = Analysis3761(messageReceived); + if (tB3761 != null) + { + if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测) + { + if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null) + { + _logger.LogError($"解析AFN.链路接口检测报文失败,报文:{messageReceived},TB3761:{tB3761.Serialize()}"); + } + else + { + if (tB3761.DT?.Fn == (int)FN.登录) + { + // 登录回复 + if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认) + await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + } + else if (tB3761.DT?.Fn == (int)FN.心跳) + { + // 心跳回复 + //心跳帧有两种情况: + //1. 集中器先有登录帧,再有心跳帧 + //2. 集中器没有登录帧,只有心跳帧 + await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + } + } + + } + await OnTcpNormalReceived(client, tB3761); + } + return (tB3761 as T)!; + } + + /// + /// 正常帧处理,将不同的AFN进行分发 + /// + /// + /// + /// + /// + private async Task OnTcpNormalReceived(ITcpSessionClient tcpSessionClient, TB3761 tB3761) + { + //string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, aFn); + //todo 如何确定时标?目前集中器的采集频率,都是固定,数据上报的时候,根据当前时间,往后推测出应当采集的时间点作为时标。但是如果由于网络问题,数据一直没上报的情况改怎么计算? + //await _producerBus.PublishAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived + //{ + // ClientId = client.Id, + // ClientIp = client.IP, + // ClientPort = client.Port, + // MessageHexString = messageHexString, + // DeviceNo = deviceNo, + // MessageId = NewId.NextGuid().ToString() + //}); + + if (tB3761.AFN_FC.BaseHexMessage == null || tB3761.DT.BaseHexMessage == null || tB3761.BaseHexMessage.HexMessageString==null) + { + _logger.LogError("376.1协议解析AFN失败"); + return; + } + // 登录心跳已做了处理,故需要忽略登录和心跳帧 + if (tB3761.DT.Fn == (int)FN.登录 || tB3761.DT.Fn == (int)FN.心跳) + return; + //TODO:根据AFN进行分流推送到kafka + string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, tB3761.AFN_FC.AFN.ToString().PadLeft(2, '0')); + + MessageProtocolAnalysis messageReceivedAnalysis = new MessageProtocolAnalysis() + { + ClientId = tcpSessionClient.Id, + ClientIp = tcpSessionClient.IP, + ClientPort = tcpSessionClient.Port, + MessageHexString = tB3761.BaseHexMessage.HexMessageString!, + DeviceNo = tB3761.A.Code!, + MessageId = Guid.NewGuid().ToString(), + ReceivedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), + Data = tB3761 + }; + + List topics = ProtocolConstExtensions.GetAllTopicNamesByReceived(); + if (topics.Contains(topicName)) + await _producerService.ProduceAsync(topicName, messageReceivedAnalysis); + else + { + _logger.LogError($"不支持的上报kafka主题:{topicName}"); + await _producerService.ProduceAsync(ProtocolConst.SubscriberReceivedEventName, messageReceivedAnalysis); + } + + } + + + /// + /// 登录回复 + /// + /// + /// + /// + /// + /// + public async Task LoginAsync(ITcpSessionClient client, string messageReceived, string code, int? msa, int? pseq) + { + string oldClientId = $"{client.Id}"; + await client.ResetIdAsync(code); + var deviceInfoList = await _deviceRepository.GetListAsync(a => a.Number == code); + if (deviceInfoList != null && deviceInfoList.Count > 1) + { + //todo 推送集中器编号重复预警 + _logger.LogError($"集中器编号:{code},存在多个集中器,请检查集中器编号是否重复"); + return; + } + + var entity = deviceInfoList?.FirstOrDefault(a => a.Number == code); + if (entity == null) + { + await _deviceRepository.InsertAsync(new Device(code, oldClientId, DateTime.Now, DateTime.Now, DeviceStatus.Online)); + } + else + { + entity.UpdateByLoginAndHeartbeat(oldClientId); + await _deviceRepository.UpdateAsync(entity); + } + + var messageReceivedLoginEvent = new MessageReceivedLogin + { + ClientId = code, + ClientIp = client.IP, + ClientPort = client.Port, + MessageHexString = messageReceived, + DeviceNo = code, + MessageId = Guid.NewGuid().ToString(), + ReceivedTime=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + }; + await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent); + var reqParam = new ReqParameter2 + { + AFN = AFN.确认或否认, + FunCode = (int)CFromStationFunCode.链路数据, + PRM = PRM.从动站报文, + A = code, + Seq = new Seq() + { + TpV = TpV.附加信息域中无时间标签, + FIRFIN = FIRFIN.单帧, + CON = CON.需要对该帧进行确认, + PRSEQ = pseq!.Value + }, + MSA = msa!.Value, + Pn = 0, + Fn = 1 + }; + var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); + var issuedEventMessage = new IssuedEventMessage + { + ClientId = messageReceivedLoginEvent.ClientId, + DeviceNo = messageReceivedLoginEvent.DeviceNo, + Message = bytes, + Type = IssuedEventType.Login, + MessageId = messageReceivedLoginEvent.MessageId + }; + if (_tcpService.ClientExists(issuedEventMessage.ClientId)) + { + await _tcpService.SendAsync(issuedEventMessage.ClientId, issuedEventMessage.Message); + _logger.LogInformation($"集中器地址{issuedEventMessage.ClientId} 登录回复下发内容:{Convert.ToHexString(bytes)}"); + await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, issuedEventMessage); + } + } + + /// + /// 心跳帧解析 + /// + /// + /// + /// + /// + /// + public async Task HeartbeatAsync(ITcpSessionClient client, string messageReceived, string code, int? msa, int? pseq) + { + + string clientId = code; + string oldClientId = $"{client.Id}"; + var deviceInfoList = await _deviceRepository.GetListAsync(a => a.Number == code); + if (deviceInfoList != null && deviceInfoList.Count > 1) + { + //todo 推送集中器编号重复预警 + _logger.LogError($"集中器编号:{code},存在多个集中器,请检查集中器编号是否重复"); + return; + } + + var entity = deviceInfoList?.FirstOrDefault(a => a.Number == code); + if (entity == null) //没有登录帧的设备,只有心跳帧 + { + await client.ResetIdAsync(clientId); + await _deviceRepository.InsertAsync(new Device(code, oldClientId, DateTime.Now, DateTime.Now, DeviceStatus.Online)); + } + else + { + if (clientId != oldClientId) + { + entity.UpdateByLoginAndHeartbeat(oldClientId); + } + else + { + entity.UpdateByLoginAndHeartbeat(); + } + + await _deviceRepository.UpdateAsync(entity); + } + + var messageReceivedHeartbeatEvent = new MessageReceivedHeartbeat + { + ClientId = clientId, + ClientIp = client.IP, + ClientPort = client.Port, + MessageHexString = messageReceived, + DeviceNo = code, + MessageId = Guid.NewGuid().ToString(), + ReceivedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + }; + await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatReceivedEventName, messageReceivedHeartbeatEvent); + + var reqParam = new ReqParameter2() + { + AFN = AFN.确认或否认, + FunCode = (int)CFromStationFunCode.链路数据, + PRM = PRM.从动站报文, + A = code, + Seq = new Seq() + { + TpV = TpV.附加信息域中无时间标签, + FIRFIN = FIRFIN.单帧, + CON = CON.不需要对该帧进行确认, + PRSEQ = pseq!.Value, + }, + MSA = msa!.Value, + Pn = 0, + Fn = 1 + }; + var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); + + IssuedEventMessage issuedEventMessage = new IssuedEventMessage + { + ClientId = messageReceivedHeartbeatEvent.ClientId, + DeviceNo = messageReceivedHeartbeatEvent.DeviceNo, + Message = bytes, + Type = IssuedEventType.Heartbeat, + MessageId = messageReceivedHeartbeatEvent.MessageId + }; + if (_tcpService.ClientExists(issuedEventMessage.ClientId)) + { + await _tcpService.SendAsync(issuedEventMessage.ClientId, bytes); + _logger.LogWarning($"集中器地址{issuedEventMessage.ClientId} 心跳回复下发内容:{Convert.ToHexString(bytes)}"); + await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, issuedEventMessage); + } + + + } + + /// + /// 组装报文 + /// + /// 报文构建参数 + /// + public override async Task BuildAsync(ProtocolBuildRequest request) + { + if (request == null) + { + throw new Exception($"{nameof(T37612012ProtocolPlugin)} 报文构建失败,参数为空"); + } + var itemCodeArr = request.ItemCode.Split('_'); + var aFNStr = itemCodeArr[0]; + var aFN = (AFN)aFNStr.HexToDec(); + var fn = int.Parse(itemCodeArr[1]); + Telemetry3761PacketResponse builderResponse = null; + + List dataUnit = new List(); + //数据转发场景 10H_F1_1CH + if (aFNStr == "10" && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false) + { + //var t645PacketHandlerName = $"C{request.SubProtocolRequest.ItemCode}_Send"; + //Telemetry645PacketResponse t645PacketResponse = null; + + //if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName + // , out var t645PacketHandler)) + //{ + // t645PacketResponse = t645PacketHandler(new Telemetry645PacketRequest() + // { + // MeterAddress = request.SubProtocolRequest.MeterAddress, + // Password = request.SubProtocolRequest.Password, + // ItemCode = request.SubProtocolRequest.ItemCode, + // }); + //} + + //if (t645PacketResponse != null) + //{ + // dataUnit = t645PacketResponse.Data; + //} + } + + string afnMethonCode = $"AFN{aFNStr}_Fn_Send"; + if (T3761AFNHandlers != null && T3761AFNHandlers.TryGetValue(afnMethonCode + , out var handler)) + { + builderResponse = handler(new Telemetry3761PacketRequest() + { + FocusAddress = request.FocusAddress, + Fn = fn, + Pn = request.Pn, + DataUnit = dataUnit, + }); + } + + if (builderResponse == null) + { + return new ProtocolBuildResponse(); + } + + var result = builderResponse.Adapt(); + result.IsSuccess = true; + + return await Task.FromResult(result); + } + + + + + /// + /// 解析376.1帧 + /// + /// + /// + public virtual TB3761? Analysis3761(string messageReceived) + { + try + { + var hexStringList = messageReceived.StringToPairs(); + // 初步校验 + if (hexStringList.Count < 6 || hexStringList.FirstOrDefault() != "68" || hexStringList.Skip(5).Take(1).FirstOrDefault() != "68" || hexStringList.Count < 18 || hexStringList.LastOrDefault() != "16") + { + _logger.LogError($"解析Analysis3761校验不通过,报文:{messageReceived}"); + } + else + { + TB3761 tB3761 = new TB3761 + { + BaseHexMessage = new BaseHexMessage + { + HexMessageString = messageReceived, + HexMessageList = hexStringList + }, + C = Analysis_C(hexStringList), + A = Analysis_A(hexStringList), + AFN_FC = Analysis_AFN_FC(hexStringList), + SEQ = Analysis_SEQ(hexStringList), + UnitData = Analysis_UnitData(hexStringList), + DA = Analysis_DA(hexStringList), + DT = Analysis_DT(hexStringList) + }; + return tB3761; + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis3761错误,报文:{messageReceived},异常:{ex.Message}"); + } + return null; + } + + /// + /// 控制域C解析 + /// + /// + public virtual C Analysis_C(List hexStringList) + { + C c = new C(); + try + { + if (hexStringList.Count > 6) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(6, 1) // 控制域 1字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + if (baseHexMessage.HexMessageList.Count == 0) + return null; + string binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); + c = new C + { + BaseHexMessage = baseHexMessage, + FC = binStr.Substring(binStr.Length - 4, 4).BinToDec(), + FCV = binStr.Substring(3, 1).BinToDec(), + FCB = binStr.Substring(2, 1).BinToDec(), + PRM = binStr.Substring(1, 1).BinToDec(), + DIR = binStr.Substring(0, 1).BinToDec() + }; + return c; + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_C错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + + return c; + } + + /// + /// 地址域A解析 + /// + /// + /// + public virtual A Analysis_A(List hexStringList) + { + A a = new A(); + try + { + if (hexStringList.Count > 7) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(7, 5) // 地址域 5个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + a = new A + { + BaseHexMessage = baseHexMessage, + A1 = baseHexMessage.HexMessageList.ListReverseToStr(0, 2),//.DataConvert(10);//行政区划码A1 + A2 = baseHexMessage.HexMessageList.ListReverseToStr(2, 2).PadLeft(5, '0').HexToDec(),//终端地址A2 + A3 = Analysis_A3(baseHexMessage.HexMessageList) //主站地址和组地址标志A3 + }; + a.Code = $"{a.A1.PadLeft(4, '0')}{a.A2.ToString()!.PadLeft(5, '0')}"; + + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_A错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + + return a; + + } + + /// + /// 站地址和组地址标志A3 + /// + /// 地址域A集合 + /// + public virtual A3 Analysis_A3(List hexAList) + { + A3 a3 = new A3(); + try + { + if (hexAList.Count != 0) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexAList.GetRange(4, 1) // 站地址和组地址标志A3 1个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); + a3 = new A3 + { + BaseHexMessage = baseHexMessage, + D0 = binStr.Substring(binStr.Length - 1, 1).BinToDec(), + D1_D7 = binStr.Substring(0, binStr.Length - 1).BinToDec() + }; + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_A3错误,报文:{string.Join("", hexAList)},异常:{ex.Message}"); + } + + return a3; + } + + /// + /// AFN_FC功能码 + /// + /// + public virtual AFN_FC Analysis_AFN_FC(List hexStringList) + { + AFN_FC aFN_FC = new AFN_FC(); + try + { + if (hexStringList.Count == 0) + { + + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(12, 1) //AFN功能码 1个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + + aFN_FC = new AFN_FC + { + BaseHexMessage = baseHexMessage, + AFN = baseHexMessage.HexMessageString.HexToDec(), + }; + } + + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_AFN_FC错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + + return aFN_FC; + } + + /// + /// 解析帧序列域SEQ + /// + /// + public virtual SEQ Analysis_SEQ(List hexStringList) + { + SEQ seq = new SEQ(); + try + { + if (hexStringList.Count != 0) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(13, 1) //帧序列域 SEQ 1个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); + seq = new SEQ + { + PSEQ = binStr.Substring(binStr.Length - 4, 4).BinToDec(), + CON = binStr.Substring(3, 1).BinToDec(), + FIN = binStr.Substring(2, 1).BinToDec(), + FIR = binStr.Substring(1, 1).BinToDec(), + TpV = binStr.Substring(0, 1).BinToDec() + }; + } + + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_SEQ错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + return seq; + } + + + /// + /// 数据单元标识及数据单元数据 + /// + public virtual UnitData Analysis_UnitData(List hexStringList) + { + UnitData unitData = new UnitData(); + try + { + if (hexStringList.Count != 0) + { + unitData = new UnitData + { + HexMessageList = hexStringList.GetRange(14, hexStringList.Count - 14 - 2) //总数字节数-固定长度报文头-控制域C-地址域A-校验和CS-结束字符(16H) + }; + unitData.HexMessageString = string.Join("", unitData.HexMessageList); + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_UnitData错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + return unitData; + } + + /// + /// 信息点DA Pn + /// + /// + public virtual DA Analysis_DA(List hexStringList) + { + DA da = new DA(); + try + { + if (hexStringList.Count != 0) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(14, 2) //信息点DA Pn 2个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + var da1 = baseHexMessage.HexMessageList[0]; + var da2 = baseHexMessage.HexMessageList[1]; + da = new DA() + { + BaseHexMessage = baseHexMessage, + Pn = CalculatePn(da1, da2) + }; + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_DA错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + return da; + } + + /// + /// 信息类DT Fn + /// + /// + public virtual DT Analysis_DT(List hexStringList) + { + DT dt = new DT(); + try + { + if (hexStringList.Count != 0) + { + BaseHexMessage baseHexMessage = new BaseHexMessage + { + HexMessageList = hexStringList.GetRange(16, 2) //信息类DT Fn 2个字节 + }; + baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); + var dt1 = baseHexMessage.HexMessageList[0]; + var dt2 = baseHexMessage.HexMessageList[1]; + dt = new DT() + { + BaseHexMessage = baseHexMessage, + Fn = CalculateFn(dt1, dt2) + }; + } + } + catch (Exception ex) + { + _logger.LogError($"解析Analysis_DT错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); + } + + return dt; + + } + + + /// + /// 计算Pn + /// + /// + /// + /// + public static int CalculatePn(string da1, string da2) => (da2.HexToDec() - 1) * 8 + (8 - da1.HexTo4BinZero().IndexOf(da1.Equals("00") ? "0" : "1")); + + + /// + /// 计算Fn + /// + /// + /// + /// + public static int CalculateFn(string dt1, string dt2) => dt2.HexToDec() * 8 + (8 - dt1.HexTo4BinZero().IndexOf("1")); + + + + #region 上行命令 + + //68 + //32 00 + //32 00 + //68 + //C9 1100'1001. 控制域C。 + // D7=1, (终端发送)上行方向。 + // D6=1, 此帧来自启动站。 + // D5=0, (上行方向)要求访问位。表示终端无事件数据等待访问。 + // D4=0, 保留 + // D3~D0=9, 功能码。链路测试 + + //20 32 行政区划码 + //90 26 终端地址 + //00 主站地址和组地址标志。终端为单地址。 //3220 09 87 2 + // 终端启动的发送帧的 MSA 应为 0, 其主站响应帧的 MSA 也应为 0. + //02 应用层功能码。AFN=2, 链路接口检测 + //70 0111'0000. 帧序列域。无时间标签、单帧、需要确认。 + //00 00 信息点。DA1和DA2全为“0”时,表示终端信息点。 + //01 00 信息类。F1, 登录。 + //44 帧尾,包含用户区数据校验和 + //16 帧结束标志 + + /// + /// 解析上行命令 + /// + /// + /// + public CommandReulst? AnalysisCmd(string cmd) + { + CommandReulst? commandReulst = null; + var hexStringList = cmd.StringToPairs(); + + if (hexStringList.Count < hearderLen) + { + return commandReulst; + } + //验证起始字符 + if (!hexStringList[0].IsStartStr() || !hexStringList[5].IsStartStr()) + { + return commandReulst; + } + + var lenHexStr = $"{hexStringList[2]}{hexStringList[1]}"; + var lenBin = lenHexStr.HexToBin(); + var len = lenBin.Remove(lenBin.Length - 2).BinToDec(); + //验证长度 + if (hexStringList.Count - 2 != hearderLen + len) + return commandReulst; + + var userDataIndex = hearderLen; + var c = hexStringList[userDataIndex];//控制域 1字节 + userDataIndex += 1; + + var aHexList = hexStringList.Skip(userDataIndex).Take(5).ToList();//地址域 5字节 + var a = AnalysisA(aHexList); + var a3Bin = aHexList[4].HexToBin().PadLeft(8, '0'); + var mSA = a3Bin.Substring(0, 7).BinToDec(); + userDataIndex += 5; + + var aFN = (AFN)hexStringList[userDataIndex].HexToDec();//1字节 + userDataIndex += 1; + + var seq = hexStringList[userDataIndex].HexToBin().PadLeft(8, '0'); + var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1)); + var fIRFIN = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2)); + var cON = (CON)Convert.ToInt32(seq.Substring(3, 1)); + var prseqBin = seq.Substring(4, 4); + userDataIndex += 1; + + // (DA2 - 1) * 8 + DA1 = pn + var da1Bin = hexStringList[userDataIndex].HexToBin(); + var da1 = da1Bin == "0" ? 0 : da1Bin.Length; + userDataIndex += 1; + var da2 = hexStringList[userDataIndex].HexToDec(); + var pn = da2 == 0 ? 0 : (da2 - 1) * 8 + da1; + userDataIndex += 1; + //(DT2*8)+DT1=fn + var dt1Bin = hexStringList[userDataIndex].HexToBin(); + var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0; + userDataIndex += 1; + var dt2 = hexStringList[userDataIndex].HexToDec(); + var fn = dt2 * 8 + dt1; + userDataIndex += 1; + + //数据单元 + var datas = hexStringList.Skip(userDataIndex).Take(len + hearderLen - userDataIndex).ToList(); + + //EC + //Tp + commandReulst = new CommandReulst() + { + A = a, + MSA = mSA, + AFN = aFN, + Seq = new Seq() + { + TpV = tpV, + FIRFIN = fIRFIN, + CON = cON, + PRSEQ = prseqBin.BinToDec(), + }, + CmdLength = len, + Pn = pn, + Fn = fn, + HexDatas = datas + }; + + return commandReulst; + } + + /// + /// 解析地址 + /// + /// + /// + private string AnalysisA(List aHexList) + { + var a1 = aHexList[1] + aHexList[0]; + var a2 = aHexList[3] + aHexList[2]; + var a2Dec = a2.HexToDec(); + var a3 = aHexList[4]; + var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}"; + return a; + } + + #endregion + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/JiShe.CollectBus.Protocol.T6452007.csproj b/protocols/JiShe.CollectBus.Protocol.T6452007/JiShe.CollectBus.Protocol.T6452007.csproj new file mode 100644 index 0000000..e19a7e0 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/JiShe.CollectBus.Protocol.T6452007.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + preview + + + + + + + + + + + + + + + + + + + diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/JiSheCollectBusProtocolT6452007Module.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/JiSheCollectBusProtocolT6452007Module.cs new file mode 100644 index 0000000..cbd7422 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/JiSheCollectBusProtocolT6452007Module.cs @@ -0,0 +1,29 @@ +using JiShe.CollectBus.Protocol.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; +using Volo.Abp; +using Volo.Abp.Modularity; + +namespace JiShe.CollectBus.Protocol +{ + public class JiSheCollectBusProtocolT6452007Module : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddKeyedSingleton(nameof(T6452007ProtocolPlugin)); + } + + public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + Console.WriteLine($"{nameof(T6452007ProtocolPlugin)} OnApplicationInitializationAsync"); + var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(T6452007ProtocolPlugin)); + await standardProtocol.LoadAsync(); + } + + public override void OnApplicationShutdown(ApplicationShutdownContext context) + { + Console.WriteLine($"{nameof(T6452007ProtocolPlugin)} OnApplicationShutdown"); + base.OnApplicationShutdown(context); + } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs new file mode 100644 index 0000000..6c3e69a --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketBuilder.cs @@ -0,0 +1,106 @@ +using FreeSql; +using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Models; +using System.Reflection; + +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 构建645-2007下发报文 + /// + public static class Telemetry6452007PacketBuilder + { + /// + /// 构建报文的委托 + /// + /// + /// + public delegate Telemetry6452007PacketResponse T6452007Delegate(Telemetry6452007PacketRequest request); + + /// + /// 编码与方法的映射表 + /// + public static readonly Dictionary T645ControlHandlers = new(); + + static Telemetry6452007PacketBuilder() + { + // 初始化时自动注册所有符合命名规则的方法 + var methods = typeof(Telemetry6452007PacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public); + foreach (var method in methods) + { + if (method.Name.StartsWith("C") && method.Name.EndsWith("_Send")) + { + string code = method.Name; + var delegateInstance = (T6452007Delegate)Delegate.CreateDelegate(typeof(T6452007Delegate), method); + T645ControlHandlers[code] = delegateInstance; + } + } + } + + #region 1CH 跳合闸、报警、保电 + + /// + /// 1CH 跳合闸 + /// + /// + /// + public static Telemetry6452007PacketResponse C1C_01_Send(Telemetry6452007PacketRequest request) + { + var itemCodeArr = request.ItemCode.Split('_'); + var c_data = itemCodeArr[0]; + var n_data = itemCodeArr[1]; + string password = request.Password; + string pwdLevel = "02"; + + if (!string.IsNullOrWhiteSpace(password) && password.Contains("|")) + { + var sp = password.Split('|'); + password = sp[0]; + pwdLevel = sp[1]; + } + + var strDate = DateTime.Now.AddYears(3).ToString("000012ddMMyy").StrAddSpan();//命令有效截止时间 + + var strP = password.StrAddSpan().StrReverseOrder(); + var strSJY = " " + pwdLevel + " " + strP + " 01 00 00 00 " + n_data + " 00 " + strDate; + var dataUnit = strSJY.Replace(" ", "").StringToPairs(); + + var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit); + return new Telemetry6452007PacketResponse() { Data = dataList }; + } + + + /// + /// 1CH 保电 + /// + /// + /// + public static Telemetry6452007PacketResponse C1C_03_Send(Telemetry6452007PacketRequest request) + { + var itemCodeArr = request.ItemCode.Split('_'); + var c_data = itemCodeArr[0]; + var n_data = itemCodeArr[1]; + string password = request.Password; + + if (!string.IsNullOrWhiteSpace(password) && password.Contains("|")) + { + var sp = password.Split('|'); + password = sp[0]; + } + + var strDate = (n_data + DateTime.Now.AddDays(1).ToString("00000012ddMMyy")).StrAddSpan(); + + var strP = password.StrAddSpan().StrReverseOrder(); + + var strSJY = " 02 " + strP + " 01 00 00 00 " + strDate; + + var dataUnit = strSJY.Replace(" ", "").StringToPairs(); + + 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 new file mode 100644 index 0000000..b4b45b7 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketRequest.cs @@ -0,0 +1,23 @@ +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 构建645报文参数 + /// + public class Telemetry6452007PacketRequest + { + /// + /// 表地址 + /// + 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/SendData/Telemetry6452007PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketResponse.cs new file mode 100644 index 0000000..6d8f90d --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/SendData/Telemetry6452007PacketResponse.cs @@ -0,0 +1,13 @@ +namespace JiShe.CollectBus.Protocol.SendData +{ + /// + /// 返回645报文结果 + /// + public class Telemetry6452007PacketResponse + { + /// + /// 报文体 + /// + public List Data { get; set; } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs new file mode 100644 index 0000000..fad7ed0 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs @@ -0,0 +1,271 @@ +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.IotSystems.Devices; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Kafka.Producer; +using JiShe.CollectBus.Protocol.Contracts.Abstracts; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol.SendData; +using Mapster; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using TouchSocket.Sockets; +using Volo.Abp.Domain.Repositories; + +namespace JiShe.CollectBus.Protocol +{ + /// + /// T6452007协议插件 + /// + public class T6452007ProtocolPlugin : T37612012ProtocolPlugin + { + private readonly ILogger _logger; + + public readonly Dictionary T645ControlHandlers; + + /// + /// Initializes a new instance of the class. + /// + /// The service provider. + public T6452007ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger, tcpService) + { + _logger = logger; + T645ControlHandlers = Telemetry6452007PacketBuilder.T645ControlHandlers; + } + + public sealed override ProtocolInfo Info => new(nameof(T6452007ProtocolPlugin), "376.1/645-2007", "TCP", "376.1/645-2007协议", "DTS1980"); + + public override async Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null) + { + //TODO:645解析报文 + //TB3761? tB3761 = Analysis3761(messageReceived); + //if (tB3761 != null) + //{ + // if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测) + // { + // if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null) + // { + // _logger.LogError($"解析AFN.链路接口检测报文失败,报文:{messageReceived},TB3761:{tB3761.Serialize()}"); + // } + // else + // { + // if (tB3761.DT?.Fn == (int)FN.登录) + // { + // // 登录回复 + // if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认) + // await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + // } + // else if (tB3761.DT?.Fn == (int)FN.心跳) + // { + // // 心跳回复 + // //心跳帧有两种情况: + // //1. 集中器先有登录帧,再有心跳帧 + // //2. 集中器没有登录帧,只有心跳帧 + // await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); + // } + // } + + // } + // await OnTcpNormalReceived(client, tB3761); + //} + //return (tB3761 as T)!; + return null; + } + + /// + /// 组装报文 + /// + /// 报文构建参数 + /// + public override async Task BuildAsync(ProtocolBuildRequest request) + { + if (request == null) + { + _logger.LogError($"{nameof(ProtocolBuildResponse)} 报文构建失败,参数为空"); + return new ProtocolBuildResponse(); + } + var itemCodeArr = request.ItemCode.Split('_'); + var aFNStr = itemCodeArr[0]; + var aFN = (AFN)aFNStr.HexToDec(); + var fn = int.Parse(itemCodeArr[1]); + Telemetry3761PacketResponse builderResponse = null; + + List dataUnit = new List(); + //数据转发场景 10H_F1_1CH + if (aFNStr == "10" && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false) + { + var t645PacketHandlerName = $"C{request.SubProtocolRequest.ItemCode}_Send"; + Telemetry6452007PacketResponse t645PacketResponse = null; + + if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName + , out var t645PacketHandler)) + { + t645PacketResponse = t645PacketHandler(new Telemetry6452007PacketRequest() + { + MeterAddress = request.SubProtocolRequest.MeterAddress, + Password = request.SubProtocolRequest.Password, + ItemCode = request.SubProtocolRequest.ItemCode, + }); + } + + if (t645PacketResponse != null) + { + dataUnit = t645PacketResponse.Data; + } + } + + string afnMethonCode = $"AFN{aFNStr}_Fn_Send"; + if (base.T3761AFNHandlers != null && base.T3761AFNHandlers.TryGetValue(afnMethonCode + , out var handler)) + { + builderResponse = handler(new Telemetry3761PacketRequest() + { + FocusAddress = request.FocusAddress, + Fn = fn, + Pn = request.Pn, + DataUnit = dataUnit, + }); + } + + if (builderResponse == null) + { + return new ProtocolBuildResponse(); + } + + var result = builderResponse.Adapt(); + result.IsSuccess = true; + + return await Task.FromResult(result); + } + + + #region 上行命令 + + //68 + //32 00 + //32 00 + //68 + //C9 1100'1001. 控制域C。 + // D7=1, (终端发送)上行方向。 + // D6=1, 此帧来自启动站。 + // D5=0, (上行方向)要求访问位。表示终端无事件数据等待访问。 + // D4=0, 保留 + // D3~D0=9, 功能码。链路测试 + + //20 32 行政区划码 + //90 26 终端地址 + //00 主站地址和组地址标志。终端为单地址。 //3220 09 87 2 + // 终端启动的发送帧的 MSA 应为 0, 其主站响应帧的 MSA 也应为 0. + //02 应用层功能码。AFN=2, 链路接口检测 + //70 0111'0000. 帧序列域。无时间标签、单帧、需要确认。 + //00 00 信息点。DA1和DA2全为“0”时,表示终端信息点。 + //01 00 信息类。F1, 登录。 + //44 帧尾,包含用户区数据校验和 + //16 帧结束标志 + + /// + /// 解析上行命令 + /// + /// + /// + public CommandReulst? AnalysisCmd(string cmd) + { + CommandReulst? commandReulst = null; + var hexStringList = cmd.StringToPairs(); + + if (hexStringList.Count < hearderLen) + { + return commandReulst; + } + //验证起始字符 + if (!hexStringList[0].IsStartStr() || !hexStringList[5].IsStartStr()) + { + return commandReulst; + } + + var lenHexStr = $"{hexStringList[2]}{hexStringList[1]}"; + var lenBin = lenHexStr.HexToBin(); + var len = lenBin.Remove(lenBin.Length - 2).BinToDec(); + //验证长度 + if (hexStringList.Count - 2 != hearderLen + len) + return commandReulst; + + var userDataIndex = hearderLen; + var c = hexStringList[userDataIndex];//控制域 1字节 + userDataIndex += 1; + + var aHexList = hexStringList.Skip(userDataIndex).Take(5).ToList();//地址域 5字节 + var a = AnalysisA(aHexList); + var a3Bin = aHexList[4].HexToBin().PadLeft(8, '0'); + var mSA = a3Bin.Substring(0, 7).BinToDec(); + userDataIndex += 5; + + var aFN = (AFN)hexStringList[userDataIndex].HexToDec();//1字节 + userDataIndex += 1; + + var seq = hexStringList[userDataIndex].HexToBin().PadLeft(8, '0'); + var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1)); + var fIRFIN = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2)); + var cON = (CON)Convert.ToInt32(seq.Substring(3, 1)); + var prseqBin = seq.Substring(4, 4); + userDataIndex += 1; + + // (DA2 - 1) * 8 + DA1 = pn + var da1Bin = hexStringList[userDataIndex].HexToBin(); + var da1 = da1Bin == "0" ? 0 : da1Bin.Length; + userDataIndex += 1; + var da2 = hexStringList[userDataIndex].HexToDec(); + var pn = da2 == 0 ? 0 : (da2 - 1) * 8 + da1; + userDataIndex += 1; + //(DT2*8)+DT1=fn + var dt1Bin = hexStringList[userDataIndex].HexToBin(); + var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0; + userDataIndex += 1; + var dt2 = hexStringList[userDataIndex].HexToDec(); + var fn = dt2 * 8 + dt1; + userDataIndex += 1; + + //数据单元 + var datas = hexStringList.Skip(userDataIndex).Take(len + hearderLen - userDataIndex).ToList(); + + //EC + //Tp + commandReulst = new CommandReulst() + { + A = a, + MSA = mSA, + AFN = aFN, + Seq = new Seq() + { + TpV = tpV, + FIRFIN = fIRFIN, + CON = cON, + PRSEQ = prseqBin.BinToDec(), + }, + CmdLength = len, + Pn = pn, + Fn = fn, + HexDatas = datas + }; + + return commandReulst; + } + + /// + /// 解析地址 + /// + /// + /// + private string AnalysisA(List aHexList) + { + var a1 = aHexList[1] + aHexList[0]; + var a2 = aHexList[3] + aHexList[2]; + var a2Dec = a2.HexToDec(); + var a3 = aHexList[4]; + var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}"; + return a; + } + #endregion + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.Test/JiShe.CollectBus.Protocol.Test.csproj b/protocols/JiShe.CollectBus.Protocol.Test/JiShe.CollectBus.Protocol.Test.csproj index bfc186f..e798bdb 100644 --- a/protocols/JiShe.CollectBus.Protocol.Test/JiShe.CollectBus.Protocol.Test.csproj +++ b/protocols/JiShe.CollectBus.Protocol.Test/JiShe.CollectBus.Protocol.Test.csproj @@ -17,7 +17,7 @@ - + diff --git a/protocols/JiShe.CollectBus.Protocol.Test/JiSheCollectBusTestProtocolModule.cs b/protocols/JiShe.CollectBus.Protocol.Test/JiSheCollectBusTestProtocolModule.cs index b9a28e4..6c3ebdc 100644 --- a/protocols/JiShe.CollectBus.Protocol.Test/JiSheCollectBusTestProtocolModule.cs +++ b/protocols/JiShe.CollectBus.Protocol.Test/JiSheCollectBusTestProtocolModule.cs @@ -1,6 +1,5 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.DependencyInjection; -using System; using Volo.Abp; using Volo.Abp.Modularity; diff --git a/protocols/JiShe.CollectBus.Protocol.Test/TestProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.Test/TestProtocolPlugin.cs index 511baa4..cb6d42e 100644 --- a/protocols/JiShe.CollectBus.Protocol.Test/TestProtocolPlugin.cs +++ b/protocols/JiShe.CollectBus.Protocol.Test/TestProtocolPlugin.cs @@ -1,30 +1,31 @@ -using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Common.Models; -using JiShe.CollectBus.IotSystems.MessageReceiveds; -using JiShe.CollectBus.IotSystems.Protocols; -using JiShe.CollectBus.Protocol.Contracts.Abstracts; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Protocol.Contracts.SendData; using Microsoft.Extensions.Logging; using TouchSocket.Sockets; namespace JiShe.CollectBus.Protocol.Test { - public class TestProtocolPlugin : ProtocolPlugin + public class TestProtocolPlugin : T37612012ProtocolPlugin { private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The service provider. - public TestProtocolPlugin(IServiceProvider serviceProvider, ILogger logger) : base(serviceProvider, logger) + public TestProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger, tcpService) { } - public sealed override ProtocolInfo Info => new(nameof(TestProtocolPlugin), "Test", "TCP", "Test协议", "DTS1980-TEST-01"); + public override ProtocolInfo Info => new(nameof(TestProtocolPlugin), "Test", "TCP", "Test协议", "DTS1980-TEST"); public override Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? receivedAction = null) { throw new NotImplementedException(); } + + public override Task BuildAsync(ProtocolBuildRequest request) + { + throw new NotImplementedException(); + } } } diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin_bak.cs b/protocols/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin_bak.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin_bak.cs rename to protocols/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin_bak.cs diff --git a/protocols/JiShe.CollectBus.Protocol/Abstracts/ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol/Abstracts/ProtocolPlugin.cs new file mode 100644 index 0000000..0bc18d4 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol/Abstracts/ProtocolPlugin.cs @@ -0,0 +1,69 @@ +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.FreeRedis; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using TouchSocket.Sockets; +using Volo.Abp.Domain.Repositories; + +namespace JiShe.CollectBus.Protocol.Contracts.Abstracts +{ + public abstract class ProtocolPlugin : IProtocolPlugin + { + //头部字节长度 + public const int hearderLen = 6; + + public const int tPLen = 6; + + public const string errorData = "EE"; + + private readonly ILogger _logger; + private readonly IRepository _protocolInfoRepository; + private readonly IFreeRedisProvider _redisProvider; + + public ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger) + { + _logger = logger; + _protocolInfoRepository = serviceProvider.GetRequiredService>(); + _redisProvider = serviceProvider.GetRequiredService(); + } + + + public abstract ProtocolInfo Info { get; } + + public virtual async Task GetAsync() => await Task.FromResult(Info); + + public virtual async Task LoadAsync() + { + if (Info == null) + { + throw new ArgumentNullException(nameof(Info)); + } + + await _protocolInfoRepository.DeleteDirectAsync(a => a.Name == Info.Name); + await _protocolInfoRepository.InsertAsync(Info); + await _redisProvider.Instance.HDelAsync($"{RedisConst.ProtocolKey}", Info.Name); + await _redisProvider.Instance.HSetAsync($"{RedisConst.ProtocolKey}", Info.Name, Info); + } + + public abstract Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? receivedAction = null) where T : class; + + #region 下行命令构建 + + /// + /// 组装报文 + /// + /// + /// 设备数据实体 + /// 映射读取执行方法的Code,例如10_1,表示 10H_F1_00000,10H_F1_00001,统一英文下划线分隔 + /// + public abstract Task BuildAsync(ProtocolBuildRequest request); + + #endregion + + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Adapters/StandardFixedHeaderDataHandlingAdapter.cs b/protocols/JiShe.CollectBus.Protocol/Adapters/StandardFixedHeaderDataHandlingAdapter.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Adapters/StandardFixedHeaderDataHandlingAdapter.cs rename to protocols/JiShe.CollectBus.Protocol/Adapters/StandardFixedHeaderDataHandlingAdapter.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisData/Appendix.cs b/protocols/JiShe.CollectBus.Protocol/AnalysisData/Appendix.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisData/Appendix.cs rename to protocols/JiShe.CollectBus.Protocol/AnalysisData/Appendix.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisStrategyContext.cs b/protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs similarity index 83% rename from protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisStrategyContext.cs rename to protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs index 628934a..8a524cc 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisStrategyContext.cs +++ b/protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs @@ -1,10 +1,5 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace JiShe.CollectBus.Protocol.Contracts { diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Attributes/ProtocolNameAttribute.cs b/protocols/JiShe.CollectBus.Protocol/Attributes/ProtocolNameAttribute.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Attributes/ProtocolNameAttribute.cs rename to protocols/JiShe.CollectBus.Protocol/Attributes/ProtocolNameAttribute.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/CollectBusProtocolModule.cs b/protocols/JiShe.CollectBus.Protocol/CollectBusProtocolModule.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/CollectBusProtocolModule.cs rename to protocols/JiShe.CollectBus.Protocol/CollectBusProtocolModule.cs diff --git a/protocols/JiShe.CollectBus.Protocol/Interfaces/IAnalysisStrategy.cs b/protocols/JiShe.CollectBus.Protocol/Interfaces/IAnalysisStrategy.cs new file mode 100644 index 0000000..0066c19 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol/Interfaces/IAnalysisStrategy.cs @@ -0,0 +1,7 @@ +namespace JiShe.CollectBus.Protocol.Interfaces +{ + public interface IAnalysisStrategy + { + Task ExecuteAsync(TInput input); + } +} diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolPlugin.cs similarity index 51% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs rename to protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolPlugin.cs index 326dad0..91eba1a 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs +++ b/protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolPlugin.cs @@ -4,9 +4,10 @@ using JiShe.CollectBus.Common.Models; using JiShe.CollectBus.IotSystems.MessageReceiveds; using JiShe.CollectBus.IotSystems.Protocols; using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.Protocol.Contracts.SendData; using TouchSocket.Sockets; -namespace JiShe.CollectBus.Protocol.Contracts.Interfaces +namespace JiShe.CollectBus.Protocol.Interfaces { public interface IProtocolPlugin { @@ -16,10 +17,12 @@ namespace JiShe.CollectBus.Protocol.Contracts.Interfaces Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null) where T : class; - TB3761? Analysis3761(string messageReceived); - - //Task LoginAsync(MessageReceivedLogin messageReceived); - - //Task HeartbeatAsync(MessageReceivedHeartbeat messageReceived); + /// + /// 组装报文 + /// + /// 是否需要转发的扩展协议入参对象 + /// 映射读取执行方法的Code,例如10_1,表示10H_F1 + /// + Task BuildAsync(ProtocolBuildRequest request); } } diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolService.cs b/protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolService.cs similarity index 94% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolService.cs rename to protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolService.cs index 757457a..fd42f76 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolService.cs +++ b/protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolService.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp; -namespace JiShe.CollectBus.Protocol.Contracts.Interfaces +namespace JiShe.CollectBus.Protocol.Interfaces { public interface IProtocolService { diff --git a/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj b/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj index 3a7cc07..f75b5dd 100644 --- a/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj +++ b/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj @@ -4,24 +4,30 @@ net8.0 enable enable - - preview - - - + + + - - - + + - - - + + + + + + + + + + + + diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/CustomFixedHeaderRequestInfo.cs b/protocols/JiShe.CollectBus.Protocol/Models/CustomFixedHeaderRequestInfo.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/CustomFixedHeaderRequestInfo.cs rename to protocols/JiShe.CollectBus.Protocol/Models/CustomFixedHeaderRequestInfo.cs diff --git a/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildRequest.cs b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildRequest.cs new file mode 100644 index 0000000..31b386b --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildRequest.cs @@ -0,0 +1,30 @@ +using JiShe.CollectBus.Protocol.Contracts.Models; + +namespace JiShe.CollectBus.Protocol.Contracts.SendData +{ + /// + /// 报文构建参数 + /// + public class ProtocolBuildRequest + { + /// + /// 集中器地址 + /// + public required string FocusAddress { get; set; } + + /// + /// 抄读计量点,也就是终端电表对应端口 + /// + public int Pn { get; set; } + + /// + /// 3761协议构建组合功能码 + /// + public required string ItemCode { get; set; } + + /// + /// 集中器转发协议构建构建参数 + /// + public SubProtocolBuildRequest SubProtocolRequest { get; set; } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs new file mode 100644 index 0000000..09afc47 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs @@ -0,0 +1,38 @@ +namespace JiShe.CollectBus.Protocol.Contracts.SendData +{ + /// + /// 报文构建返回结果 + /// + public class ProtocolBuildResponse + { + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } = false; + + /// + /// 帧功能域AFN + /// + public int AFn { get; set;} + + /// + /// 帧功能域FN + /// + public int Fn { get; set; } + + /// + /// 帧序列域SEQ + /// + public int Seq { get; set; } + + /// + /// 地址域A3的主站地址MSA + /// + public int MSA { get; set; } + + /// + /// 报文体 + /// + public byte[] Data { get; set; } + } +} diff --git a/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs b/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs new file mode 100644 index 0000000..c104ea7 --- /dev/null +++ b/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Protocol.Contracts.Models +{ + /// + /// 子协议构建参数 + /// + public class 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.Contracts/QGDW3761Config.cs b/protocols/JiShe.CollectBus.Protocol/QGDW3761Config.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/QGDW3761Config.cs rename to protocols/JiShe.CollectBus.Protocol/QGDW3761Config.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Services/ProtocolService.cs b/protocols/JiShe.CollectBus.Protocol/Services/ProtocolService.cs similarity index 88% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Services/ProtocolService.cs rename to protocols/JiShe.CollectBus.Protocol/Services/ProtocolService.cs index 0c50f6e..c4cf931 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Services/ProtocolService.cs +++ b/protocols/JiShe.CollectBus.Protocol/Services/ProtocolService.cs @@ -1,17 +1,12 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.FreeRedis; using JiShe.CollectBus.IotSystems.Protocols; -using Volo.Abp.DependencyInjection; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using System.Text.RegularExpressions; using Volo.Abp; +using Volo.Abp.DependencyInjection; namespace JiShe.CollectBus.Protocol.Contracts.Services { @@ -19,11 +14,13 @@ namespace JiShe.CollectBus.Protocol.Contracts.Services { private readonly IFreeRedisProvider _freeRedisProvider; private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; - public ProtocolService(IFreeRedisProvider freeRedisProvider, IServiceProvider serviceProvider) + public ProtocolService(IFreeRedisProvider freeRedisProvider, IServiceProvider serviceProvider, ILogger logger) { _freeRedisProvider = freeRedisProvider; _serviceProvider = serviceProvider; + _logger= logger; } /// @@ -61,6 +58,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Services } catch (Exception ex) { + _logger.LogError(ex, "获取协议失败"); return null; } } diff --git a/protocols/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs deleted file mode 100644 index 094f9e8..0000000 --- a/protocols/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs +++ /dev/null @@ -1,390 +0,0 @@ -using DeviceDetectorNET.Parser.Device; -using JiShe.CollectBus.Common.BuildSendDatas; -using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Common.Helpers; -using JiShe.CollectBus.Common.Models; -using JiShe.CollectBus.Enums; -using JiShe.CollectBus.IotSystems.Devices; -using JiShe.CollectBus.IotSystems.MessageReceiveds; -using JiShe.CollectBus.IotSystems.Protocols; -using JiShe.CollectBus.Kafka.Producer; -using JiShe.CollectBus.Protocol.Contracts.Abstracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using TouchSocket.Sockets; -using Volo.Abp.Domain.Repositories; - -namespace JiShe.CollectBus.Protocol -{ - public class StandardProtocolPlugin : ProtocolPlugin - { - private readonly ILogger _logger; - - private readonly IProducerService _producerService; - - private readonly IRepository _deviceRepository; - private readonly ITcpService _tcpService; - - /// - /// Initializes a new instance of the class. - /// - /// The service provider. - public StandardProtocolPlugin(IServiceProvider serviceProvider,ILogger logger, ITcpService tcpService) : base(serviceProvider, logger) - { - _logger = logger; - //_logger = serviceProvider.GetRequiredService>(); - _producerService = serviceProvider.GetRequiredService(); - _deviceRepository = serviceProvider.GetRequiredService>(); - _tcpService = tcpService; - } - - public sealed override ProtocolInfo Info => new(nameof(StandardProtocolPlugin), "376.1", "TCP", "376.1协议", "DTS1980"); - - public override async Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null) - { - TB3761? tB3761 = Analysis3761(messageReceived); - if (tB3761 != null) - { - if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测) - { - if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null) - { - _logger.LogError($"解析AFN.链路接口检测报文失败,报文:{messageReceived},TB3761:{tB3761.Serialize()}"); - } - else - { - if (tB3761.DT?.Fn == (int)FN.登录) - { - // 登录回复 - if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认) - await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); - } - else if (tB3761.DT?.Fn == (int)FN.心跳) - { - // 心跳回复 - //心跳帧有两种情况: - //1. 集中器先有登录帧,再有心跳帧 - //2. 集中器没有登录帧,只有心跳帧 - await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ); - } - } - - } - - } - return (tB3761 as T)!; - } - - - /// - /// 登录回复 - /// - /// - /// - /// - /// - /// - public async Task LoginAsync(ITcpSessionClient client,string messageReceived, string code, int? msa, int? pseq) - { - string oldClientId = $"{client.Id}"; - await client.ResetIdAsync(code); - var deviceInfoList = await _deviceRepository.GetListAsync(a => a.Number == code); - if (deviceInfoList != null && deviceInfoList.Count > 1) - { - //todo 推送集中器编号重复预警 - _logger.LogError($"集中器编号:{code},存在多个集中器,请检查集中器编号是否重复"); - return; - } - - var entity = deviceInfoList?.FirstOrDefault(a => a.Number == code); - if (entity == null) - { - await _deviceRepository.InsertAsync(new Device(code, oldClientId, DateTime.Now, DateTime.Now, DeviceStatus.Online)); - } - else - { - entity.UpdateByLoginAndHeartbeat(oldClientId); - await _deviceRepository.UpdateAsync(entity); - } - - var messageReceivedLoginEvent = new MessageReceivedLogin - { - ClientId = code, - ClientIp = client.IP, - ClientPort = client.Port, - MessageHexString = messageReceived, - DeviceNo = code, - MessageId = Guid.NewGuid().ToString() - }; - - //await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent); - - - await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginReceivedEventName, messageReceivedLoginEvent); - - //await _producerBus.Publish( messageReceivedLoginEvent); - - //var aTuple = (Tuple)messageReceived.StringToPairs().GetAnalyzeValue(CommandChunkEnum.A); - //var seq = (Seq)messageReceived.StringToPairs().GetAnalyzeValue(CommandChunkEnum.SEQ); - var reqParam = new ReqParameter2 - { - AFN = AFN.确认或否认, - FunCode = (int)CFromStationFunCode.链路数据, - PRM = PRM.从动站报文, - A =code, - Seq = new Seq() - { - TpV = TpV.附加信息域中无时间标签, - FIRFIN = FIRFIN.单帧, - CON = CON.需要对该帧进行确认, - PRSEQ = pseq!.Value - }, - MSA = msa!.Value, - Pn = 0, - Fn = 1 - }; - var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); - var issuedEventMessage = new IssuedEventMessage - { - ClientId = messageReceivedLoginEvent.ClientId, - DeviceNo = messageReceivedLoginEvent.DeviceNo, - Message = bytes, Type = IssuedEventType.Login, - MessageId = messageReceivedLoginEvent.MessageId - }; - //await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId }); - if (_tcpService.ClientExists(issuedEventMessage.ClientId)) - { - await _tcpService.SendAsync(issuedEventMessage.ClientId, issuedEventMessage.Message); - _logger.LogInformation($"集中器地址{issuedEventMessage.ClientId} 登录回复下发内容:{Convert.ToHexString(bytes)}"); - await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, issuedEventMessage); - } - - //await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId }); - } - - /// - /// 心跳帧解析 - /// - /// - /// - /// - /// - /// - public async Task HeartbeatAsync(ITcpSessionClient client,string messageReceived, string code, int? msa, int? pseq) - { - - string clientId = code; - string oldClientId = $"{client.Id}"; - var deviceInfoList = await _deviceRepository.GetListAsync(a => a.Number == code); - if (deviceInfoList != null && deviceInfoList.Count > 1) - { - //todo 推送集中器编号重复预警 - _logger.LogError($"集中器编号:{code},存在多个集中器,请检查集中器编号是否重复"); - return; - } - - var entity = deviceInfoList?.FirstOrDefault(a => a.Number == code); - if (entity == null) //没有登录帧的设备,只有心跳帧 - { - await client.ResetIdAsync(clientId); - await _deviceRepository.InsertAsync(new Device(code, oldClientId, DateTime.Now, DateTime.Now, DeviceStatus.Online)); - } - else - { - if (clientId != oldClientId) - { - entity.UpdateByLoginAndHeartbeat(oldClientId); - } - else - { - entity.UpdateByLoginAndHeartbeat(); - } - - await _deviceRepository.UpdateAsync(entity); - } - - var messageReceivedHeartbeatEvent = new MessageReceivedHeartbeat - { - ClientId = clientId, - ClientIp = client.IP, - ClientPort = client.Port, - MessageHexString = messageReceived, - DeviceNo = code, - MessageId = Guid.NewGuid().ToString() - }; - await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatReceivedEventName, messageReceivedHeartbeatEvent); - - var reqParam = new ReqParameter2() - { - AFN = AFN.确认或否认, - FunCode = (int)CFromStationFunCode.链路数据, - PRM = PRM.从动站报文, - A = code, - Seq = new Seq() - { - TpV = TpV.附加信息域中无时间标签, - FIRFIN = FIRFIN.单帧, - CON = CON.不需要对该帧进行确认, - PRSEQ = pseq!.Value, - }, - MSA = msa!.Value, - Pn = 0, - Fn = 1 - }; - var bytes = Build3761SendData.BuildSendCommandBytes(reqParam); - - IssuedEventMessage issuedEventMessage = new IssuedEventMessage - { - ClientId = messageReceivedHeartbeatEvent.ClientId, - DeviceNo = messageReceivedHeartbeatEvent.DeviceNo, - Message = bytes, - Type = IssuedEventType.Heartbeat, - MessageId = messageReceivedHeartbeatEvent.MessageId - }; - if (_tcpService.ClientExists(issuedEventMessage.ClientId)) - { - await _tcpService.SendAsync(issuedEventMessage.ClientId, bytes); - _logger.LogWarning($"集中器地址{issuedEventMessage.ClientId} 心跳回复下发内容:{Convert.ToHexString(bytes)}"); - await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, issuedEventMessage); - } - } - - - - - - - #region 上行命令 - - //68 - //32 00 - //32 00 - //68 - //C9 1100'1001. 控制域C。 - // D7=1, (终端发送)上行方向。 - // D6=1, 此帧来自启动站。 - // D5=0, (上行方向)要求访问位。表示终端无事件数据等待访问。 - // D4=0, 保留 - // D3~D0=9, 功能码。链路测试 - - //20 32 行政区划码 - //90 26 终端地址 - //00 主站地址和组地址标志。终端为单地址。 //3220 09 87 2 - // 终端启动的发送帧的 MSA 应为 0, 其主站响应帧的 MSA 也应为 0. - //02 应用层功能码。AFN=2, 链路接口检测 - //70 0111'0000. 帧序列域。无时间标签、单帧、需要确认。 - //00 00 信息点。DA1和DA2全为“0”时,表示终端信息点。 - //01 00 信息类。F1, 登录。 - //44 帧尾,包含用户区数据校验和 - //16 帧结束标志 - - /// - /// 解析上行命令 - /// - /// - /// - public CommandReulst? AnalysisCmd(string cmd) - { - CommandReulst? commandReulst = null; - var hexStringList = cmd.StringToPairs(); - - if (hexStringList.Count < hearderLen) - { - return commandReulst; - } - //验证起始字符 - if (!hexStringList[0].IsStartStr() || !hexStringList[5].IsStartStr()) - { - return commandReulst; - } - - var lenHexStr = $"{hexStringList[2]}{hexStringList[1]}"; - var lenBin = lenHexStr.HexToBin(); - var len = lenBin.Remove(lenBin.Length - 2).BinToDec(); - //验证长度 - if (hexStringList.Count - 2 != hearderLen + len) - return commandReulst; - - var userDataIndex = hearderLen; - var c = hexStringList[userDataIndex];//控制域 1字节 - userDataIndex += 1; - - var aHexList = hexStringList.Skip(userDataIndex).Take(5).ToList();//地址域 5字节 - var a = AnalysisA(aHexList); - var a3Bin = aHexList[4].HexToBin().PadLeft(8, '0'); - var mSA = a3Bin.Substring(0, 7).BinToDec(); - userDataIndex += 5; - - var aFN = (AFN)hexStringList[userDataIndex].HexToDec();//1字节 - userDataIndex += 1; - - var seq = hexStringList[userDataIndex].HexToBin().PadLeft(8, '0'); - var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1)); - var fIRFIN = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2)); - var cON = (CON)Convert.ToInt32(seq.Substring(3, 1)); - var prseqBin = seq.Substring(4, 4); - userDataIndex += 1; - - // (DA2 - 1) * 8 + DA1 = pn - var da1Bin = hexStringList[userDataIndex].HexToBin(); - var da1 = da1Bin == "0" ? 0 : da1Bin.Length; - userDataIndex += 1; - var da2 = hexStringList[userDataIndex].HexToDec(); - var pn = da2 == 0 ? 0 : (da2 - 1) * 8 + da1; - userDataIndex += 1; - //(DT2*8)+DT1=fn - var dt1Bin = hexStringList[userDataIndex].HexToBin(); - var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0; - userDataIndex += 1; - var dt2 = hexStringList[userDataIndex].HexToDec(); - var fn = dt2 * 8 + dt1; - userDataIndex += 1; - - //数据单元 - var datas = hexStringList.Skip(userDataIndex).Take(len + hearderLen - userDataIndex).ToList(); - - //EC - //Tp - commandReulst = new CommandReulst() - { - A = a, - MSA = mSA, - AFN = aFN, - Seq = new Seq() - { - TpV = tpV, - FIRFIN = fIRFIN, - CON = cON, - PRSEQ = prseqBin.BinToDec(), - }, - CmdLength = len, - Pn = pn, - Fn = fn, - HexDatas = datas - }; - - return commandReulst; - } - - /// - /// 解析地址 - /// - /// - /// - private string AnalysisA(List aHexList) - { - var a1 = aHexList[1] + aHexList[0]; - var a2 = aHexList[3] + aHexList[2]; - var a2Dec = a2.HexToDec(); - var a3 = aHexList[4]; - var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}"; - return a; - } - #endregion - } -} diff --git a/services/JiShe.CollectBus.Application.Contracts/ScheduledMeterReading/IScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application.Contracts/ScheduledMeterReading/IScheduledMeterReadingService.cs index 6dec9db..9d64747 100644 --- a/services/JiShe.CollectBus.Application.Contracts/ScheduledMeterReading/IScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application.Contracts/ScheduledMeterReading/IScheduledMeterReadingService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using JiShe.CollectBus.Ammeters; using JiShe.CollectBus.GatherItem; @@ -72,6 +73,13 @@ namespace JiShe.CollectBus.ScheduledMeterReading /// Task AmmeterScheduledAutoValveControl(); + /// + /// 电表自动校时 + /// + /// 采集频率 + /// + Task AmmeterScheduledAutomaticVerificationTime(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps); + #endregion diff --git a/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAnalysisAppService.cs b/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAnalysisAppService.cs new file mode 100644 index 0000000..ec12ab6 --- /dev/null +++ b/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAnalysisAppService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Subscribers +{ + public interface ISubscriberAnalysisAppService + { + + } +} diff --git a/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAppService.cs b/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAppService.cs index bdc6b78..63594c8 100644 --- a/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAppService.cs +++ b/services/JiShe.CollectBus.Application.Contracts/Subscribers/ISubscriberAppService.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using JiShe.CollectBus.Common.Models; using JiShe.CollectBus.IotSystems.MessageReceiveds; using JiShe.CollectBus.Kafka.Internal; +using JiShe.CollectBus.Protocol3761; using Volo.Abp.Application.Services; namespace JiShe.CollectBus.Subscribers @@ -11,7 +12,7 @@ namespace JiShe.CollectBus.Subscribers { Task LoginIssuedEvent(List issuedEventMessage); Task HeartbeatIssuedEvent(List issuedEventMessage); - Task ReceivedEvent(MessageReceived receivedMessage); + Task ReceivedEvent(MessageProtocolAnalysis receivedMessage); Task ReceivedHeartbeatEvent(List receivedHeartbeatMessage); Task ReceivedLoginEvent(List receivedLoginMessage); } diff --git a/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj index b97fd0f..3ab9831 100644 --- a/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj +++ b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj @@ -22,7 +22,7 @@ - + diff --git a/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs b/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs index e9ec23b..6eadb0a 100644 --- a/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs +++ b/services/JiShe.CollectBus.Application/Plugins/TcpMonitor.cs @@ -1,35 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using DeviceDetectorNET.Parser.Device; -using JiShe.CollectBus.Ammeters; -using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Extensions; -using JiShe.CollectBus.Common.Helpers; -using JiShe.CollectBus.Enums; -using JiShe.CollectBus.Interceptors; -using JiShe.CollectBus.IotSystems.Ammeters; +using JiShe.CollectBus.IotSystems.Ammeters; using JiShe.CollectBus.IotSystems.Devices; -using JiShe.CollectBus.IotSystems.MessageReceiveds; using JiShe.CollectBus.Kafka.Producer; -using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Abstracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; -using JiShe.CollectBus.Protocol.Contracts.Services; -using Microsoft.Extensions.DependencyInjection; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; -using static System.Formats.Asn1.AsnWriter; -using static FreeSql.Internal.GlobalFilter; namespace JiShe.CollectBus.Plugins { @@ -77,13 +58,10 @@ namespace JiShe.CollectBus.Plugins TB3761? tB3761 = await protocolPlugin!.AnalyzeAsync(tcpSessionClient, messageHexString); if (tB3761 == null) { + // TODO: 暂时不处理,后续再处理 _logger.LogError($"指令初步解析失败,指令内容:{messageHexString}"); } - else - { - await OnTcpNormalReceived(tcpSessionClient, messageHexString, tB3761); - } - await e.InvokeNext(); + await e.InvokeNext(); } //[GeneratorPlugin(typeof(ITcpConnectingPlugin))] @@ -124,76 +102,5 @@ namespace JiShe.CollectBus.Plugins await e.InvokeNext(); } - /// - /// 正常帧处理,将不同的AFN进行分发 - /// - /// - /// - /// - /// - private async Task OnTcpNormalReceived(ITcpSessionClient tcpSessionClient,string messageHexString, TB3761? tB3761) - { - //await _producerBus.Publish(new MessageReceived - //{ - // ClientId = client.Id, - // ClientIp = client.IP, - // ClientPort = client.Port, - // MessageHexString = messageHexString, - // DeviceNo = deviceNo, - // MessageId = NewId.NextGuid().ToString() - //}); - - - //string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, aFn); - //todo 如何确定时标?目前集中器的采集频率,都是固定,数据上报的时候,根据当前时间,往后推测出应当采集的时间点作为时标。但是如果由于网络问题,数据一直没上报的情况改怎么计算? - //await _producerBus.PublishAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived - //{ - // ClientId = client.Id, - // ClientIp = client.IP, - // ClientPort = client.Port, - // MessageHexString = messageHexString, - // DeviceNo = deviceNo, - // MessageId = NewId.NextGuid().ToString() - //}); - - if(tB3761?.AFN_FC.BaseHexMessage==null || tB3761.DT.BaseHexMessage == null) - { - _logger.LogError("376.1协议解析AFN失败"); - return; - } - // 登录心跳已做了处理,故需要忽略登录和心跳帧 - //if(tB3761.DT?.Fn == (int)FN.登录 || tB3761.DT?.Fn == (int)FN.心跳) - // return; - - //TODO:根据AFN进行分流推送到kafka - string topicName = string.Format(ProtocolConst.AFNTopicNameFormat, tB3761?.AFN_FC.AFN.ToString().PadLeft(2,'0')); - - List topics = ProtocolConstExtensions.GetAllTopicNamesByReceived(); - - if(topics.Contains(topicName)) - await _producerService.ProduceAsync(topicName, new MessageReceived - { - ClientId = tcpSessionClient.Id, - ClientIp = tcpSessionClient.IP, - ClientPort = tcpSessionClient.Port, - MessageHexString = messageHexString, - DeviceNo = tB3761?.A?.Code!, - MessageId = Guid.NewGuid().ToString() - }); - else - { - _logger.LogError($"不支持的上报kafka主题:{topicName}"); - await _producerService.ProduceAsync(ProtocolConst.SubscriberReceivedEventName, new MessageReceived - { - ClientId = tcpSessionClient.Id, - ClientIp = tcpSessionClient.IP, - ClientPort = tcpSessionClient.Port, - MessageHexString = messageHexString, - DeviceNo = tB3761?.A?.Code!, - MessageId = Guid.NewGuid().ToString() - }); - } - - } } } diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index 63566bf..31a3494 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -10,11 +10,11 @@ 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.PrepayModel; using JiShe.CollectBus.Kafka.Attributes; using JiShe.CollectBus.Kafka.Internal; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; @@ -24,7 +24,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; -using JiShe.CollectBus.IotSystems.Ammeters; namespace JiShe.CollectBus.Samples; diff --git a/services/JiShe.CollectBus.Application/Samples/TestAppService.cs b/services/JiShe.CollectBus.Application/Samples/TestAppService.cs index f5f2e6b..1975d5a 100644 --- a/services/JiShe.CollectBus.Application/Samples/TestAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/TestAppService.cs @@ -1,35 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Apache.IoTDB.DataStructure; -using Apache.IoTDB; -using Confluent.Kafka; -using JiShe.CollectBus.Ammeters; -using JiShe.CollectBus.FreeSql; -using JiShe.CollectBus.IotSystems.PrepayModel; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Logging; -using JiShe.CollectBus.Common.Helpers; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using Microsoft.Extensions.DependencyInjection; +using Cassandra; using JiShe.CollectBus.Cassandra; using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.DynamicModule; +using JiShe.CollectBus.Interceptors; using JiShe.CollectBus.IotSystems.MessageIssueds; -using Volo.Abp.Application.Services; -using JiShe.CollectBus.IotSystems.MessageReceiveds; -using Volo.Abp.Domain.Repositories; +using JiShe.CollectBus.IotSystems.Protocols; +using JiShe.CollectBus.Protocol.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; -using Cassandra; -using JiShe.CollectBus.Interceptors; -using JiShe.CollectBus.IotSystems.Protocols; -using TouchSocket.Core; +using System.Threading.Tasks; using Volo.Abp.Modularity; -using JiShe.CollectBus.DynamicModule; namespace JiShe.CollectBus.Samples; diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs index f50d121..2b0df9e 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Application.Contracts; -using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.DeviceBalanceControl; using JiShe.CollectBus.Common.Encrypt; @@ -18,8 +18,9 @@ using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.IotSystems.Watermeter; using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Producer; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using Microsoft.Extensions.DependencyInjection; +using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; @@ -40,9 +41,10 @@ namespace JiShe.CollectBus.ScheduledMeterReading private readonly IProducerService _producerService; private readonly IRedisDataCacheService _redisDataCacheService; private readonly KafkaOptionConfig _kafkaOptions; + private readonly ServerApplicationOptions _applicationOptions; private readonly IoTDBRuntimeContext _runtimeContext; - private readonly IServiceProvider _serviceProvider; - + private readonly IProtocolService _protocolService; + int pageSize = 3000; public BasicScheduledMeterReadingService( @@ -51,8 +53,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading IRedisDataCacheService redisDataCacheService, IIoTDbProvider dbProvider, IoTDBRuntimeContext runtimeContext, - IServiceProvider serviceProvider, - IOptions kafkaOptions) + IProtocolService protocolService, + IOptions kafkaOptions, + IOptions applicationOptions) { _logger = logger; _dbProvider = dbProvider; @@ -60,7 +63,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading _producerService = producerService; _redisDataCacheService = redisDataCacheService; _kafkaOptions = kafkaOptions.Value; - _serviceProvider = serviceProvider; + _applicationOptions = applicationOptions.Value; + _protocolService = protocolService; _runtimeContext.UseTableSessionPool = true; } @@ -109,6 +113,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading } var currentTime = DateTime.Now; + + //定时抄读 foreach (var item in taskInfos) { var tasksToBeIssueModel = await FreeRedisProvider.Instance.GetAsync(item); @@ -127,6 +133,27 @@ namespace JiShe.CollectBus.ScheduledMeterReading timeDensity = 15; } + + //电表定时广播校时,一天一次。 + string currentTimeStr = $"{currentTime:HH:mm:00}"; + //判断是否是自动校时时间 + if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase)) + { + _logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间"); + return; + } + else + { + _ = CreateMeterPublishTask( + timeDensity: timeDensity, + nextTaskTime: currentTime, + meterType: MeterTypeEnum.Ammeter, + taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => + { + await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps); + }); + } + //检查任务时间节点,由于定时任务10秒钟运行一次,需要判定当前时间是否在任务时间节点内,不在则跳过 if (!IsTaskTime(tasksToBeIssueModel.NextTaskTime, timeDensity)) { @@ -145,15 +172,15 @@ namespace JiShe.CollectBus.ScheduledMeterReading timeDensity: timeDensity, nextTaskTime: currentTaskTime, meterType: MeterTypeEnum.Ammeter, - taskCreateAction: (timeDensity, data, groupIndex, timestamps) => + taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => { - var tempTask = AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps); + var tempTask = await AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps); if (tempTask == null || tempTask.Count <= 0) { _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}"); return; } - _dbProvider.BatchInsertAsync(metadata, tempTask); + _ = _dbProvider.BatchInsertAsync(metadata, tempTask); }); } else if (meteryType == MeterTypeEnum.WaterMeter.ToString()) @@ -163,16 +190,16 @@ namespace JiShe.CollectBus.ScheduledMeterReading timeDensity: timeDensity, nextTaskTime: currentTaskTime, meterType: MeterTypeEnum.WaterMeter, - taskCreateAction: (timeDensity, data, groupIndex, timestamps) => + taskCreateAction: async (timeDensity, data, groupIndex, timestamps) => { - var tempTask = WatermeterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps); + var tempTask = await WatermeterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps); if (tempTask == null || tempTask.Count <= 0) { _logger.LogWarning($"水表 {data.Name} 任务数据构建失败:{data.Serialize()}"); return; } - _dbProvider.BatchInsertAsync(metadata, tempTask); + _ = _dbProvider.BatchInsertAsync(metadata, tempTask); }); } else @@ -187,8 +214,12 @@ namespace JiShe.CollectBus.ScheduledMeterReading //根据当前的采集频率和类型,重新更新下一个任务点,把任务的创建源固定在当前逻辑,避免任务处理的逻辑异常导致任务创建失败。 tasksToBeIssueModel.LastTaskTime = currentTaskTime; tasksToBeIssueModel.NextTaskTime = currentTaskTime.CalculateNextCollectionTime(timeDensity); - await FreeRedisProvider.Instance.SetAsync(item, tasksToBeIssueModel); + await FreeRedisProvider.Instance.SetAsync(item, tasksToBeIssueModel); } + + //电表定时阀控任务处理。 + _= AmmeterScheduledAutoValveControl(); + } #region 电表采集处理 @@ -275,9 +306,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading //根据采集频率分组,获得采集频率分组 var meterInfoGroupByTimeDensity = meterInfos.GroupBy(d => d.TimeDensity); - if (_kafkaOptions.FirstCollectionTime.HasValue == false) + if (_applicationOptions.FirstCollectionTime.HasValue == false) { - _kafkaOptions.FirstCollectionTime = DateTime.Now; + _applicationOptions.FirstCollectionTime = DateTime.Now; } //先处理采集频率任务缓存 foreach (var item in meterInfoGroupByTimeDensity) @@ -286,7 +317,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading { LastTaskTime = null, TimeDensity = item.Key, - NextTaskTime = _kafkaOptions.FirstCollectionTime.Value.CalculateNextCollectionTime(item.Key),//使用首次采集时间作为下一次采集时间 + NextTaskTime = _applicationOptions.FirstCollectionTime.Value.CalculateNextCollectionTime(item.Key),//使用首次采集时间作为下一次采集时间 }; //todo 首次采集时间节点到目前运行时间中漏采的时间点,可以考虑使用IoTDB的存储,利用时间序列处理。 @@ -500,11 +531,20 @@ namespace JiShe.CollectBus.ScheduledMeterReading /// 集中器所在分组 /// 采集频率对应的时间戳 /// - private List AmmerterCreatePublishTaskAction(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps) + private async Task> AmmerterCreatePublishTaskAction(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps) { var currentTime = DateTime.Now; - var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary; + //根据电表型号获取协议插件 + var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType); + if (protocolPlugin == null) + { + //_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105"); + //return; + } + + + //todo 检查需要待补抄的电表的时间点信息,保存到需要待补抄的缓存中。如果此线程异常,该如何补偿? if (string.IsNullOrWhiteSpace(ammeterInfo.ItemCodes)) @@ -601,43 +641,18 @@ namespace JiShe.CollectBus.ScheduledMeterReading continue; } - var itemCodeArr = tempItem.Split('_'); - var aFNStr = itemCodeArr[0]; - var aFN = (AFN)aFNStr.HexToDec(); - var fn = int.Parse(itemCodeArr[1]); - TelemetryPacketResponse builderResponse = null; - if (ammeterInfo.AutomaticReport.Equals(1) && aFN == AFN.请求实时数据) - { - //实时数据 - builderResponse = TelemetryPacketBuilder.AFN0C_Fn_Send(new TelemetryPacketRequest() - { - FocusAddress = ammeterInfo.FocusAddress, - Fn = fn, - Pn = ammeterInfo.MeteringCode - }); - } - else - { - string methonCode = $"AFN{aFNStr}_Fn_Send"; - //特殊表暂不处理 - if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode - , out var handler)) - { - builderResponse = handler(new TelemetryPacketRequest() - { - FocusAddress = ammeterInfo.FocusAddress, - Fn = fn, - Pn = ammeterInfo.MeteringCode - }); - } - else - { - _logger.LogWarning($"{nameof(AmmerterCreatePublishTaskAction)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}无效编码。"); - continue; - } - } - //TODO:特殊表 + //var itemCodeArr = tempItem.Split('_'); + //var aFNStr = itemCodeArr[0]; + //var aFN = (AFN)aFNStr.HexToDec(); + //var fn = int.Parse(itemCodeArr[1]); + //TODO:特殊表 + ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() + { + FocusAddress = ammeterInfo.FocusAddress, + Pn = ammeterInfo.MeteringCode, + ItemCode = tempItem, + }); if (builderResponse == null || builderResponse.Data.Length <= 0) { //_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。"); @@ -645,7 +660,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading } - string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, ammeterInfo.MeteringCode, builderResponse.MSA); + string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, ammeterInfo.MeteringCode, builderResponse.MSA, builderResponse.Seq); var meterReadingRecords = new MeterReadingTelemetryPacketInfo() { SystemName = SystemType, @@ -657,9 +672,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading PendingCopyReadTime = timestamps, CreationTime = currentTime, MeterAddress = ammeterInfo.AmmerterAddress, - AFN = (int)aFN, - Fn = fn, - //Seq = builderResponse.Seq, + AFN = builderResponse.AFn, + Fn = builderResponse.Fn, + Seq = builderResponse.Seq, MSA = builderResponse.MSA, ItemCode = tempItem, TaskMark = taskMark, @@ -697,6 +712,110 @@ namespace JiShe.CollectBus.ScheduledMeterReading throw new NotImplementedException($"{nameof(AmmeterScheduledAutoValveControl)}请根据不同系统类型进行实现"); } + /// + /// 电表自动校时 + /// + /// 采集频率 + /// 电表信息 + /// 集中器所在分组 + /// 采集频率对应的时间戳 + /// + public virtual async Task AmmeterScheduledAutomaticVerificationTime(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps) + { + var currentTime = DateTime.Now; + string currentTimeStr = $"{currentTime:HH:mm:00}"; + + try + { + //判断是否是自动校时时间 + if (!string.Equals(currentTimeStr , _applicationOptions.AutomaticVerificationTime,StringComparison.CurrentCultureIgnoreCase)) + { + _logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间"); + return; + } + + List taskList = new List(); + var metadata = await _dbProvider.GetMetadata(); + + var temCode = "10_01"; + + //根据电表型号获取协议插件 + var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType); + if (protocolPlugin == null) + { + _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105"); + return; + } + + ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() + { + FocusAddress = ammeterInfo.FocusAddress, + Pn = ammeterInfo.MeteringCode, + ItemCode = temCode, + SubProtocolRequest = new SubProtocolBuildRequest() + { + MeterAddress = ammeterInfo.AmmerterAddress, + Password = ammeterInfo.Password, + ItemCode = T6452007PacketItemCodeConst.C08, + } + }); + + string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, ammeterInfo.MeteringCode, builderResponse.MSA, builderResponse.Seq); + var meterReadingRecords = new MeterReadingTelemetryPacketInfo() + { + SystemName = SystemType, + ProjectId = $"{ammeterInfo.ProjectID}", + DeviceType = $"{MeterTypeEnum.Ammeter}", + DeviceId = $"{ammeterInfo.MeterId}", + Timestamps = currentTime.GetDateTimeOffset().ToUnixTimeNanoseconds(), + DatabaseBusiID = ammeterInfo.DatabaseBusiID, + PendingCopyReadTime = currentTime, + CreationTime = currentTime, + MeterAddress = ammeterInfo.AmmerterAddress, + AFN = builderResponse.AFn, + Fn = builderResponse.Fn, + Seq = builderResponse.Seq, + MSA = builderResponse.MSA, + ItemCode = temCode, + TaskMark = taskMark, + IsSend = false, + ManualOrNot = false, + Pn = ammeterInfo.MeteringCode, + IssuedMessageId = GuidGenerator.Create().ToString(), + IssuedMessageHexString = Convert.ToHexString(builderResponse.Data), + IsReceived = false, + ScoreValue = $"{ammeterInfo.FocusAddress}.{taskMark}".Md5Fun(), + }; + taskList.Add(meterReadingRecords); + + if (taskList == null || taskList.Count <= 0) + { + _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有自动阀控任务生成,-106"); + return; + } + + //任务记录入库 + await _dbProvider.BatchInsertAsync(metadata, taskList); + + //任务信息推送Kafka + _ = DeviceGroupBalanceControl.ProcessWithThrottleAsync( + items: taskList, + deviceIdSelector: data => data.DeviceId, + processor: (data, groupIndex) => + { + _ = KafkaProducerIssuedMessageAction(ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, data, groupIndex); + } + ); + + //todo 阀控记录入库,推送到新的服务 + } + catch (Exception) + { + + throw; + } + } + #endregion @@ -736,9 +855,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading //根据采集频率分组,获得采集频率分组 var meterInfoGroupByTimeDensity = meterInfos.GroupBy(d => d.TimeDensity); - if (_kafkaOptions.FirstCollectionTime.HasValue == false) + if (_applicationOptions.FirstCollectionTime.HasValue == false) { - _kafkaOptions.FirstCollectionTime = DateTime.Now; + _applicationOptions.FirstCollectionTime = DateTime.Now; } //先处理采集频率任务缓存 @@ -748,7 +867,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading { LastTaskTime = null, TimeDensity = item.Key, - NextTaskTime = _kafkaOptions.FirstCollectionTime.Value.CalculateNextCollectionTime(item.Key),//使用首次采集时间作为下一次采集时间 + NextTaskTime = _applicationOptions.FirstCollectionTime.Value.CalculateNextCollectionTime(item.Key),//使用首次采集时间作为下一次采集时间 }; //todo 首次采集时间节点到目前运行时间中漏采的时间点,可以考虑使用IoTDB的存储,利用时间序列处理。 @@ -851,10 +970,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading /// 集中器所在分组 /// 时间格式的任务批次名称 /// - private List WatermeterCreatePublishTaskAction(int timeDensity + private async Task> WatermeterCreatePublishTaskAction(int timeDensity , WatermeterInfo watermeter, int groupIndex, DateTime timestamps) { - var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary; var currentTime = DateTime.Now; string typeName; @@ -912,10 +1030,12 @@ namespace JiShe.CollectBus.ScheduledMeterReading tempCodes = new List() { "10_1" }; } - var protocolPlugin = _serviceProvider.GetKeyedService("StandardProtocolPlugin"); + //根据表型号获取协议插件 + var protocolPlugin = await _protocolService.GetProtocolServiceAsync(watermeter.Code); if (protocolPlugin == null) { - _logger.LogError("协议不存在!"); + //_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105"); + //return; } foreach (var tempItem in tempCodes) @@ -931,39 +1051,57 @@ namespace JiShe.CollectBus.ScheduledMeterReading continue; } - var itemCodeArr = tempItem.Split('_'); - var aFNStr = itemCodeArr[0]; - var aFN = (AFN)aFNStr.HexToDec(); - var fn = int.Parse(itemCodeArr[1]); - TelemetryPacketResponse builderResponse = null; + //var itemCodeArr = tempItem.Split('_'); + //var aFNStr = itemCodeArr[0]; + //var aFN = (AFN)aFNStr.HexToDec(); + //var fn = int.Parse(itemCodeArr[1]); + //TelemetryPacketResponse builderResponse = null; - string methonCode = $"AFN{aFNStr}_Fn_Send"; - //特殊表暂不处理 - if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode - , out var handler)) + //string methonCode = $"AFN{aFNStr}_Fn_Send"; + ////特殊表暂不处理 + //if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode + // , out var handler)) + //{ + // builderResponse = handler(new TelemetryPacketRequest() + // { + // FocusAddress = watermeter.FocusAddress, + // Fn = fn, + // Pn = watermeter.MeteringCode, + // DataUnit = Build188SendData.Build188WaterMeterReadingSendDataUnit(watermeter.Address), + // }); + //} + //else + //{ + // _logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name}采集项{tempItem}无效编码。"); + // continue; + //} + + ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() { - builderResponse = handler(new TelemetryPacketRequest() + FocusAddress = watermeter.FocusAddress, + Pn = watermeter.MeteringCode, + ItemCode = tempItem, + SubProtocolRequest = new SubProtocolBuildRequest() { - FocusAddress = watermeter.FocusAddress, - Fn = fn, - Pn = watermeter.MeteringCode, - DataUnit = Build188SendData.Build188WaterMeterReadingSendDataUnit(watermeter.Address), - }); - } - else + MeterAddress = watermeter.MeterAddress, + Password = watermeter.Password, + ItemCode = tempItem, + } + }); + if (builderResponse == null || builderResponse.Data.Length <= 0) { - _logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的电表{watermeter.Name}采集项{tempItem}无效编码。"); + //_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。"); continue; } if (builderResponse == null || builderResponse.Data.Length <= 0) { - _logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的电表{watermeter.Name}采集项{tempItem}未能正确获取报文。"); + _logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name}采集项{tempItem}未能正确获取报文。"); continue; } - string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, watermeter.MeteringCode, builderResponse.MSA); + string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, watermeter.MeteringCode, builderResponse.MSA, builderResponse.Seq); var meterReadingRecords = new MeterReadingTelemetryPacketInfo() { SystemName = SystemType, @@ -975,9 +1113,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading PendingCopyReadTime = timestamps, CreationTime = currentTime, MeterAddress = watermeter.MeterAddress, - AFN = (int)aFN, - Fn = fn, - //Seq = builderResponse.Seq, + AFN = builderResponse.AFn, + Fn = builderResponse.Fn, + Seq = builderResponse.Seq, MSA = builderResponse.MSA, ItemCode = tempItem, TaskMark = taskMark, @@ -1102,8 +1240,6 @@ namespace JiShe.CollectBus.ScheduledMeterReading bool hasNext; var stopwatch = Stopwatch.StartNew(); - var ddd = _runtimeContext.UseTableSessionPool; - do { options.PageIndex = pageNumber++; diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs index 82e9588..da0854d 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs @@ -1,5 +1,5 @@ using JiShe.CollectBus.Application.Contracts; -using JiShe.CollectBus.Common.BuildSendDatas; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.DeviceBalanceControl; using JiShe.CollectBus.Common.Encrypt; @@ -15,9 +15,10 @@ using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.IotSystems.Watermeter; using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Producer; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.Protocol.Contracts.SendData; +using JiShe.CollectBus.Protocol.Interfaces; using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; @@ -38,28 +39,30 @@ namespace JiShe.CollectBus.ScheduledMeterReading string serverTagName = string.Empty; private readonly ILogger _logger; private readonly IIoTDbProvider _dbProvider; - private readonly IServiceProvider _serviceProvider; + private readonly IProtocolService _protocolService; public EnergySystemScheduledMeterReadingService( ILogger logger, IIoTDbProvider dbProvider, IOptions kafkaOptions, + IOptions applicationOptions, IoTDBRuntimeContext runtimeContext, IProducerService producerService, - IServiceProvider serviceProvider, + IProtocolService protocolService, IRedisDataCacheService redisDataCacheService) : base(logger, producerService, redisDataCacheService, dbProvider, runtimeContext, - serviceProvider, - kafkaOptions) + protocolService, + kafkaOptions, + applicationOptions) { - serverTagName = kafkaOptions.Value.ServerTagName; + serverTagName = applicationOptions.Value.ServerTagName; _dbProvider = dbProvider; _logger = logger; - _serviceProvider = serviceProvider; + _protocolService = protocolService; } public sealed override string SystemType => SystemTypeConst.Energy; @@ -179,13 +182,12 @@ namespace JiShe.CollectBus.ScheduledMeterReading /// public override async Task AmmeterScheduledAutoValveControl() { - var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary; - var currentTime = DateTime.Now; string currentTimeStr = $"{currentTime:HH:mm}"; try { + //获取电表阀控配置 var settingInfos = await GetAmmeterAutoValveControlSetting(currentTimeStr); if (settingInfos == null || settingInfos.Count <= 0) @@ -198,7 +200,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading var ammeterInfos = new List(); List taskList = new List(); var metadata = await _dbProvider.GetMetadata(); - + foreach (var settingInfo in settingInfos) { bool isGenerate = false; @@ -226,16 +228,22 @@ namespace JiShe.CollectBus.ScheduledMeterReading //获取对应的缓存电表信息 var ammeterInfo = ammeterInfos.First(); bool tripStateResult = false; + string subItemCode = string.Empty; if (settingInfo.TripType.Equals("on")) { ammeterInfo.TripState = 0; tripStateResult = true; + subItemCode = T6452007PacketItemCodeConst.C1C01C; + if (ammeterInfo.TypeName != 1) + { + subItemCode = T6452007PacketItemCodeConst.C1C01B; + } } else if (settingInfo.TripType.Equals("off")) { ammeterInfo.TripState = 1; tripStateResult = false; - + subItemCode = T6452007PacketItemCodeConst.C1C01A; } else { @@ -243,44 +251,30 @@ namespace JiShe.CollectBus.ScheduledMeterReading continue; } - var protocolPlugin = _serviceProvider.GetKeyedService("StandardProtocolPlugin"); + var temCode = "10_01_"; + + //根据电表型号获取协议插件 + var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType); if (protocolPlugin == null) { - _logger.LogError("协议不存在!"); + _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105"); + return; } - var temCode = "10_98"; - var itemCodeArr = temCode.Split('_'); - var aFNStr = itemCodeArr[0]; - var aFN = (AFN)(aFNStr.HexToDec()); - var fn = int.Parse(itemCodeArr[1]); - TelemetryPacketResponse builderResponse = null; - string methonCode = $"AFN{aFNStr}_Fn_Send"; - //特殊表暂不处理 - if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode - , out var handler)) + ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest() { - builderResponse = handler(new TelemetryPacketRequest() + FocusAddress = ammeterInfo.FocusAddress, + Pn = ammeterInfo.MeteringCode, + ItemCode = temCode, + SubProtocolRequest = new SubProtocolBuildRequest() { - FocusAddress = ammeterInfo.FocusAddress, - Fn = fn, - Pn = ammeterInfo.MeteringCode, - DataUnit = Build645SendData.BuildAmmeterValveControlSendDataUnit(ammeterInfo.AmmerterAddress, "", ammeterInfo.Password, tripStateResult),//生成阀控报文 - }); - } - else - { - _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{temCode}无效编码,-103"); - continue; - } + MeterAddress = ammeterInfo.AmmerterAddress, + Password = ammeterInfo.Password, + ItemCode = subItemCode, + } + }); - if (builderResponse == null) - { - _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{temCode}报文构建失败,-104"); - continue; - } - - string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, ammeterInfo.MeteringCode, builderResponse.MSA); + string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, ammeterInfo.MeteringCode, builderResponse.MSA, builderResponse.Seq); var meterReadingRecords = new MeterReadingTelemetryPacketInfo() { SystemName = SystemType, @@ -292,9 +286,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading PendingCopyReadTime = currentTime, CreationTime = currentTime, MeterAddress = ammeterInfo.AmmerterAddress, - AFN = (int)aFN, - Fn = fn, - //Seq = builderResponse.Seq, + AFN = builderResponse.AFn, + Fn = builderResponse.Fn, + Seq = builderResponse.Seq, MSA = builderResponse.MSA, ItemCode = temCode, TaskMark = taskMark, @@ -310,12 +304,12 @@ namespace JiShe.CollectBus.ScheduledMeterReading } if (taskList == null || taskList.Count <= 0) { - _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有自动阀控任务生成,-105"); + _logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有自动阀控任务生成,-106"); return; } //任务记录入库 - _ = _dbProvider.BatchInsertAsync(metadata, taskList); + await _dbProvider.BatchInsertAsync(metadata, taskList); //任务信息推送Kafka _ = DeviceGroupBalanceControl.ProcessWithThrottleAsync( @@ -334,9 +328,6 @@ namespace JiShe.CollectBus.ScheduledMeterReading throw; } - - - throw new NotImplementedException($"{nameof(GetAmmeterInfoList)}请根据不同系统类型进行实现"); } /// diff --git a/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs new file mode 100644 index 0000000..990ff51 --- /dev/null +++ b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAnalysisAppService.cs @@ -0,0 +1,79 @@ +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Helpers; +using JiShe.CollectBus.IoTDB.Interface; +using JiShe.CollectBus.IotSystems.MessageReceiveds; +using JiShe.CollectBus.Kafka.Attributes; +using JiShe.CollectBus.Kafka.Internal; +using JiShe.CollectBus.Protocol.Contracts; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; +using JiShe.CollectBus.Repository.MeterReadingRecord; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using TouchSocket.Sockets; + +namespace JiShe.CollectBus.Subscribers +{ + public class SubscriberAnalysisAppService : CollectBusAppService, ISubscriberAnalysisAppService, IKafkaSubscribe + { + private readonly ILogger _logger; + private readonly ITcpService _tcpService; + private readonly IServiceProvider _serviceProvider; + private readonly IMeterReadingRecordRepository _meterReadingRecordsRepository; + private readonly IIoTDbProvider _dbProvider; + private readonly IProtocolService _protocolService; + + public SubscriberAnalysisAppService(ILogger logger, + ITcpService tcpService, + IServiceProvider serviceProvider, + IIoTDbProvider dbProvider, + IMeterReadingRecordRepository meterReadingRecordsRepository, IProtocolService protocolService) + { + _logger = logger; + _tcpService = tcpService; + _serviceProvider = serviceProvider; + _meterReadingRecordsRepository = meterReadingRecordsRepository; + _dbProvider = dbProvider; + _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"); + + //var data = await analysisStrategy.ExecuteAsync>(tB3761); + var executor = _serviceProvider.GetRequiredService(); + await executor.ExecuteAsync(serverName, receivedMessage.Data); + } + + return SubscribeAck.Fail(); + } + + } +} diff --git a/services/JiShe.CollectBus.Application/Subscribers/SubscriberAppService.cs b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAppService.cs index 5b3b6a0..a082551 100644 --- a/services/JiShe.CollectBus.Application/Subscribers/SubscriberAppService.cs +++ b/services/JiShe.CollectBus.Application/Subscribers/SubscriberAppService.cs @@ -1,31 +1,22 @@ using JiShe.CollectBus.Common.Consts; using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Common.Models; -using JiShe.CollectBus.IotSystems.Devices; +using JiShe.CollectBus.Interceptors; +using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IotSystems.MessageReceiveds; using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.Kafka.Attributes; -using JiShe.CollectBus.Protocol.Contracts; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.Kafka.Internal; +using JiShe.CollectBus.Protocol.Interfaces; +using JiShe.CollectBus.Protocol3761; using JiShe.CollectBus.Repository.MeterReadingRecord; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; -using System.Linq; +using System.Collections.Generic; using System.Threading.Tasks; -using JiShe.CollectBus.IoTDB.Interface; using TouchSocket.Sockets; using Volo.Abp.Domain.Repositories; -using System.Collections.Generic; -using JiShe.CollectBus.Interceptors; -using JiShe.CollectBus.Kafka.Internal; -using JiShe.CollectBus.IoTDB.Provider; -using JiShe.CollectBus.Protocol.Dto; -using System.Collections; -using JiShe.CollectBus.Interfaces; -using System.CodeDom.Compiler; namespace JiShe.CollectBus.Subscribers { @@ -112,7 +103,7 @@ namespace JiShe.CollectBus.Subscribers } [KafkaSubscribe(ProtocolConst.SubscriberReceivedEventName)] - public async Task ReceivedEvent(MessageReceived receivedMessage) + public async Task ReceivedEvent(MessageProtocolAnalysis receivedMessage) { var currentTime = Clock.Now; @@ -124,24 +115,24 @@ namespace JiShe.CollectBus.Subscribers else { //todo 会根据不同的协议进行解析,然后做业务处理 - TB3761? tB3761 = protocolPlugin.Analysis3761(receivedMessage.MessageHexString); - if (tB3761 == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (tB3761.DT == null || tB3761.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } + //TB3761? tB3761 = protocolPlugin.Analysis3761(receivedMessage.MessageHexString); + //if (tB3761 == null) + //{ + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + //} + //if (tB3761.DT == null || tB3761.AFN_FC == null) + //{ + // Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); + // return SubscribeAck.Success(); + //} //报文入库 var entity = new MeterReadingRecords() { ReceivedMessageHexString = receivedMessage.MessageHexString, - AFN = (AFN)tB3761.AFN_FC.AFN, - Fn = tB3761.DT.Fn, + AFN = (AFN)receivedMessage.Data?.AFN_FC.AFN!, + Fn = receivedMessage.Data.DT.Fn, Pn = 0, FocusAddress = "", MeterAddress = "", @@ -169,7 +160,6 @@ namespace JiShe.CollectBus.Subscribers public async Task ReceivedHeartbeatEvent(List receivedHeartbeatMessages) { await _messageReceivedHeartbeatEventRepository.InsertManyAsync(receivedHeartbeatMessages); - return SubscribeAck.Success(); } @@ -180,40 +170,5 @@ namespace JiShe.CollectBus.Subscribers return SubscribeAck.Success(); } - - //[KafkaSubscribe(ProtocolConst.SubscriberAFN02HReceivedEventNameTemp)] - public async Task ReceivedAFN00Event(MessageReceived receivedMessage) - { - - var protocolPlugin = _serviceProvider.GetKeyedService("StandardProtocolPlugin"); - if (protocolPlugin == null) - { - _logger.LogError("协议不存在!"); - } - else - { - TB3761? tB3761 = protocolPlugin.Analysis3761(receivedMessage.MessageHexString); - if (tB3761 == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - if (tB3761.DT == null || tB3761.AFN_FC == null) - { - Logger.LogError($"数据解析失败:{receivedMessage.Serialize()}"); - return SubscribeAck.Success(); - } - string serverName = $"AFN{tB3761.AFN_FC.AFN}_F{tB3761.DT.Fn}_Analysis"; - //var analysisStrategy = _serviceProvider.GetKeyedService($"AFN0_F1_Analysis"); - - //var data = await analysisStrategy.ExecuteAsync>(tB3761); - var executor = _serviceProvider.GetRequiredService(); - bool isSucces= await executor.ExecuteAsync("AFN0_F1_Analysis", tB3761); - } - - return SubscribeAck.Fail(); - } - - } } diff --git a/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs b/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs index fa90fed..e34c087 100644 --- a/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs +++ b/services/JiShe.CollectBus.Application/Subscribers/WorkerSubscriberAppService.cs @@ -82,6 +82,7 @@ namespace JiShe.CollectBus.Subscribers [KafkaSubscribe(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName)] public async Task AmmeterScheduledAutoValveControl(MeterReadingTelemetryPacketInfo receivedMessage) { + //todo 如果是时段自动阀控,需要检查当前的时间,如果时间在自动阀控时间段内,则发送自动阀控报文,否则不发送,尤其是消息队列阻塞或者延时过长的时候。以免造成生产事故。 _logger.LogInformation("电表自动阀控下行消息消费队列开始处理"); return await SendMessagesAsync(receivedMessage); } diff --git a/services/JiShe.CollectBus.Domain/IotSystems/MessageReceiveds/MessageReceived.cs b/services/JiShe.CollectBus.Domain/IotSystems/MessageReceiveds/MessageReceived.cs index 4fad589..f194d00 100644 --- a/services/JiShe.CollectBus.Domain/IotSystems/MessageReceiveds/MessageReceived.cs +++ b/services/JiShe.CollectBus.Domain/IotSystems/MessageReceiveds/MessageReceived.cs @@ -50,4 +50,9 @@ namespace JiShe.CollectBus.IotSystems.MessageReceiveds public DateTime? AckTime { get; set; } } + + public class MessageProtocolAnalysis : MessageReceived + { + public T Data { get; set; } = default!; + } } diff --git a/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs index 07b5369..e39b2bd 100644 --- a/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs +++ b/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs @@ -104,10 +104,10 @@ namespace JiShe.CollectBus.IotSystems.MeterReadingRecords [FIELDColumn] public string ItemCode { get; set; } - ///// - ///// 帧序列域SEQ - ///// - //public required Seq Seq { get; set; } + /// + /// 帧序列域 SEQ + /// + public int Seq { get; set; } /// /// 地址域A3的主站地址MSA diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F10_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN10_F10_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F10_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN10_F10_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F66_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN10_F66_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F66_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN10_F66_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F129_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F129_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F129_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F129_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F130_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F130_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F130_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F130_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F131_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F131_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F131_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F131_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F132_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F132_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F132_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F132_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F145_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F145_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F145_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F145_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F149_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F149_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F149_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F149_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F188_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F188_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F188_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F188_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F25_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F25_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F25_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F25_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F2_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F2_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F2_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F2_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F33_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F33_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F33_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F33_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F49_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F49_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F49_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN12_F49_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN9_F1_AnalysisDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN9_F1_AnalysisDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN9_F1_AnalysisDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AFN9_F1_AnalysisDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AnalysisBaseDto.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/AnalysisBaseDto.cs similarity index 100% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AnalysisBaseDto.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/AnalysisBaseDto.cs diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/UnitDataAnalysis.cs b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/UnitDataAnalysis.cs similarity index 70% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/UnitDataAnalysis.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/Dto/UnitDataAnalysis.cs index 3a03923..d10594b 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/UnitDataAnalysis.cs +++ b/services/JiShe.CollectBus.Domain/Protocol3761/Dto/UnitDataAnalysis.cs @@ -5,7 +5,7 @@ /// /// 集中器地址 /// - public string? Code { get; set; } + public string Code { get; set; } = null!; /// /// AFN功能码 @@ -22,7 +22,16 @@ /// public int Fn { get; set; } - + /// + /// 主站地址 MSA + /// + public int MSA { get; set; } + + /// + /// 响应帧序号 + /// + public int PSEQ { get; set; } + } public class UnitDataAnalysis: UnitDataAnalysis diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/TB3761.cs b/services/JiShe.CollectBus.Domain/Protocol3761/TB3761.cs similarity index 98% rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/TB3761.cs rename to services/JiShe.CollectBus.Domain/Protocol3761/TB3761.cs index 75727d2..d5e647f 100644 --- a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/TB3761.cs +++ b/services/JiShe.CollectBus.Domain/Protocol3761/TB3761.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace JiShe.CollectBus.Protocol.Contracts.Models +namespace JiShe.CollectBus.Protocol3761 { /// @@ -238,10 +238,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Models /// /// 数据单元标识和数据单元格式 /// - public class UnitData: BaseHexMessage - { - - } + public class UnitData: BaseHexMessage{ } #endregion diff --git a/shared/JiShe.CollectBus.Common/BuildSendDatas/Build645SendData.cs b/shared/JiShe.CollectBus.Common/BuildSendDatas/Build645SendData.cs index 6c4e960..023cb7f 100644 --- a/shared/JiShe.CollectBus.Common/BuildSendDatas/Build645SendData.cs +++ b/shared/JiShe.CollectBus.Common/BuildSendDatas/Build645SendData.cs @@ -69,6 +69,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas var strP = password.StrAddSpan().StrReverseOrder(); var strSJY = " " + pwdLevel + " " + strP + " 01 00 00 00 " + code + " 00 " + strDate; var dataUnit = strSJY.Replace(" ", "").StringToPairs(); + var dataList = Build645SendCommand(ammeterAddress, "1C", dataUnit); return dataList; diff --git a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketResponse.cs b/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketResponse.cs deleted file mode 100644 index 8cd964a..0000000 --- a/shared/JiShe.CollectBus.Common/BuildSendDatas/TelemetryPacketResponse.cs +++ /dev/null @@ -1,30 +0,0 @@ -using JiShe.CollectBus.Common.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JiShe.CollectBus.Common.BuildSendDatas -{ - /// - /// 报文构建返回结果 - /// - public class TelemetryPacketResponse - { - /// - /// 帧序列域SEQ - /// - public required Seq Seq { get; set; } - - /// - /// 地址域A3的主站地址MSA - /// - public int MSA { get; set; } - - /// - /// 报文体 - /// - public required byte[] Data { get; set; } - } -} diff --git a/shared/JiShe.CollectBus.Common/Consts/DataFieldConst.cs b/shared/JiShe.CollectBus.Common/Consts/DataFieldConst.cs new file mode 100644 index 0000000..62973ef --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Consts/DataFieldConst.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Consts +{ + /// + /// 数据保存字段常量 + /// + public class DataFieldConst + { + public const string ZYGDN = "ZYGDN"; + public const string ZWGDN = "ZWGDN"; + public const string FYGDN = "FYGDN"; + public const string FWGDN = "FWGDN"; + + public const string ZYGDNSZ = "ZYGDNSZ"; + public const string ZWGDNSZ = "ZWGDNSZ"; + public const string FYGDNSZ = "FYGDNSZ"; + public const string FWGDNSZ = "FWGDNSZ"; + + public const string WGDN1 = "WGDN1"; + public const string WGDN2 = "WGDN2"; + public const string WGDN3 = "WGDN3"; + public const string WGDN4 = "WGDN4"; + + public const string WGDNSZ1 = "WGDNSZ1"; + public const string WGDNSZ2 = "WGDNSZ2"; + public const string WGDNSZ3 = "WGDNSZ3"; + public const string WGDNSZ4 = "WGDNSZ4"; + + public const string YGGL = "YGGL"; + public const string AYGGL = "AYGGL"; + public const string BYGGL = "BYGGL"; + public const string CYGGL = "CYGGL"; + + public const string WGGL = "WGGL"; + public const string AWGGL = "AWGGL"; + public const string BWGGL = "BWGGL"; + public const string CWGGL = "CWGGL"; + + public const string GLYS = "GLYS"; + public const string AGLYS = "AGLYS"; + public const string BGLYS = "BGLYS"; + public const string CGLYS = "CGLYS"; + + public const string ADY = "ADY"; + public const string BDY = "BDY"; + public const string CDY = "CDY"; + + public const string ADL = "ADL"; + public const string BDL = "BDL"; + public const string CDL = "CDL"; + + public const string PowerGridFrequency = "PowerGridFrequency"; + + public const string Ua = "Ua"; + public const string Ub = "Ub"; + public const string Uc = "Uc"; + + public const string Ia = "Ia"; + public const string Ib = "Ib"; + public const string Ic = "Ic"; + + } + + public class ConstGatherDataType + { + public const string ZYGDN = "0D_97"; //正向有功总电能量 + public const string ZWGDN = "0D_98"; //正向无功总电能量曲线 + public const string FYGDN = "0D_99"; //反向有功总电能量曲线 + public const string FWGDN = "0D_100"; //反向无功总电能量曲线 + + public const string ZYGDNSZ = "0D_101"; //正向有功总电能示值曲线 + public const string ZWGDNSZ = "0D_102"; //正向无功总电能示值曲线 + public const string FYGDNSZ = "0D_103"; //反向有功总电能示值曲线 + public const string FWGDNSZ = "0D_104"; //反向无功总电能示值曲线 + + public const string WGDNSZ1 = "0D_145"; //一象限无功总电能示值曲线 + public const string WGDNSZ4 = "0D_146"; //四象限无功总电能示值曲线 + public const string WGDNSZ2 = "0D_147"; //二象限无功总电能示值曲线 + public const string WGDNSZ3 = "0D_148"; //三象限无功总电能示值曲线 + + public const string YGGL = "0D_81"; //有功功率曲线 + public const string AYGGL = "0D_82"; //A相有功功率曲线 + public const string BYGGL = "0D_83"; //B相有功功率曲线 + public const string CYGGL = "0D_84"; //C相有功功率曲线 + + public const string WGGL = "0D_85"; //无功功率曲线 + public const string AWGGL = "0D_86"; //A相无功功率曲线 + public const string BWGGL = "0D_87"; //B相无功功率曲线 + public const string CWGGL = "0D_88"; //C相无功功率曲线 + + public const string GLYS = "0D_105"; // 功率因数曲线 + public const string AGLYS = "0D_106"; // A相功率因数曲线 + public const string BGLYS = "0D_107"; // B相功率因数曲线 + public const string CGLYS = "0D_108"; // C相功率因数曲线 + + public const string ADY = "0D_89"; //A相电压曲线 + public const string BDY = "0D_90"; //B相电压曲线 + public const string CDY = "0D_91"; //C相电压曲线 + + public const string ADL = "0D_92"; //A相电流曲线 + public const string BDL = "0D_93"; //B相电流曲线 + public const string CDL = "0D_94"; //C相电流曲线 + + public const string PowerGridFrequency = "10_97"; //电网频率 + + public const string Ua = "0C_49_Uab_Ua"; // 当前电压、电流相位角 + public const string Ub = "0C_49_Ub"; // 当前电压、电流相位角 + public const string Uc = "0C_49_Ucb_Uc"; // 当前电压、电流相位角 + public const string Ia = "0C_49_Ia"; // 当前电压、电流相位角 + public const string Ib = "0C_49_Ib"; // 当前电压、电流相位角 + public const string Ic = "0C_49_Ic"; // 当前电压、电流相位角 + + } + + + public static class DataFieldHelper + { + /// + /// 数据字段映射 + /// + public static Dictionary DataFieldDic = new Dictionary(); + + /// + /// 创建数据字段映射 + /// + /// + public static Dictionary CreateDataFieldMapping() + { + if (DataFieldDic.Count > 0) + return DataFieldDic; + var dataFieldMapping = new Dictionary(); + Type dataType = typeof(ConstGatherDataType); + Type fieldType = typeof(DataFieldConst); + + foreach (FieldInfo gatherField in dataType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)) + { + if (gatherField.IsLiteral && !gatherField.IsInitOnly) + { + // 获取ConstGatherDataType的字段值作为key + string key = (string)gatherField.GetValue(null)!; + + // 查找DataFieldConst中同名字段 + FieldInfo dataField = fieldType.GetField(gatherField.Name, + BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)!; + + if (dataField != null) + { + string value = (string)dataField.GetValue(null)!; + dataFieldMapping[key] = value; + } + } + } + + return dataFieldMapping; + } + + /// + /// 根据采集数据类型获取数据字段 + /// 返回null表示 无效字段 + /// + /// + /// + public static string? GetDataFieldByGatherDataType(this string gatherDataType) + { + if (CreateDataFieldMapping().TryGetValue(gatherDataType, out string? column)) + { + return column; + } + return null; + } + + + } +} diff --git a/shared/JiShe.CollectBus.Common/Consts/ProtocolConst.cs b/shared/JiShe.CollectBus.Common/Consts/ProtocolConst.cs index 5f8e441..6af0fd0 100644 --- a/shared/JiShe.CollectBus.Common/Consts/ProtocolConst.cs +++ b/shared/JiShe.CollectBus.Common/Consts/ProtocolConst.cs @@ -47,7 +47,7 @@ namespace JiShe.CollectBus.Common.Consts public const string AmmeterSubscriberWorkerFifteenMinuteIssuedEventName = "issued.auto.fifteen.ammeter.event"; /// - /// 其他采集数据下行消息主题,日冻结,月冻结、集中器版本号控等 + /// 其他采集数据下行消息主题,日冻结,月冻结、集中器版本号、SIM卡号、定时校时等 /// public const string AmmeterSubscriberWorkerOtherIssuedEventName = "issued.auto.other.ammeter.event"; diff --git a/shared/JiShe.CollectBus.Common/Consts/T1882018PacketItemCodeConst.cs b/shared/JiShe.CollectBus.Common/Consts/T1882018PacketItemCodeConst.cs new file mode 100644 index 0000000..a51f77f --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Consts/T1882018PacketItemCodeConst.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Consts +{ + /// + /// T188报文项编码 + /// + public class T1882018PacketItemCodeConst + { + #region 下行报文编码 + + /// + /// 基路径 + /// + public const string BasicT1882018 = "CTR"; + + #region 读数据 + + + /// + /// 读取计量数据1 + /// + public const string CTR0190 = $"01_90"; + + /// + /// 读取计量数据2 + /// + public const string CTR0191 = $"01_91"; + + #endregion + + #region 写数据 + + /// + /// 关阀 + /// + public const string CTR30455 = $"_04_55"; + + /// + /// 开阀 + /// + public const string CTR30499 = $"_04_99"; + + + #endregion + + #endregion + } +} diff --git a/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs b/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs new file mode 100644 index 0000000..8a0834a --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Consts/T6452007PacketItemCodeConst.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Consts +{ + /// + /// T6452007报文项编码 + /// + public class T6452007PacketItemCodeConst + { + #region 下行报文编码 + #region 跳合闸、报警、保电 + /// + /// 跳闸 + /// + public const string C1C01A = "1C_1A"; + + /// + /// 单相合闸 + /// + public const string C1C01B = "1C_1B"; + + /// + /// 三相合闸 + /// + public const string C1C01C = "1C_1C"; + + /// + /// 触发报警 + /// + public const string C1C02A = "1C_2A"; + + /// + /// 报警解除 + /// + public const string C1C02B = "1C_2B"; + + /// + /// 保电开始 + /// + public const string C1C03A = "1C_3A"; + + /// + /// 保电结束 + /// + public const string C1C03B = "1C_3B"; + #endregion + + #region 广播校时 + + /// + /// 广播校时 + /// + public const string C08 = "08"; + #endregion + #endregion + } +} diff --git a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs index 11ba0a6..59691ce 100644 --- a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs +++ b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs @@ -768,10 +768,11 @@ namespace JiShe.CollectBus.Common.Helpers /// /// /// + /// /// - public static string GetTaskMark(int afn, int fn, int pn, int msa) + public static string GetTaskMark(int afn, int fn, int pn, int msa,int seq) { - var makstr = $"{afn.ToString().PadLeft(2, '0')}{fn.ToString().PadLeft(2, '0')}{pn.ToString().PadLeft(2, '0')}"; + var makstr = $"{afn.ToString().PadLeft(2, '0')}{fn.ToString().PadLeft(2, '0')}{pn.ToString().PadLeft(2, '0')}{msa.ToString().PadLeft(2, '0')}{seq.ToString().PadLeft(2, '0')}"; return makstr;// Convert.ToInt32(makstr) << 32 | msa; } @@ -831,5 +832,7 @@ namespace JiShe.CollectBus.Common.Helpers return arr.Contains(weekName); } + + } } diff --git a/shared/JiShe.CollectBus.Common/Helpers/DataFieldHelper.cs b/shared/JiShe.CollectBus.Common/Helpers/DataFieldHelper.cs new file mode 100644 index 0000000..a9173bb --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Helpers/DataFieldHelper.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Helpers +{ + public class DataFieldHelper + { + public static string GetDataField(string dataField) + { + if (string.IsNullOrWhiteSpace(dataField)) + { + return string.Empty; + } + + if (dataField.Contains(".")) + { + return dataField.Split('.')[0]; + } + + return dataField; + } + } +} diff --git a/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs b/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs new file mode 100644 index 0000000..6ed9e4a --- /dev/null +++ b/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs @@ -0,0 +1,23 @@ +namespace JiShe.CollectBus.Common +{ + /// + /// 服务器应用配置 + /// + public class ServerApplicationOptions + { + /// + /// 服务器标识 + /// + public required string ServerTagName { get; set; } + + /// + /// 首次采集时间 + /// + public DateTime? FirstCollectionTime { get; set; } + + /// + /// 自动验证时间 + /// + public required string AutomaticVerificationTime { get; set;} + } +} diff --git a/web/JiShe.CollectBus.Host/CollectBusHostModule.cs b/web/JiShe.CollectBus.Host/CollectBusHostModule.cs index 5068663..e451a1d 100644 --- a/web/JiShe.CollectBus.Host/CollectBusHostModule.cs +++ b/web/JiShe.CollectBus.Host/CollectBusHostModule.cs @@ -1,8 +1,10 @@ using Hangfire; using HealthChecks.UI.Client; +using JiShe.CollectBus.Common; using JiShe.CollectBus.Host.Extensions; using JiShe.CollectBus.Host.HealthChecks; using JiShe.CollectBus.Host.Swaggers; +using JiShe.CollectBus.IoTDB.Options; using JiShe.CollectBus.MongoDB; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Swashbuckle.AspNetCore.SwaggerUI; @@ -28,7 +30,7 @@ namespace JiShe.CollectBus.Host typeof(AbpSwashbuckleModule), typeof(AbpTimingModule), typeof(CollectBusApplicationModule), - typeof(CollectBusMongoDbModule), + typeof(CollectBusMongoDbModule), typeof(AbpCachingStackExchangeRedisModule), typeof(AbpBackgroundWorkersHangfireModule) )] @@ -50,6 +52,12 @@ namespace JiShe.CollectBus.Host ConfigureCustom(context, configuration); ConfigureHealthChecks(context, configuration); Configure(options => { options.Kind = DateTimeKind.Local; }); + + Configure(options => + { + configuration.GetSection(nameof(ServerApplicationOptions)).Bind(options); + }); + } diff --git a/web/JiShe.CollectBus.Host/Extensions/CustomApplicationBuilderExtensions.cs b/web/JiShe.CollectBus.Host/Extensions/CustomApplicationBuilderExtensions.cs index 6019cd2..f933497 100644 --- a/web/JiShe.CollectBus.Host/Extensions/CustomApplicationBuilderExtensions.cs +++ b/web/JiShe.CollectBus.Host/Extensions/CustomApplicationBuilderExtensions.cs @@ -1,7 +1,4 @@ -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using Volo.Abp.Caching; - -namespace JiShe.CollectBus.Host.Extensions +namespace JiShe.CollectBus.Host.Extensions { public static class CustomApplicationBuilderExtensions { diff --git a/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj b/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj index ffb3536..4ebd67d 100644 --- a/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj +++ b/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj @@ -66,7 +66,13 @@ - + + Always + + + Always + + Always