diff --git a/JiShe.CollectBus.sln b/JiShe.CollectBus.sln
index 6bc2bee..c3ad8a0 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}"
@@ -49,10 +45,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Shared", "5.Shared", "{EB
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Kafka.Test", "modules\JiShe.CollectBus.Kafka.Test\JiShe.CollectBus.Kafka.Test.csproj", "{6D6A2A58-7406-9C8C-7B23-3E442CCE3E6B}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.External", "6.External", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6", "6", "{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}"
EndProject
+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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -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
@@ -135,6 +131,22 @@ Global
{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
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}
@@ -159,6 +169,10 @@ Global
{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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD}
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/JiSheCollectBusProtocolModule.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs
similarity index 96%
rename from protocols/JiShe.CollectBus.Protocol/JiSheCollectBusProtocolModule.cs
rename to protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs
index 6b08805..6cb202a 100644
--- a/protocols/JiShe.CollectBus.Protocol/JiSheCollectBusProtocolModule.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T1882018/JiSheCollectBusProtocolT1882018Module.cs
@@ -16,11 +16,11 @@ using Volo.Abp.Modularity;
namespace JiShe.CollectBus.Protocol
{
- public class JiSheCollectBusProtocolModule : AbpModule
+ public class JiSheCollectBusProtocolT1882018Module : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
- context.Services.AddKeyedSingleton(nameof(StandardProtocolPlugin));
+ context.Services.AddKeyedSingleton(nameof(T1882018ProtocolPlugin));
//RegisterProtocolAnalysis(context.Services);
LoadAnalysisStrategy(context.Services);
}
@@ -28,7 +28,7 @@ namespace JiShe.CollectBus.Protocol
public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
Console.WriteLine("StandardProtocolPlugin OnApplicationInitializationAsync");
- var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(StandardProtocolPlugin));
+ var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(T1882018ProtocolPlugin));
await standardProtocol.LoadAsync();
}
diff --git a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs
similarity index 77%
rename from protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketBuilder.cs
rename to protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs
index a7faf67..e5dabab 100644
--- a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketBuilder.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketBuilder.cs
@@ -10,30 +10,30 @@ namespace JiShe.CollectBus.Protocol.SendData
///
/// 构建645-2007下发报文
///
- public static class Telemetry645PacketBuilder
+ public static class Telemetry1882018PacketBuilder
{
///
/// 构建报文的委托
///
///
///
- public delegate Telemetry645PacketResponse T645Delegate(Telemetry645PacketRequest request);
+ public delegate Telemetry1882018PacketResponse T6452007Delegate(Telemetry1882018PacketRequest request);
///
/// 编码与方法的映射表
///
- public static readonly Dictionary T645ControlHandlers = new();
+ public static readonly Dictionary T645ControlHandlers = new();
- static Telemetry645PacketBuilder()
+ static Telemetry1882018PacketBuilder()
{
// 初始化时自动注册所有符合命名规则的方法
- var methods = typeof(Telemetry645PacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public);
+ var methods = typeof(Telemetry1882018PacketBuilder).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 = (T645Delegate)Delegate.CreateDelegate(typeof(T645Delegate), method);
+ var delegateInstance = (T6452007Delegate)Delegate.CreateDelegate(typeof(T6452007Delegate), method);
T645ControlHandlers[code] = delegateInstance;
}
}
@@ -46,7 +46,7 @@ namespace JiShe.CollectBus.Protocol.SendData
///
///
///
- public static Telemetry645PacketResponse C1C_01_Send(Telemetry645PacketRequest request)
+ public static Telemetry1882018PacketResponse C1C_01_Send(Telemetry1882018PacketRequest request)
{
var itemCodeArr = request.ItemCode.Split('_');
var c_data = itemCodeArr[0];
@@ -68,7 +68,7 @@ namespace JiShe.CollectBus.Protocol.SendData
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit);
- return new Telemetry645PacketResponse() { Data = dataList };
+ return new Telemetry1882018PacketResponse() { Data = dataList };
}
@@ -77,7 +77,7 @@ namespace JiShe.CollectBus.Protocol.SendData
///
///
///
- public static Telemetry645PacketResponse C1C_03_Send(Telemetry645PacketRequest request)
+ public static Telemetry1882018PacketResponse C1C_03_Send(Telemetry1882018PacketRequest request)
{
var itemCodeArr = request.ItemCode.Split('_');
var c_data = itemCodeArr[0];
@@ -99,7 +99,7 @@ namespace JiShe.CollectBus.Protocol.SendData
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit);
- return new Telemetry645PacketResponse() { Data = dataList };
+ return new Telemetry1882018PacketResponse() { Data = dataList };
}
#endregion
}
diff --git a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs
similarity index 91%
rename from protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketRequest.cs
rename to protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs
index fd90322..ef51ea1 100644
--- a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketRequest.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketRequest.cs
@@ -3,7 +3,7 @@
///
/// 构建645报文参数
///
- public class Telemetry645PacketRequest
+ public class Telemetry1882018PacketRequest
{
///
/// 表地址
diff --git a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketResponse.cs
similarity index 83%
rename from protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketResponse.cs
rename to protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketResponse.cs
index 7731e0f..90e6e62 100644
--- a/protocols/JiShe.CollectBus.Protocol/SendData/Telemetry645PacketResponse.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T1882018/SendData/Telemetry1882018PacketResponse.cs
@@ -3,7 +3,7 @@
///
/// 返回645报文结果
///
- public class Telemetry645PacketResponse
+ public class Telemetry1882018PacketResponse
{
///
/// 报文体
diff --git a/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs
new file mode 100644
index 0000000..3b392e2
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol.T1882018/T1882018ProtocolPlugin.cs
@@ -0,0 +1,506 @@
+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.Models;
+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
+{
+ public class T1882018ProtocolPlugin : T37612012ProtocolPlugin
+ {
+ private readonly ILogger _logger;
+
+ private readonly IProducerService _producerService;
+
+ private readonly IRepository _deviceRepository;
+ private readonly ITcpService _tcpService;
+
+ public readonly Dictionary T3761AFNHandlers;
+ public readonly Dictionary T645ControlHandlers;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The service provider.
+ public T1882018ProtocolPlugin(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;
+ T645ControlHandlers = Telemetry1882018PacketBuilder.T645ControlHandlers;
+ }
+
+ public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "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(T1882018ProtocolPlugin)} 报文构建失败,参数为空");
+ }
+ 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";
+ Telemetry1882018PacketResponse t645PacketResponse = null;
+
+ if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName
+ , 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 (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);
+ }
+
+
+ #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.Contracts/Abstracts/BaseProtocolPlugin_bak.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Abstracts/BaseProtocolPlugin_bak.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin_bak.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Abstracts/BaseProtocolPlugin_bak.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/Abstracts/T37612012ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Abstracts/T37612012ProtocolPlugin.cs
new file mode 100644
index 0000000..772ab4e
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol.T37612012/Abstracts/T37612012ProtocolPlugin.cs
@@ -0,0 +1,405 @@
+using JiShe.CollectBus.Common.BuildSendDatas;
+using JiShe.CollectBus.Common.Enums;
+using System;
+using System.Reflection;
+using JiShe.CollectBus.Common.Consts;
+using JiShe.CollectBus.Common.Extensions;
+using JiShe.CollectBus.Common.Models;
+using JiShe.CollectBus.FreeRedis;
+using JiShe.CollectBus.IotSystems.Protocols;
+using JiShe.CollectBus.Protocol.Contracts.Interfaces;
+using JiShe.CollectBus.Protocol.Contracts.Models;
+using JiShe.CollectBus.Protocol.Contracts.SendData;
+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 T37612012ProtocolPlugin : 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 T37612012ProtocolPlugin(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"));
+
+ #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.T37612012/Adapters/StandardFixedHeaderDataHandlingAdapter.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Adapters/StandardFixedHeaderDataHandlingAdapter.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Adapters/StandardFixedHeaderDataHandlingAdapter.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisData/Appendix.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/Appendix.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisData/Appendix.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/Appendix.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisStrategyContext.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisStrategyContext.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/AnalysisStrategyContext.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisStrategyContext.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Attributes/ProtocolNameAttribute.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Attributes/ProtocolNameAttribute.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Attributes/ProtocolNameAttribute.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Attributes/ProtocolNameAttribute.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs
new file mode 100644
index 0000000..d3005df
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol.T37612012/CollectBusProtocolT37612012Module.cs
@@ -0,0 +1,18 @@
+using JiShe.CollectBus.FreeRedis.Options;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace JiShe.CollectBus.Protocol.Contracts
+{
+ public class CollectBusProtocolT37612012Module : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+
+ }
+ }
+}
+
+
+
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IAnalysisStrategy.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Interfaces/IAnalysisStrategy.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IAnalysisStrategy.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Interfaces/IAnalysisStrategy.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Interfaces/IProtocolPlugin.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Interfaces/IProtocolPlugin.cs
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..2c074cd
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol.T37612012/JiShe.CollectBus.Protocol.T37612012.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/CustomFixedHeaderRequestInfo.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Models/CustomFixedHeaderRequestInfo.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/CustomFixedHeaderRequestInfo.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Models/CustomFixedHeaderRequestInfo.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/TB3761.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Models/TB3761.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/TB3761.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Models/TB3761.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F10_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN10_F10_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F10_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN10_F10_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F66_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN10_F66_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN10_F66_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN10_F66_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F129_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F129_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F129_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F129_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F130_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F130_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F130_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F130_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F131_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F131_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F131_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F131_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F132_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F132_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F132_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F132_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F145_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F145_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F145_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F145_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F149_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F149_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F149_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F149_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F188_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F188_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F188_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F188_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F25_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F25_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F25_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F25_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F2_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F2_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F2_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F2_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F33_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F33_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F33_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F33_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F49_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F49_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN12_F49_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN12_F49_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN9_F1_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN9_F1_AnalysisDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AFN9_F1_AnalysisDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AFN9_F1_AnalysisDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AnalysisBaseDto.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AnalysisBaseDto.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/AnalysisBaseDto.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/AnalysisBaseDto.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/UnitDataAnalysis.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/UnitDataAnalysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Protocol/Dto/UnitDataAnalysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/Protocol/Dto/UnitDataAnalysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/QGDW3761Config.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/QGDW3761Config.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/QGDW3761Config.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/QGDW3761Config.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketBuilder.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketBuilder.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketBuilder.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketRequest.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketRequest.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketRequest.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketResponse.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/SendData/Telemetry3761PacketResponse.cs
rename to protocols/JiShe.CollectBus.Protocol.T37612012/SendData/Telemetry3761PacketResponse.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_00H/AFN0_F1_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_00H/AFN0_F2_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_09H/AFN9_F1_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_09H/AFN9_F9_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F10_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F66_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0AH/AFN10_F68_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F129_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F130_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F131_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F132_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F145_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F149_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F188_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F25_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F2_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F33_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/AnalysisData/AFN_0CH/AFN12_F49_Analysis.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_02800002.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_02800002.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_02800002.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_02800002.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000201.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000201.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000201.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000201.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000202.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000202.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000202.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000202.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000203.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000203.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000203.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000203.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000204.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000204.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04000204.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04000204.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010000.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010000.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010000.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010000.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010001.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010001.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010001.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010001.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010002.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010002.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010002.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010002.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010003.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010003.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010003.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010003.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010004.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010004.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010004.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010004.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010005.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010005.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010005.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010005.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010006.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010006.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010006.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010006.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010007.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010007.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010007.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010007.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010008.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010008.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_04010008.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_04010008.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A1.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A1.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A1.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A1.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A11.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A11.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A11.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A11.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A13.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A13.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A13.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A13.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A14.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A14.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A14.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A14.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A15.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A15.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A15.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A15.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A17.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A17.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A17.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A17.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A23.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A23.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A23.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A23.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A25.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A25.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A25.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A25.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A5.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A5.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A5.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A5.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A7.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A7.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A7.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A7.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A9.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A9.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Appendix/Appendix_A9.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Appendix/Appendix_A9.cs
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..767a2d3
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol.T6452007/JiSheCollectBusProtocolT6452007Module.cs
@@ -0,0 +1,111 @@
+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 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
+{
+ public class JiSheCollectBusProtocolT6452007Module : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddKeyedSingleton(nameof(T6452007ProtocolPlugin));
+ //RegisterProtocolAnalysis(context.Services);
+ LoadAnalysisStrategy(context.Services);
+ }
+
+ public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
+ {
+ Console.WriteLine("StandardProtocolPlugin OnApplicationInitializationAsync");
+ var standardProtocol = context.ServiceProvider.GetRequiredKeyedService(nameof(T6452007ProtocolPlugin));
+ await standardProtocol.LoadAsync();
+ }
+
+ public override void OnApplicationShutdown(ApplicationShutdownContext context)
+ {
+ Console.WriteLine("StandardProtocolPlugin OnApplicationShutdown");
+ base.OnApplicationShutdown(context);
+ }
+
+ public void LoadAnalysisStrategy(IServiceCollection services)
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+ var analysisStrategyTypes = assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAnalysisStrategy<,>)));
+ foreach (var analysisStrategyType in analysisStrategyTypes)
+ {
+ var service = analysisStrategyType.GetInterfaces().First();
+ services.AddKeyedSingleton(service, analysisStrategyType.Name,analysisStrategyType);
+ }
+ }
+
+ public void RegisterProtocolAnalysis(IServiceCollection services)
+ {
+ // 扫描并注册所有策略
+ var strategyMetadata = new Dictionary<(string, Type, Type), Type>();
+ services.AddTransient();
+
+ // 批量注册
+ var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
+ if (string.IsNullOrWhiteSpace(assemblyPath))
+ {
+ return;
+ }
+ var dllFiles = Directory.GetFiles(Path.Combine(assemblyPath, "Plugins") , "*.dll");
+ foreach (var file in dllFiles)
+ {
+ // 跳过已加载的程序集
+ var assemblyName = AssemblyName.GetAssemblyName(file);
+ var existingAssembly = AppDomain.CurrentDomain.GetAssemblies()
+ .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<,>)));
+ if (!analysisStrategyTypes.Any())
+ continue;
+ foreach (var analysisStrategyType in analysisStrategyTypes)
+ {
+ // 通过反射获取静态元数据
+ var strategyType = analysisStrategyType.Name;
+ var genericArgs = analysisStrategyType.GetInterface($"IAnalysisStrategy`2")!.GetGenericArguments();
+ var inputType = genericArgs[0];
+ var resultType = genericArgs[1];
+ // 注册策略实现
+ services.AddTransient(analysisStrategyType);
+ strategyMetadata[(strategyType, inputType, resultType)] = analysisStrategyType;
+ }
+ }
+
+ // 注册元数据字典
+ services.AddSingleton(strategyMetadata);
+
+ // 注册策略解析工厂
+ services.AddTransient>(provider => (name, inputType, resultType) =>
+ {
+ var metadata = provider.GetRequiredService>();
+ if (metadata.TryGetValue((name, inputType, resultType), out var strategyType))
+ {
+ return provider.GetRequiredService(strategyType);
+ }
+ else
+ {
+ var logger= provider.GetRequiredService>();
+ logger.LogWarning($"未能找到解析策略:{name}-{inputType}-{resultType}");
+ return null;
+ }
+ });
+
+
+ }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol3761Extensions.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/Protocol3761Extensions.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol/Protocol3761Extensions.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/Protocol3761Extensions.cs
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/StandardProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs
similarity index 96%
rename from protocols/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
rename to protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs
index 4201d04..e0e9fc3 100644
--- a/protocols/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T6452007/T6452007ProtocolPlugin.cs
@@ -21,9 +21,9 @@ using Volo.Abp.Domain.Repositories;
namespace JiShe.CollectBus.Protocol
{
- public class StandardProtocolPlugin : ProtocolPlugin
+ public class T6452007ProtocolPlugin : ProtocolPlugin
{
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
private readonly IProducerService _producerService;
@@ -31,13 +31,13 @@ namespace JiShe.CollectBus.Protocol
private readonly ITcpService _tcpService;
public readonly Dictionary T3761AFNHandlers;
- public readonly Dictionary T645ControlHandlers;
+ public readonly Dictionary T645ControlHandlers;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The service provider.
- public StandardProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger)
+ public T6452007ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger, ITcpService tcpService) : base(serviceProvider, logger)
{
_logger = logger;
//_logger = serviceProvider.GetRequiredService>();
@@ -45,10 +45,10 @@ namespace JiShe.CollectBus.Protocol
_deviceRepository = serviceProvider.GetRequiredService>();
_tcpService = tcpService;
T3761AFNHandlers = Telemetry3761PacketBuilder.T3761AFNHandlers;
- T645ControlHandlers = Telemetry645PacketBuilder.T645ControlHandlers;
+ T645ControlHandlers = Telemetry6452007PacketBuilder.T645ControlHandlers;
}
- public sealed override ProtocolInfo Info => new(nameof(StandardProtocolPlugin), "376.1", "TCP", "376.1协议", "DTS1980");
+ public sealed override ProtocolInfo Info => new(nameof(T6452007ProtocolPlugin), "376.1", "TCP", "376.1协议", "DTS1980");
public override async Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? sendAction = null)
{
@@ -318,7 +318,7 @@ namespace JiShe.CollectBus.Protocol
{
if (request == null)
{
- throw new Exception($"{nameof(StandardProtocolPlugin)} 报文构建失败,参数为空");
+ throw new Exception($"{nameof(T6452007ProtocolPlugin)} 报文构建失败,参数为空");
}
var itemCodeArr = request.ItemCode.Split('_');
var aFNStr = itemCodeArr[0];
@@ -331,12 +331,12 @@ namespace JiShe.CollectBus.Protocol
if (aFNStr == "10" && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false)
{
var t645PacketHandlerName = $"C{request.SubProtocolRequest.ItemCode}_Send";
- Telemetry645PacketResponse t645PacketResponse = null;
+ Telemetry6452007PacketResponse t645PacketResponse = null;
if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName
, out var t645PacketHandler))
{
- t645PacketResponse = t645PacketHandler(new Telemetry645PacketRequest()
+ t645PacketResponse = t645PacketHandler(new Telemetry6452007PacketRequest()
{
MeterAddress = request.SubProtocolRequest.MeterAddress,
Password = request.SubProtocolRequest.Password,
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..c3be8a6 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,6 @@
-
diff --git a/protocols/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin_bak.cs b/protocols/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin_bak.cs
new file mode 100644
index 0000000..923f9ba
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin_bak.cs
@@ -0,0 +1,1177 @@
+using FreeRedis;
+using JiShe.CollectBus.Common.Enums;
+using JiShe.CollectBus.Common.Extensions;
+using JiShe.CollectBus.Common.Models;
+using JiShe.CollectBus.Protocol.Contracts.Interfaces;
+using Microsoft.Extensions.Logging;
+using JiShe.CollectBus.Protocol.Contracts.Models;
+using Volo.Abp.Domain.Repositories;
+using JiShe.CollectBus.Common.BuildSendDatas;
+using JiShe.CollectBus.Protocol.Contracts.AnalysisData;
+using Microsoft.Extensions.DependencyInjection;
+using JiShe.CollectBus.IotSystems.MessageReceiveds;
+using JiShe.CollectBus.IotSystems.Protocols;
+using JiShe.CollectBus.Kafka.Producer;
+using JiShe.CollectBus.Common.Consts;
+using JiShe.CollectBus.FreeRedis;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
+{
+ public abstract class BaseProtocolPlugin_bak //: IProtocolPlugin
+ {
+ private readonly IProducerService _producerService;
+ private readonly ILogger _logger;
+ private readonly IRepository _protocolInfoRepository;
+ private readonly IFreeRedisProvider _redisProvider;
+
+ //头部字节长度
+ public const int hearderLen = 6;
+
+ public const int tPLen = 6;
+
+ public const string errorData = "EE";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The service provider.
+ protected BaseProtocolPlugin_bak(IServiceProvider serviceProvider)
+ {
+
+ _logger = serviceProvider.GetRequiredService>();
+ _protocolInfoRepository = serviceProvider.GetRequiredService>();
+ _producerService = 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(MessageReceived messageReceived, Action? sendAction = null) where T : TB3761;
+
+ ///
+ /// 登录帧解析
+ ///
+ /// 报文
+ ///
+ public virtual async Task LoginAsync(MessageReceivedLogin messageReceived)
+ {
+ var hexStringList = messageReceived.MessageHexString.StringToPairs();
+ var aTuple = (Tuple)hexStringList.GetAnalyzeValue(CommandChunkEnum.A);
+ var seq = (Seq)hexStringList.GetAnalyzeValue(CommandChunkEnum.SEQ);
+ var reqParam = new ReqParameter2
+ {
+ AFN = AFN.确认或否认,
+ FunCode = (int)CFromStationFunCode.链路数据,
+ PRM = PRM.从动站报文,
+ A = aTuple.Item1,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.需要对该帧进行确认,
+ PRSEQ = seq.PRSEQ
+ },
+ MSA = aTuple.Item2,
+ Pn = 0,
+ Fn = 1
+ };
+ var bytes = Build3761SendData.BuildSendCommandBytes(reqParam);
+ //await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
+
+ await _producerService.ProduceAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
+ //await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
+ }
+
+ ///
+ /// 心跳帧解析
+ ///
+ /// 报文
+ ///
+ public virtual async Task HeartbeatAsync(MessageReceivedHeartbeat messageReceived)
+ {
+ var hexStringList = messageReceived.MessageHexString.StringToPairs();
+ var aTuple = (Tuple)hexStringList.GetAnalyzeValue(CommandChunkEnum.A);
+ var seq = (Seq)hexStringList.GetAnalyzeValue(CommandChunkEnum.SEQ);
+ if (seq.TpV == TpV.附加信息域中带时间标签)
+ {
+ //解析
+
+ }
+ if (seq.CON == CON.需要对该帧进行确认)
+ {
+ var reqParam = new ReqParameter2()
+ {
+ AFN = AFN.确认或否认,
+ FunCode = (int)CFromStationFunCode.链路数据,
+ PRM = PRM.从动站报文,
+ A = aTuple.Item1,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.不需要对该帧进行确认,
+ PRSEQ = seq.PRSEQ,
+ },
+ MSA = aTuple.Item2,
+ Pn = 0,
+ Fn = 1
+ };
+ var bytes = Build3761SendData.BuildSendCommandBytes(reqParam);
+ //await _producerBus.PublishAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId });
+
+ await _producerService.ProduceAsync(ProtocolConst.SubscriberHeartbeatIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId });
+
+ //await _producerBus.Publish(new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Heartbeat, MessageId = messageReceived.MessageId });
+ }
+ }
+
+ ///
+ /// 解析确认或否认数据
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task AnalyzeAnswerDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexStringList = messageReceived.MessageHexString.StringToPairs();
+ var fn = hexStringList.GetAnalyzeValue(CommandChunkEnum.FN);
+ //1:全部确认
+ //2:全部否认
+ //3:按数据单元表示确认和否认
+ //4 硬件安全认证错误应答
+ }
+
+ ///
+ /// 解析电表档案读取数据
+ ///
+ ///
+ ///
+ ///
+ public virtual List AnalyzeAmmeterParameterReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+
+ var meterList = new List();
+ var count = (hexData[1] + hexData[0]).HexToDec();
+ //if (2 + count * 27 != hexDatas.Count - pWLen - tPLen - 2)
+ // return;
+ var index = 2;//数量
+ for (int i = 1; i <= count; i++)
+ {
+ var meterNumber = $"{hexData[index + 1]}{hexData[index]}".HexToDec();
+ index += 2;
+
+ var pn = $"{hexData[index + 1]}{hexData[index]}".HexToDec();
+ index += 2;
+
+ var baudRateAndPortBin = hexData[index].HexToBin().PadLeft(8, '0');
+ var baudRate = baudRateAndPortBin.Substring(0, 3).BinToDec();
+ var port = baudRateAndPortBin.Substring(3, 5).BinToDec();
+ index += 1;
+
+ var protocolType = (CommunicationProtocolType)hexData[index].HexToDec();
+ index += 1;
+
+ var addressHexList = hexData.Skip(index).Take(6).ToList();
+ addressHexList.Reverse();
+ var address = string.Join("", addressHexList);
+ index += 6;
+
+ var pwdHexList = hexData.Skip(index).Take(6).ToList();
+ pwdHexList.Reverse();
+ var password = string.Join("", pwdHexList.Take(3).ToList());
+ index += 6;
+
+ var rateNumberBin = hexData[index].HexToBin().PadLeft(8, '0');
+ var rateNumber = rateNumberBin.Substring(4).BinToDec();
+ index += 1;
+
+ var intBitAndDecBitNumberBin = hexData[index].HexToBin().PadLeft(8, '0');
+ var intBitNumber = intBitAndDecBitNumberBin.Substring(4, 2).BinToDec() + 4;
+ var decBitNumber = intBitAndDecBitNumberBin.Substring(6, 2).BinToDec() + 1;
+ index += 1;
+
+ // hexDatas.GetRange()
+ var collectorAddressHexList = hexData.Skip(index).Take(6).ToList();
+ collectorAddressHexList.Reverse();
+ var collectorAddress = string.Join("", collectorAddressHexList);
+ index += 6;
+
+ var userClassNumberBin = hexData[index].HexToBin().PadLeft(8, '0');
+ var userClass = userClassNumberBin.Substring(0, 4).BinToDec();
+ var userSubClass = userClassNumberBin.Substring(4, 4).BinToDec();
+ index += 1;
+
+ meterList.Add(new AmmeterParameter()
+ {
+ Pn = pn,
+ BaudRate = baudRate,
+ Port = port,
+ ProtocolType = (int)protocolType,
+ Address = address,
+ Password = password,
+ RateNumber = rateNumber,
+ IntegerBitNumber = intBitNumber,
+ DecimalBitNumber = decBitNumber,
+ CollectorAddress = collectorAddress,
+ UserCategoryNumber = userClass,
+ UserSubclassNumber = userSubClass,
+ });
+ }
+
+ return meterList;
+ }
+
+ ///
+ /// 解析当前正向有功电能示值抄读数据
+ ///
+ /// 报文
+ /// 发送委托
+ ///
+ public virtual CurrentPositiveActiveEnergyAnalyze AnalyzeActivePowerIndicationReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+
+ var minute = Convert.ToInt32(hexData[0]); // 获取当前分钟数
+ var hour = Convert.ToInt32(hexData[1]); // 获取当前小时数
+ var day = Convert.ToInt32(hexData[2]); // 获取当前日期的日数
+ var month = Convert.ToInt32(hexData[3]); // 获取当前月份
+ var year = Convert.ToInt32(hexData[4]); // 获取当前日期的年份
+ var dateTime = new DateTime(year, month, day, hour, minute, 0);
+ // 转换为本地时间
+ var localDateTime = dateTime.ToLocalTime();
+
+ var rateNumber = Convert.ToInt32(hexData[5]);
+ var kwhTotal = hexData.Skip(5).Take(5).ToList();
+ var kwhList = new List();
+ var index = 11;
+ for (int i = 0; i < rateNumber; i++)
+ {
+ var kwhHexList = hexData.Skip(index).Take(5).ToList();
+ kwhHexList.Reverse();
+ var integerStr = $"{kwhHexList.Take(0)}{kwhHexList.Take(1)}{kwhHexList.Take(2)}";
+ var decimalValStr = $"{kwhHexList[3]}{kwhHexList[4]}";
+ var val = decimal.Parse($"{integerStr}{decimalValStr}");
+ kwhList.Add(new PositiveActiveEnergyItem()
+ {
+ Name = $"费率{i + 1}正向有功总电能示值",
+ Value = val
+ });
+ index += 5;
+ }
+
+ return new CurrentPositiveActiveEnergyAnalyze()
+ {
+ ReadingTime = localDateTime,
+ RateNumber = rateNumber,
+ Items = kwhList
+ };
+ }
+
+ ///
+ /// 解析日冻结正向有功电能示值抄读数据
+ ///
+ ///
+ ///
+ ///
+ public virtual void AnalyzeDailyFrozenReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+ //附录A.20 日月年
+ var td_dHex = hexData.Take(3).ToList();
+ //附录A.15 分时日月年
+ var readingTimeHex = hexData.Skip(3).Take(5).ToList();
+ var rateNumberHex = hexData.Skip(8).Take(1).FirstOrDefault().HexToDec();
+
+ var datas = new List();
+ //附录A.14 kWh 5字节
+ for (int i = 0; i < rateNumberHex; i++)
+ {
+ var skipCount = 9 + i * 5;
+ var dataHexs = hexData.Skip(skipCount).Take(5).ToList();
+ var data = AnalyzeDataAccordingToA14(dataHexs[0], dataHexs[1], dataHexs[2], dataHexs[3], dataHexs[4]);
+ datas.Add(data);
+ }
+
+ }
+
+ //接收<2024/11/7 17:34:42>: 68 3E 01 3E 01 68
+ //控制域 88
+ //地址域 20 32 90 26 1A
+ //AFN 0C
+ //Seq 62
+ //pn 01 01
+ //fn 01 03
+
+ //F0 16
+
+ //报文解析:计量点1数据
+ //++++++++ F25:当前三相及总有/无功功率功率因数 三相电压电流 零序电流 ++++++++
+ //终端抄表时间:2024年11月07日17时34分 34 17 07 11 24
+ //当前总有功功率:-0.0028 kW 28 00 80
+ //当前A相有功功率:0 kW 00 00 80
+ //当前B相有功功率:0 kW 00 00 80
+ //当前C相有功功率:-0.0027 kW 27 00 80
+ //当前总无功功率:-0.0047 kW 47 00 80
+ //当前A相无功功率:0 kW 00 00 00
+ //当前B相无功功率:0 kW 00 00 00
+ //当前C相无功功率:-0.0047 kW 47 00 80
+ //当前总功率因数:-51.8 % 18 85
+ //当前A相功率因数:0 % 00 80
+ //当前B相功率因数:0 % 00 80
+ //当前C相功率因数:-50 % 00 85
+ //当前A相电压:0.1 V 01 00
+ //当前B相电压:0.2 V 02 00
+ //当前C相电压:239 V 90 23
+ //当前A相电流:0 A 00 00 80
+ //当前B相电流:0 A 00 00 80
+ //当前C相电流:-0.024 A 24 00 80
+ //当前零序电流:Error: 数据不符合BCD码格式 A EE EE EE
+ //当前总视在功率:Error: 数据不符合BCD码格式 kVA EE EE EE
+ //当前A相视在功率:Error: 数据不符合BCD码格式 kVA EE EE EE
+ //当前B相视在功率:Error: 数据不符合BCD码格式 kVA EE EE EE
+ //当前C相视在功率:Error: 数据不符合BCD码格式 kVA EE EE EE
+ //++++++++++++++++++++++++++++++++++++
+ ///
+ /// 当前三相及总有/无功功率、功率因数、三相电压、电流、零序电流、视在功率
+ ///
+ ///
+ ///
+ /// //F25ReadingAnalyze
+ public virtual Analyze3761Data AnalyzeF25ReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+ //A.15 分时日月年
+ var readingTimeHex = hexData.Take(5).ToList();
+ var readingTime = AnalyzeDataAccordingToA15(readingTimeHex[0], readingTimeHex[1], readingTimeHex[2], readingTimeHex[3], readingTimeHex[4]);
+
+ //A.9 kW
+ var crntTotalActivePowerHexs = hexData.Skip((int)F25DataItemEnum.CrntTotalActivePower).Take(3).ToList();
+ var crntTotalActivePower = AnalyzeDataAccordingToA09(crntTotalActivePowerHexs[0], crntTotalActivePowerHexs[1], crntTotalActivePowerHexs[2]);
+
+ var crntActivePowerOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntActivePowerOfA).Take(3).ToList();
+ var crntActivePowerOfA = AnalyzeDataAccordingToA09(crntActivePowerOfAHexs[0], crntActivePowerOfAHexs[1], crntActivePowerOfAHexs[2]);
+
+ var crntActivePowerOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntActivePowerOfB).Take(3).ToList();
+ var crntActivePowerOfB = AnalyzeDataAccordingToA09(crntActivePowerOfBHexs[0], crntActivePowerOfBHexs[1], crntActivePowerOfBHexs[2]);
+
+ var crntActivePowerOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntActivePowerOfC).Take(3).ToList();
+ var crntActivePowerOfC = AnalyzeDataAccordingToA09(crntActivePowerOfCHexs[0], crntActivePowerOfCHexs[1], crntActivePowerOfCHexs[2]);
+
+ var crntTotalReactivePowerHexs = hexData.Skip((int)F25DataItemEnum.CrntTotalReactivePower).Take(3).ToList();
+ var crntTotalReactivePower = AnalyzeDataAccordingToA09(crntTotalReactivePowerHexs[0], crntTotalReactivePowerHexs[1], crntTotalReactivePowerHexs[2]);
+
+ var crntReactivePowerOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntReactivePowerOfA).Take(3).ToList();
+ var crntReactivePowerOfA = AnalyzeDataAccordingToA09(crntReactivePowerOfAHexs[0], crntReactivePowerOfAHexs[1], crntReactivePowerOfAHexs[2]);
+
+ var crntReactivePowerOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntReactivePowerOfB).Take(3).ToList();
+ var crntReactivePowerOfB = AnalyzeDataAccordingToA09(crntReactivePowerOfBHexs[0], crntReactivePowerOfBHexs[1], crntReactivePowerOfBHexs[2]);
+
+ var crntReactivePowerOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntReactivePowerOfC).Take(2).ToList();
+ var crntReactivePowerOfC = AnalyzeDataAccordingToA09(crntReactivePowerOfCHexs[0], crntReactivePowerOfCHexs[1], crntReactivePowerOfCHexs[2]);
+
+ //A.5 %
+ var crntTotalPowerFactorHexs = hexData.Skip((int)F25DataItemEnum.CrntTotalPowerFactor).Take(2).ToList();
+ var crntTotalPowerFactor = AnalyzeDataAccordingToA05(crntTotalPowerFactorHexs[0], crntTotalPowerFactorHexs[1]);
+
+ var crntPowerFactorOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntPowerFactorOfA).Take(2).ToList();
+ var crntPowerFactorOfA = AnalyzeDataAccordingToA05(crntPowerFactorOfAHexs[0], crntPowerFactorOfAHexs[1]);
+
+ var crntPowerFactorOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntPowerFactorOfB).Take(2).ToList();
+ var crntPowerFactorOfB = AnalyzeDataAccordingToA05(crntPowerFactorOfBHexs[0], crntPowerFactorOfBHexs[1]);
+
+ var crntPowerFactorOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntPowerFactorOfC).Take(2).ToList();
+ var crntPowerFactorOfC = AnalyzeDataAccordingToA05(crntPowerFactorOfCHexs[0], crntPowerFactorOfCHexs[1]);
+
+ //A.7 V
+ var crntVoltageOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntVoltageOfA).Take(2).ToList();
+ var crntVoltageOfA = AnalyzeDataAccordingToA07(crntVoltageOfAHexs[0], crntVoltageOfAHexs[1]);
+
+ var crntVoltageOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntVoltageOfB).Take(2).ToList();
+ var crntVoltageOfB = AnalyzeDataAccordingToA07(crntVoltageOfBHexs[0], crntVoltageOfBHexs[1]);
+
+ var crntVoltageOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntVoltageOfC).Take(2).ToList();
+ var crntVoltageOfC = AnalyzeDataAccordingToA07(crntVoltageOfCHexs[0], crntVoltageOfCHexs[1]);
+
+ //A.25 A
+ var crntCurrentOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntCurrentOfA).Take(3).ToList();
+ var crntCurrentOfA = AnalyzeDataAccordingToA25(crntCurrentOfAHexs[0], crntCurrentOfAHexs[1], crntCurrentOfAHexs[2]);
+
+ var crntCurrentOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntCurrentOfB).Take(3).ToList();
+ var crntCurrentOfB = AnalyzeDataAccordingToA25(crntCurrentOfBHexs[0], crntCurrentOfBHexs[1], crntCurrentOfBHexs[2]);
+
+ var crntCurrentOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntCurrentOfC).Take(3).ToList();
+ var crntCurrentOfC = AnalyzeDataAccordingToA25(crntCurrentOfCHexs[0], crntCurrentOfCHexs[1], crntCurrentOfCHexs[2]);
+
+ var crntZeroSequenceCurrentHexs = hexData.Skip((int)F25DataItemEnum.CrntZeroSequenceCurrent).Take(3).ToList();
+ var crntZeroSequenceCurrent = AnalyzeDataAccordingToA25(crntZeroSequenceCurrentHexs[0], crntZeroSequenceCurrentHexs[1], crntZeroSequenceCurrentHexs[2]);
+
+ //A.9 kVA
+ var crntTotalApparentPowerHexs = hexData.Skip((int)F25DataItemEnum.CrntTotalApparentPower).Take(3).ToList();
+ var crntTotalApparentPower = AnalyzeDataAccordingToA09(crntTotalApparentPowerHexs[0], crntTotalApparentPowerHexs[1], crntTotalApparentPowerHexs[2]);
+
+ var crntApparentPowerOfAHexs = hexData.Skip((int)F25DataItemEnum.CrntApparentPowerOfA).Take(3).ToList();
+ var crntApparentPowerOfA = AnalyzeDataAccordingToA09(crntApparentPowerOfAHexs[0], crntApparentPowerOfAHexs[1], crntApparentPowerOfAHexs[2]);
+
+ var crntApparentPowerOfBHexs = hexData.Skip((int)F25DataItemEnum.CrntApparentPowerOfB).Take(3).ToList();
+ var crntApparentPowerOfB = AnalyzeDataAccordingToA09(crntApparentPowerOfBHexs[0], crntApparentPowerOfBHexs[1], crntApparentPowerOfBHexs[2]);
+
+ var crntApparentPowerOfCHexs = hexData.Skip((int)F25DataItemEnum.CrntApparentPowerOfC).Take(3).ToList();
+ var crntApparentPowerOfC = AnalyzeDataAccordingToA09(crntApparentPowerOfCHexs[0], crntApparentPowerOfCHexs[1], crntApparentPowerOfCHexs[2]);
+
+ return new Analyze3761Data()
+ {
+ AFN = 12,
+ FN = 25,
+ Text = "当前三相及总有/无功功率功率因数",
+ DataUpChilds = new List()
+ {
+ new Analyze3761DataUpChild(1,"终端抄表时间",readingTime.ToString(),1),
+ new Analyze3761DataUpChild(2,"当前总有功功率",crntTotalActivePower.ToString(),2),
+ new Analyze3761DataUpChild(3,"当前A相有功功率",crntActivePowerOfA.ToString(),3),
+ new Analyze3761DataUpChild(4,"当前B相有功功率",crntActivePowerOfB.ToString(),4),
+ new Analyze3761DataUpChild(5,"当前C相有功功率",crntActivePowerOfC.ToString(),5),
+ new Analyze3761DataUpChild(6,"当前总无功功率",crntTotalReactivePower.ToString(),6),
+ new Analyze3761DataUpChild(7,"当前A相无功功率",crntReactivePowerOfA.ToString(),7),
+ new Analyze3761DataUpChild(8,"当前B相无功功率",crntReactivePowerOfB.ToString(),8),
+ new Analyze3761DataUpChild(9,"当前C相无功功率",crntReactivePowerOfC.ToString(),9),
+ new Analyze3761DataUpChild(10,"当前总功率因数",crntTotalPowerFactor.ToString(),10),
+ new Analyze3761DataUpChild(11,"当前A相功率因数",crntPowerFactorOfA.ToString(),11),
+ new Analyze3761DataUpChild(12,"当前B相功率因数",crntPowerFactorOfB.ToString(),12),
+ new Analyze3761DataUpChild(13,"当前C相功率因数",crntPowerFactorOfC.ToString(),13),
+ new Analyze3761DataUpChild(14,"当前A相电压",crntVoltageOfA.ToString(),14),
+ new Analyze3761DataUpChild(15,"当前B相电压",crntVoltageOfB.ToString(),15),
+ new Analyze3761DataUpChild(16,"当前C相电压",crntVoltageOfC.ToString(),16),
+ new Analyze3761DataUpChild(17,"当前A相电流",crntCurrentOfA.ToString(),17),
+ new Analyze3761DataUpChild(18,"当前B相电流",crntCurrentOfB.ToString(),18),
+ new Analyze3761DataUpChild(19,"当前C相电流",crntCurrentOfC.ToString(),19),
+ new Analyze3761DataUpChild(20,"当前零序电流",crntZeroSequenceCurrent.ToString(),20),
+ new Analyze3761DataUpChild(21,"当前总视在功率",crntTotalApparentPower.ToString(),21),
+ new Analyze3761DataUpChild(22,"当前A相视在功率",crntApparentPowerOfA.ToString(),22),
+ new Analyze3761DataUpChild(23,"当前B相视在功率",crntApparentPowerOfB.ToString(),23),
+ new Analyze3761DataUpChild(24,"当前C相视在功率",crntApparentPowerOfC.ToString(),24),
+ }
+ };
+
+ //var f25ReadingAnalyze = new F25ReadingAnalyze()
+ //{
+ // ReadingTime = readingTime.ToLocalTime(),
+ // CrntTotalActivePower = crntTotalActivePower,
+ // CrntActivePowerOfA = crntActivePowerOfA,
+ // CrntActivePowerOfB = crntActivePowerOfB,
+ // CrntActivePowerOfC = crntActivePowerOfC,
+ // CrntTotalReactivePower = crntTotalReactivePower,
+ // CrntReactivePowerOfA = crntReactivePowerOfA,
+ // CrntReactivePowerOfB = crntReactivePowerOfB,
+ // CrntReactivePowerOfC = crntReactivePowerOfC,
+ // CrntTotalPowerFactor = crntTotalPowerFactor,
+ // CrntPowerFactorOfA = crntPowerFactorOfA,
+ // CrntPowerFactorOfB = crntPowerFactorOfB,
+ // CrntPowerFactorOfC = crntPowerFactorOfC,
+ // CrntVoltageOfA = crntVoltageOfA,
+ // CrntVoltageOfB = crntVoltageOfB,
+ // CrntVoltageOfC = crntVoltageOfC,
+ // CrntCurrentOfA = crntCurrentOfA,
+ // CrntCurrentOfB = crntCurrentOfB,
+ // CrntCurrentOfC = crntCurrentOfC,
+ // CrntZeroSequenceCurrent = crntZeroSequenceCurrent,
+ // CrntTotalApparentPower = crntTotalApparentPower,
+ // CrntApparentPowerOfA = crntApparentPowerOfA,
+ // CrntApparentPowerOfB = crntApparentPowerOfB,
+ // CrntApparentPowerOfC = crntApparentPowerOfC
+ //};
+
+ //return f25ReadingAnalyze;
+
+ }
+
+ ///
+ /// 解析终端版本信息抄读
+ ///
+ ///
+ ///
+ /// //TerminalVersionInfoAnalyze
+ public virtual Analyze3761Data AnalyzeTerminalVersionInfoReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+
+ var makerNo = string.Join("",hexData.Take(4).Select(s => (char)s.HexToDec()));//厂商代码
+ var deviceNo = string.Join("", hexData.Skip((int)TerminalVersionInfoEnum.DeviceNo).Take(8).Select(s => (char)s.HexToDec()));//设备编号
+ var softwareVersionNo = string.Join("", hexData.Skip((int)TerminalVersionInfoEnum.SoftwareVersionNo).Take(4).Select(s => (char)s.HexToDec()));//软件版本号
+ var softwareReleaseDateList = hexData.Skip((int)TerminalVersionInfoEnum.SoftwareReleaseDate).Take(3).ToList();
+ var softwareReleaseDate = $"20{AnalyzeDataAccordingToA20(softwareReleaseDateList[0], softwareReleaseDateList[1], softwareReleaseDateList[2])}";//软件发布日期
+ var capacityInformationCode = string.Join("", hexData.Skip((int)TerminalVersionInfoEnum.CapacityInformationCode).Take(11).Select(s => (char)s.HexToDec()));//容量信息码
+ var protocolVersionNo = string.Join("", hexData.Skip((int)TerminalVersionInfoEnum.ProtocolVersionNo).Take(4).Select(s => (char)s.HexToDec()));//通信协议编号
+ var hardwareVersionNo = string.Join("", hexData.Skip((int)TerminalVersionInfoEnum.HardwareVersionNo).Take(4).Select(s => (char)s.HexToDec()));//硬件版本号
+ var hardwareReleaseDateList = hexData.Skip((int)TerminalVersionInfoEnum.HardwareReleaseDate).Take(3).ToList();
+ var hardwareReleaseDate = $"20{AnalyzeDataAccordingToA20(hardwareReleaseDateList[0], hardwareReleaseDateList[1], hardwareReleaseDateList[2])}";//软件发布日期
+
+ return new Analyze3761Data()
+ {
+ AFN = 09,
+ FN = 1,
+ Text = "终端版本信息",
+ DataUpChilds = new List()
+ {
+ new Analyze3761DataUpChild(1,"厂商代码",makerNo.ToString(),1),
+ new Analyze3761DataUpChild(2,"设备编号",deviceNo.ToString(),2),
+ new Analyze3761DataUpChild(3,"软件版本号",softwareVersionNo.ToString(),3),
+ new Analyze3761DataUpChild(4,"软件发布日期",softwareReleaseDate.ToString(),4),
+ new Analyze3761DataUpChild(5,"容量信息码",capacityInformationCode.ToString(),5),
+ new Analyze3761DataUpChild(6,"通信协议编号",protocolVersionNo.ToString(),6),
+ new Analyze3761DataUpChild(7,"硬件版本号",hardwareVersionNo.ToString(),7),
+ new Analyze3761DataUpChild(8,"软件发布日期",hardwareReleaseDate.ToString(),8),
+ }
+ };
+ //return new TerminalVersionInfoAnalyze()
+ //{
+ // MakerNo = makerNo,
+ // DeviceNo = deviceNo,
+ // SoftwareVersionNo = softwareVersionNo,
+ // SoftwareReleaseDate = DateTime.Parse(softwareReleaseDate).ToLocalTime(),
+ // CapacityInformationCode = capacityInformationCode,
+ // ProtocolVersionNo = protocolVersionNo,
+ // HardwareVersionNo = hardwareVersionNo,
+ // HardwareReleaseDate = DateTime.Parse(hardwareReleaseDate).ToLocalTime()
+ //};
+ }
+
+ ///
+ /// 解析相位角
+ ///
+ ///
+ ///
+ ///
+ public virtual Analyze3761Data AnalyzeATypeOfDataItems49ReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexData = GetHexData(messageReceived.MessageHexString);
+
+ var uabUaList = hexData.Take(2).ToList();
+ var uabUa = AnalyzeDataAccordingToA05(uabUaList[0], uabUaList[1]); //单位 度
+
+ var ubList = hexData.Skip((int)ATypeOfDataItems49.Ub).Take(2).ToList();
+ var ub = AnalyzeDataAccordingToA05(ubList[0], ubList[1]);
+
+ var ucbUcList = hexData.Skip((int)ATypeOfDataItems49.UcbUc).Take(2).ToList();
+ var ucbUc = AnalyzeDataAccordingToA05(ucbUcList[0], ucbUcList[1]);
+
+ var iaList = hexData.Skip((int)ATypeOfDataItems49.Ia).Take(2).ToList();
+ var ia = AnalyzeDataAccordingToA05(iaList[0], iaList[1]);
+
+ var ibList = hexData.Skip((int)ATypeOfDataItems49.Ib).Take(2).ToList();
+ var ib = AnalyzeDataAccordingToA05(ibList[0], ibList[1]);
+
+ var icList = hexData.Skip((int)ATypeOfDataItems49.Ic).Take(2).ToList();
+ var ic = AnalyzeDataAccordingToA05(icList[0], icList[1]);
+
+ return new Analyze3761Data()
+ {
+ AFN = 12,
+ FN = 49,
+ Text = "相位角",
+ DataUpChilds =
+ [
+ new Analyze3761DataUpChild(1, "UabUa相位角", uabUa.ToString(), 1),
+ new Analyze3761DataUpChild(2, "Ub相位角", ub.ToString(), 2),
+ new Analyze3761DataUpChild(3, "UcbUc相位角", ucbUc.ToString(), 3),
+ new Analyze3761DataUpChild(4, "Ia相位角", ia.ToString(), 4),
+ new Analyze3761DataUpChild(5, "Ib相位角", ib.ToString(), 5),
+ new Analyze3761DataUpChild(6, "Ic相位角", ic.ToString(), 6)
+ ]
+ };
+ }
+
+ ///
+ /// 解析终端时间抄读
+ ///
+ ///
+ ///
+
+ public virtual void AnalyzeTerminalTimeReadingDataAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexDatas = GetHexData(messageReceived.MessageHexString);
+ var time = Appendix.Appendix_A1(hexDatas.Take(6).ToList());
+ }
+
+ /////
+ ///// 通用解析
+ /////
+ /////
+ /////
+ /////
+ //public virtual TB3761 AnalyzeReadingDataAsync(MessageReceived messageReceived,
+ // Action? sendAction = null)
+ //{
+ // var hexStringList = messageReceived.MessageHexString.StringToPairs();
+ // var afn = (AFN)hexStringList.GetAnalyzeValue(CommandChunkEnum.AFN);
+ // var fn = (int)hexStringList.GetAnalyzeValue(CommandChunkEnum.FN);
+
+ // var tb3761 = QGDW3761Config.CommandList.FirstOrDefault(it => it.Afn == afn);
+ // if (tb3761 == null) return null;
+
+ // var tb3761Fn = tb3761.FnList.FirstOrDefault(it => it.Fn == fn);
+ // if (tb3761Fn == null) return null;
+
+ // var analyzeValue = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data);
+
+ // var m = 0;
+ // var rateNumberUpSort = -1;
+ // var rateNumberUp = tb3761Fn.UpList.FirstOrDefault(it => it.Name.Contains("费率数M"));
+ // if (rateNumberUp != null)
+ // {
+ // var rateNumber = analyzeValue.Skip(rateNumberUp.DataIndex).Take(rateNumberUp.DataCount).FirstOrDefault();
+ // m = Convert.ToInt32(rateNumber);
+ // rateNumberUpSort = rateNumberUp.Sort;
+ // }
+
+ // foreach (var up in tb3761Fn.UpList)
+ // {
+ // var dataIndex = up.DataIndex;
+ // if (dataIndex == 0 && up.Sort > rateNumberUpSort)
+ // {
+ // var sum1 = tb3761Fn.UpList.Where(it => it.Sort < up.Sort)
+ // .Sum(it => it.DataCount);
+ // var sum2 = tb3761Fn.UpList.Where(it => it.Sort < up.Sort && it.Tb3761UpChildlList.Count > 0)
+ // .Sum(it => it.Tb3761UpChildlList.Sum(c=> m * c.DataCount));
+ // dataIndex = sum1 + sum2;
+ // }
+
+ // var value = AnalyzeDataAccordingDataType(analyzeValue, dataIndex, up.DataCount, up.DataType);
+ // if (value != null)
+ // {
+ // up.Value = value.ToString();
+ // }
+ // if (up.Tb3761UpChildlList.Count > 0) //复费率根据费率数来解析
+ // {
+ // var repeatCount = m;
+ // foreach (var upChild in up.Tb3761UpChildlList)
+ // {
+ // for (var j = 0; j < repeatCount; j++)
+ // {
+ // var val = AnalyzeDataAccordingDataType(analyzeValue, dataIndex, upChild.DataCount, upChild.DataType);
+ // if (val != null)
+ // {
+ // upChild.Name = string.Format(upChild.Name, j + 1);
+ // upChild.Value = val.ToString();
+ // }
+ // dataIndex += upChild.DataCount;
+ // }
+ // }
+
+ // }
+ // }
+
+ // return tb3761;
+ //}
+
+ /////
+ ///// 通用解析 日冻结曲线类
+ /////
+ /////
+ /////
+ /////
+ //public virtual TB3761 AnalyzeReadingTdcDataAsync(MessageReceived messageReceived,
+ // Action? sendAction = null)
+ //{
+
+ // var hexStringList = messageReceived.MessageHexString.StringToPairs();
+ // var afn = (AFN)hexStringList.GetAnalyzeValue(CommandChunkEnum.AFN);
+ // var fn = (int)hexStringList.GetAnalyzeValue(CommandChunkEnum.FN);
+
+ // var tb3761 = QGDW3761Config.CommandTdcList.FirstOrDefault(it => it.Afn == afn);
+ // if (tb3761 == null) return null;
+
+ // var tb3761Fn = tb3761.FnList.FirstOrDefault(it => it.Fn == fn);
+ // if (tb3761Fn == null) return null;
+
+ // var analyzeValue = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data);
+
+ // foreach (var up in tb3761Fn.UpList)
+ // {
+ // var value = AnalyzeDataAccordingDataType(analyzeValue, up.DataIndex, up.DataCount, up.DataType);
+ // if (value != null)
+ // {
+ // up.Value = value.ToString();
+
+ // if (up.Tb3761UpChildlList.Count > 0)
+ // {
+ // var dataIndex = up.DataIndex;
+ // var repeatCount = (int)value;
+ // foreach (var upChild in up.Tb3761UpChildlList)
+ // {
+ // for (var j = 0; j < repeatCount; j++)
+ // {
+ // var val = AnalyzeDataAccordingDataType(analyzeValue, dataIndex, upChild.DataCount, upChild.DataType);
+ // if (val != null)
+ // {
+ // upChild.Value = val.ToString();
+ // upChild.Name = string.Format(upChild.Name, j + 1);
+ // }
+ // dataIndex += upChild.DataCount;
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ // return tb3761;
+ // //var freezeDensity = (FreezeDensity)Convert.ToInt32(hexDatas.Skip(5).Take(1));
+ // //var addMinute = 0;
+ // //switch (freezeDensity)
+ // //{
+ // // case FreezeDensity.No:break;
+ // // case FreezeDensity.Min15:
+ // // addMinute = 15;
+ // // break;
+ // // case FreezeDensity.Min30:
+ // // addMinute = 30;
+ // // break;
+ // // case FreezeDensity.Min60:
+ // // addMinute = 60;
+ // // break;
+ // // case FreezeDensity.Min5: break;
+ // // addMinute = 5;
+ // // case FreezeDensity.Min1:
+ // // addMinute = 1;
+ // // break;
+ // // }
+ //}
+
+ private object? AnalyzeDataAccordingDataType(List analyzeValue, int dataIndex,int dataCount,string dataType)
+ {
+ var valueList = analyzeValue.Skip(dataIndex).Take(dataCount).ToList();
+ object? value = null;
+ switch (dataType)
+ {
+ case "BIN":
+ value = Convert.ToInt32(valueList[0]);
+ break;
+ case "A05":
+ if (valueList.Count == 2)
+ {
+ value = AnalyzeDataAccordingToA05(valueList[0], valueList[1]);
+ }
+ break;
+ case "A09":
+ if (valueList.Count == 3)
+ {
+ value = AnalyzeDataAccordingToA09(valueList[0], valueList[1], valueList[2]);
+ }
+ break;
+ case "A14":
+ if (valueList.Count == 5)
+ {
+ value = AnalyzeDataAccordingToA15(valueList[0], valueList[1], valueList[2], valueList[3], valueList[4]);
+ }
+ break;
+ case "A15":
+ if (valueList.Count == 5)
+ {
+ //var minutes = Convert.ToInt32(analyzeValue[0]); // 获取当前分钟数
+ //var hours = Convert.ToInt32(analyzeValue[1]); // 获取当前小时数
+ //var day = Convert.ToInt32(analyzeValue[2]); // 获取当前日期的日数
+ //var month = Convert.ToInt32(analyzeValue[3]); // 获取当前月份
+ //var year = Convert.ToInt32(analyzeValue[4]); // 获取当前日期的年份
+ value = AnalyzeDataAccordingToA15(valueList[0], valueList[1], valueList[2], valueList[3], valueList[4]);
+ }
+ break;
+ case "ATd_d":
+ var day = valueList[0];
+ var month = valueList[1];
+ var year = valueList[2];
+ break;
+ case "ATd_m":
+ var tdmMonth = valueList[0];
+ var tdmYear = valueList[1];
+ break;
+ }
+
+ return value;
+ }
+
+ ///
+ /// 解析透明转发 应答
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task AnalyzeTransparentForwardingAnswerAsync(MessageReceived messageReceivedEvent, Action? sendAction = null)
+ {
+ var hexDatas = GetHexData(messageReceivedEvent.MessageHexString);
+
+ var port = hexDatas[0].HexToDec();
+
+ var count = hexDatas[1].HexToDec();
+
+ var dataList = hexDatas.Skip(2).Take(count).ToList();
+
+ //645
+ if (dataList[0].IsStartStr() && dataList[hearderLen - 1].IsStartStr())
+ {
+
+ }
+ else if (dataList[0].IsStartStr())//188 水表只有开头是68
+ {
+ AnalyzeWaterMeterReadData(dataList);
+ }
+ }
+
+ ///
+ /// 解析透明转发 应答结果
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task AnalyzeTransparentForwardingAnswerResultAsync(MessageReceived messageReceived, Action? sendAction = null)
+ {
+ var hexDatas = GetHexData(messageReceived.MessageHexString);
+
+ var port = hexDatas[0].HexToDec();
+
+ //A.12
+ var a = hexDatas.Skip(1).Take(6).ToList();
+
+ var result = hexDatas.Skip(7).Take(1).FirstOrDefault().HexToDec();
+ var transparentForwardingFlag = (TransparentForwardingFlagEnum)result;
+ }
+
+ ///
+ /// 获取命令数据单元-数据体
+ ///
+ ///
+ ///
+ public static List GetHexData(string messageHexString)
+ {
+ var hexStringList = messageHexString.StringToPairs();
+ var analyzeValue = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data);
+ return analyzeValue;
+ }
+
+ ///
+ /// 解析时间标签
+ ///
+ ///
+ public void AnalysisTp(List hexData)
+ {
+ var pFC = hexData[0].HexToDec();//启动帧帧序号计数器
+ var seconds = Convert.ToInt32(hexData[1]); // 获取当前秒数
+ var minutes = Convert.ToInt32(hexData[2]); // 获取当前分钟数
+ var hours = Convert.ToInt32(hexData[3]); // 获取当前小时数
+ var day = Convert.ToInt32(hexData[4]); // 获取当前日期的日数
+ var delayTime = hexData[5].HexToDec();//延迟时间 min
+ }
+
+ #region 报文指定的数据格式
+
+ ///
+ /// 根据A05解析数据
+ ///
+ /// 个位和十分位
+ /// 百位和十位
+ ///
+ public decimal AnalyzeDataAccordingToA05(string singleDigitNumberAndDeciles, string hundredDigitNumbersAndTenDigitNumber)
+ {
+ if (singleDigitNumberAndDeciles.IsErrorData() && hundredDigitNumbersAndTenDigitNumber.IsErrorData())
+ {
+ return 0;
+ }
+ var bin1 = hundredDigitNumbersAndTenDigitNumber.HexToBin().PadLeft(8, '0');
+ var hundredDigitNumbers = bin1.Substring(1, 3).BinToDec();//百位
+ var tenDigitNumber = bin1.Substring(4).BinToDec();//十位
+
+ var bin2 = singleDigitNumberAndDeciles.HexToBin().PadLeft(8, '0');
+ var singleDigitNumber = bin1.Substring(0, 4).BinToDec();//个位
+ var deciles = bin1.Substring(4).BinToDec();//十分位
+
+ var value = decimal.Parse($"{hundredDigitNumbers}{tenDigitNumber}{singleDigitNumber}.{deciles}");
+ return value;
+ }
+
+ ///
+ /// 数据格式07
+ ///
+ /// 个位、十分位
+ /// 百位、十位
+ ///
+ public decimal AnalyzeDataAccordingToA07(string singleDigitNumberAndDeciles, string hundredDigitNumbersAndTenDigitNumber)
+ {
+ if (singleDigitNumberAndDeciles.IsErrorData() && hundredDigitNumbersAndTenDigitNumber.IsErrorData())
+ {
+ return 0;
+ }
+ var bin1 = hundredDigitNumbersAndTenDigitNumber.HexToBin().PadLeft(8, '0');
+ var hundredDigitNumbers = bin1.Substring(1, 3).BinToDec();//百位
+ var tenDigitNumber = bin1.Substring(4).BinToDec();//十位
+
+ var bin2 = singleDigitNumberAndDeciles.HexToBin().PadLeft(8, '0');
+ var singleDigitNumber = bin2.Substring(0, 4).BinToDec();//个位
+ var deciles = bin2.Substring(4).BinToDec();//十分位
+
+ var value = decimal.Parse($"{hundredDigitNumbers}{tenDigitNumber}{singleDigitNumber}.{deciles}");
+ return value;
+ }
+
+ ///
+ /// 数据格式09
+ ///
+ /// 千分位和万分位
+ /// 十分位和百分位
+ /// 十位和个位
+ ///
+ public decimal AnalyzeDataAccordingToA09(string thousandthPercentileAndTenThousandPositions, string decilesAndPercentile, string tenAndSingleDigit)
+ {
+ if (thousandthPercentileAndTenThousandPositions.IsErrorData() && decilesAndPercentile.IsErrorData() && tenAndSingleDigit.IsErrorData())
+ {
+ return 0;
+ }
+
+ var bin3 = tenAndSingleDigit.HexToBin().PadLeft(8, '0');
+ var tenDigitNumber = bin3.Substring(1, 3).BinToDec();//十位
+ var singleDigitNumber = bin3.Substring(4).BinToDec();//个位
+
+ var value = decimal.Parse($"{tenDigitNumber}{singleDigitNumber}.{decilesAndPercentile}{thousandthPercentileAndTenThousandPositions}");
+ return value;
+
+ //var bin3 = hex3.HexToBin().PadLeft(8, '0');
+ //var thousandthPercentile = bin3.Substring(0, 4).BinToDec();//千分位
+ //var tenThousandPositions = bin3.Substring(4).BinToDec();//万分位
+
+ //var bin2 = hex2.HexToBin().PadLeft(8, '0');
+ //var deciles = bin2.Substring(0, 4).BinToDec();//十分位
+ //var percentile = bin2.Substring(4).BinToDec();//百分位
+
+
+ }
+
+ ///
+ /// 数据格式12
+ ///
+ /// 十位 个位
+ /// 千位 百位
+ /// 十万位 万位
+ /// 千万位 百万位
+ /// 十亿位 亿位
+ /// 千亿位 百亿位
+ ///
+ public string AnalyzeDataAccordingToA12(string tenDigitAndSingleDigitNumber, string thousandAndHundredsOfPosition, string hundredThousandAndTenThousandOfPosition,
+ string millionsAndMillionOfPosition, string hundredMillionAndBillionOfPosition, string hundredBillionsAndBillionsOfPosition)
+ {
+ var value = $"{hundredBillionsAndBillionsOfPosition}{hundredMillionAndBillionOfPosition}{millionsAndMillionOfPosition}" +
+ $"{hundredThousandAndTenThousandOfPosition}{thousandAndHundredsOfPosition}{tenDigitAndSingleDigitNumber}";
+
+ return value;
+ }
+
+ ///
+ /// 数据格式14
+ ///
+ /// 千分,万分
+ /// 十分、百分
+ /// 十位、个位
+ /// 千位、百位
+ /// 十万位、万位
+ ///
+ public decimal AnalyzeDataAccordingToA14(string tenThousandPositionsAndThousandthPercentile, string decilesAndPercentile,
+ string tenDigitNumberAndSingleDigitNumber, string thousandAndHundredsOfPosition, string hundredThousandAndTenThousandOfPosition)
+ {
+ if (tenThousandPositionsAndThousandthPercentile.IsErrorData() && decilesAndPercentile.IsErrorData() && tenDigitNumberAndSingleDigitNumber.IsErrorData()
+ && thousandAndHundredsOfPosition.IsErrorData() && hundredThousandAndTenThousandOfPosition.IsErrorData())
+ return 0;
+
+ var value = decimal.Parse($"{hundredThousandAndTenThousandOfPosition}{thousandAndHundredsOfPosition}" +
+ $"{tenDigitNumberAndSingleDigitNumber}.{decilesAndPercentile}{tenThousandPositionsAndThousandthPercentile}");
+
+ return value;
+ }
+
+ ///
+ /// 数据格式A.15
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public DateTime AnalyzeDataAccordingToA15(string minuteHex, string hourHex, string dayHex, string monthHex, string yearHex)
+ {
+ var centuryString = (DateTime.Now.Year / 100).ToString();
+ var time = DateTime.Parse($"{centuryString}{yearHex}-{monthHex}-{dayHex} {hourHex}:{minuteHex}:00");
+ return time;
+ //正常转换方式
+ //var bin1 = hex1.HexToBin().PadLeft(8, '0');
+ //var tenDigitNumberOfMinute = bin1.Substring(0, 4).BinToDec();//十位
+ //var singleDigitNumberOfMinute = bin1.Substring(4).BinToDec();//个位
+ //var minute = Convert.ToInt32($"{tenDigitNumberOfMinute}{singleDigitNumberOfMinute}");
+
+ //var bin2 = hex2.HexToBin().PadLeft(8, '0');
+ //var tenDigitNumberOfHour = bin2.Substring(0, 4).BinToDec();//十位
+ //var singleDigitNumberOfHour = bin2.Substring(4).BinToDec();//个位
+
+ //var bin3 = hex3.HexToBin().PadLeft(8, '0');
+ //var tenDigitNumberOfDay = bin3.Substring(0, 4).BinToDec();//十位
+ //var singleDigitNumberOfDay = bin3.Substring(4).BinToDec();//个位
+
+ //var bin4 = hex4.HexToBin().PadLeft(8, '0');
+ //var tenDigitNumberOfMonth = bin4.Substring(0, 4).BinToDec();//十位
+ //var singleDigitNumberOfMonth = bin4.Substring(4).BinToDec();//个位
+
+ //var bin5 = hex5.HexToBin().PadLeft(8, '0');
+ //var tenDigitNumberOfYear = bin5.Substring(0, 4).BinToDec();//十位
+ //var singleDigitNumberOfYear = bin5.Substring(4).BinToDec();//个位
+ }
+
+
+ ///
+ /// 数据格式20
+ ///
+ ///
+ ///
+ ///
+ ///
+ public DateTime AnalyzeDataAccordingToA20(string dayHex, string monthHex, string yearHex)
+ {
+ var centuryString = (DateTime.Now.Year / 100).ToString();
+ var time = DateTime.Parse($"{centuryString}{yearHex}-{monthHex}-{dayHex}");
+ return time;
+
+ }
+
+ ///
+ /// 数据格式25
+ ///
+ /// 百分、千分位
+ /// 个位、十分位
+ /// 百位、十位
+ ///
+
+ public decimal AnalyzeDataAccordingToA25(string percentileAndThousandthPercentile, string singleDigitNumberAndDeciles, string hundredDigitNumbersAndTenDigitNumber)
+ {
+ if (percentileAndThousandthPercentile.IsErrorData() && singleDigitNumberAndDeciles.IsErrorData() && hundredDigitNumbersAndTenDigitNumber.IsErrorData())
+ return 0;
+
+ var bin1 = hundredDigitNumbersAndTenDigitNumber.HexToBin().PadLeft(8, '0');
+ var hundredDigitNumbers = bin1.Substring(1, 3).BinToDec();//百位
+ var tenDigitNumber = bin1.Substring(4).BinToDec();//十位
+
+ var bin2 = singleDigitNumberAndDeciles.HexToBin().PadLeft(8, '0');
+ var singleDigitNumber = bin2.Substring(0, 4).BinToDec();//个位
+ var deciles = bin1.Substring(4).BinToDec();//十分位
+
+ var value = decimal.Parse($"{hundredDigitNumbers}{tenDigitNumber}{singleDigitNumber}.{deciles}{percentileAndThousandthPercentile}");
+ return value;
+ }
+
+ #endregion
+
+ #region 645
+ ///
+ /// 解析读取表地址
+ ///
+ ///
+ ///
+ public List AnalyzeAmmeterReadMeterAddress_10_105(List dataList)
+ {
+ var values = new List();
+ //表地址
+ var addressList = dataList.GetRange(1, 6);
+ addressList.Reverse();
+ var address = string.Join("", addressList);
+ values.Add(address);
+ //控制码
+ var controlCode = dataList.GetRange(8, 1)[0];
+ values.Add(controlCode);
+ //长度
+ var len = dataList.GetRange(9, 1)[0].HexToDec();
+ //values.Add(len.ToString());
+ //数据域
+ var dataField = dataList.GetRange(10, len);
+ if (dataField.Count > 0)
+ {
+ string dataMark = string.Join("", dataField.GetRange(0, 4).AddHex33());
+ values.Add(dataMark);//数据标识
+ var readValue = dataField.GetRange(4, len - 4).ReduceHex33();//值
+ readValue.Reverse();
+ //var valueData = GetValue>(readValue, (AppendixEnums)Enum.Parse(typeof(AppendixEnums), dataMark));
+ values.AddRange(readValue);
+ }
+ return values;
+ }
+
+
+ public void AnalyzeAmmeterReadMeterAddress_10_103(List dataList)
+ {
+ var data = AnalyzeAmmeterReadMeterAddress_10_105(dataList);
+ var validData = data[2].Equals("94") ? true : false;
+ var remark = validData ? "成功" : "失败";
+ }
+
+ public void AnalyzeAutoUpSwtichRead_0A_68(List dataList)
+ {
+ var isOpen = dataList[4].Equals("55");
+ }
+
+ #endregion
+
+ #region 188
+
+ public void AnalyzeWaterMeter188Data(List dataList)
+ {
+ var waterMeterType = dataList[(int)WaterMeterReadEnum.Type];
+ var addressList = dataList.Skip((int)WaterMeterReadEnum.Address).Take(6).ToList();
+ addressList.Reverse();
+ var address = string.Join("", addressList);
+ address = address.Substring(address.Length - 12);
+ var controlCode = dataList[(int)WaterMeterReadEnum.ControlCode];
+ switch (controlCode)
+ {
+ case "81":
+ AnalyzeWaterMeterReadData(dataList);
+ break;
+ case "84":
+ AnalyzeWaterMeterValueResult(dataList);
+ break;
+ }
+
+ }
+
+ ///
+ /// 解析水表读数据
+ ///
+ ///
+ public void AnalyzeWaterMeterReadData(List dataList)
+ {
+ var accumulativeWaterflowList = dataList.Skip((int)WaterMeterReadEnum.AccumulativeWaterflow).Take(5).ToList();
+ //xxxxxx.xx
+ var accumulativeWaterflow = decimal.Parse(
+ $"{accumulativeWaterflowList[3]}{accumulativeWaterflowList[2]}{accumulativeWaterflowList[1]}." +
+ $"{accumulativeWaterflowList[0]}");
+ }
+
+ ///
+ /// 解析水表阀控结果
+ ///
+ ///
+ public bool AnalyzeWaterMeterValueResult(List dataList)
+ {
+ return true;
+ }
+
+ #endregion
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol/Abstracts/ProtocolPlugin.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Abstracts/ProtocolPlugin.cs
rename to protocols/JiShe.CollectBus.Protocol/Abstracts/ProtocolPlugin.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Adapters/StandardFixedHeaderDataHandlingAdapter.cs b/protocols/JiShe.CollectBus.Protocol/Adapters/StandardFixedHeaderDataHandlingAdapter.cs
new file mode 100644
index 0000000..0984a8f
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Adapters/StandardFixedHeaderDataHandlingAdapter.cs
@@ -0,0 +1,27 @@
+using JiShe.CollectBus.Protocol.Contracts.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TouchSocket.Core;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Adapters
+{
+ public class StandardFixedHeaderDataHandlingAdapter : CustomFixedHeaderDataHandlingAdapter
+ {
+ ///
+ /// 接口实现,指示固定包头长度
+ ///
+ public override int HeaderLength => 3;
+
+ ///
+ /// 获取新实例
+ ///
+ ///
+ protected override CustomFixedHeaderRequestInfo GetInstance()
+ {
+ return new CustomFixedHeaderRequestInfo();
+ }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisData/Appendix.cs b/protocols/JiShe.CollectBus.Protocol/AnalysisData/Appendix.cs
new file mode 100644
index 0000000..f68268c
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/AnalysisData/Appendix.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JiShe.CollectBus.Common.Extensions;
+
+namespace JiShe.CollectBus.Protocol.Contracts.AnalysisData
+{
+ ///
+ /// 附录
+ ///
+ public static class Appendix
+ {
+ ///
+ /// 附录1 A1格式
+ ///
+ ///
+ public static string Appendix_A1(List data)
+ {
+ var seconds = data[0];
+ var minutes = data[1];
+ var hours = data[2];
+ var day = data[3];
+ var binString = data[4].HexToBin();
+ var months = binString.Substring(3, 1).BinToDec() * 10 + Convert.ToInt32(binString.Substring(4, 4).BinToHex());
+ var week = binString.Substring(0, 3).BinToHex();
+ var year = $"{DateTime.Now.ToString("yyyy").Substring(0, 2)}{data[5]}";
+ return $"{year}-{months.ToString().PadLeft(2, '0')}-{day} {hours}:{minutes}:{seconds}_{week}";
+ }
+
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs b/protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs
new file mode 100644
index 0000000..628934a
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/AnalysisStrategyContext.cs
@@ -0,0 +1,33 @@
+using JiShe.CollectBus.Protocol.Contracts.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
+{
+
+ public class AnalysisStrategyContext(IServiceProvider provider)
+ {
+ private readonly IServiceProvider _provider = provider;
+
+ ///
+ /// 执行策略
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Task ExecuteAsync(string type, TInput input)
+ {
+ var factory = _provider.GetRequiredService>();
+ var strategy = (IAnalysisStrategy)factory(type, typeof(TInput), typeof(TResult));
+ return strategy.ExecuteAsync(input);
+ }
+ }
+
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Attributes/ProtocolNameAttribute.cs b/protocols/JiShe.CollectBus.Protocol/Attributes/ProtocolNameAttribute.cs
new file mode 100644
index 0000000..a04af71
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Attributes/ProtocolNameAttribute.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Attributes
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class ProtocolNameAttribute(string name) : Attribute
+ {
+ public string Name { get; set; } = name;
+ }
+}
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..dcd12fb
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Interfaces/IAnalysisStrategy.cs
@@ -0,0 +1,15 @@
+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/Interfaces/IProtocolService.cs b/protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolService.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolService.cs
rename to protocols/JiShe.CollectBus.Protocol/Interfaces/IProtocolService.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj b/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj
index 3a7cc07..495dbf1 100644
--- a/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj
+++ b/protocols/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj
@@ -4,24 +4,25 @@
net8.0
enable
enable
-
- preview
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
diff --git a/protocols/JiShe.CollectBus.Protocol/Models/CustomFixedHeaderRequestInfo.cs b/protocols/JiShe.CollectBus.Protocol/Models/CustomFixedHeaderRequestInfo.cs
new file mode 100644
index 0000000..61ea887
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Models/CustomFixedHeaderRequestInfo.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TouchSocket.Core;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Models
+{
+ public class CustomFixedHeaderRequestInfo : IFixedHeaderRequestInfo
+ {
+ ///
+ /// 报文开始前缀
+ ///
+ public string StartPrefix { get; set; } = "68";
+
+ ///
+ /// 报文结束后缀
+ ///
+ public string EndPrefix { get; set; } = "16";
+
+ ///
+ /// 头部长度
+ ///
+ public int HeadLength = 5;
+
+ ///
+ /// 固定长度
+ ///
+ private const int FixedLength = 17;
+
+ ///
+ /// 报文长度
+ ///
+ public int PacketLength { get; set; }
+
+ ///
+ /// 控制域 C
+ ///
+ public int ControlDomain { get; set; }
+
+ public bool OnParsingHeader(ReadOnlySpan header)
+ {
+ //throw new NotImplementedException();
+ return true;
+ }
+
+ public bool OnParsingBody(ReadOnlySpan body)
+ {
+ //throw new NotImplementedException();
+ return true;
+
+ }
+
+ public int BodyLength { get; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/ProtocolBuildRequest.cs b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildRequest.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/ProtocolBuildRequest.cs
rename to protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildRequest.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/ProtocolBuildResponse.cs b/protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/ProtocolBuildResponse.cs
rename to protocols/JiShe.CollectBus.Protocol/Models/ProtocolBuildResponse.cs
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Models/SubProtocolBuildRequest.cs b/protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Models/SubProtocolBuildRequest.cs
rename to protocols/JiShe.CollectBus.Protocol/Models/SubProtocolBuildRequest.cs
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F10_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F10_AnalysisDto.cs
new file mode 100644
index 0000000..46b7581
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F10_AnalysisDto.cs
@@ -0,0 +1,95 @@
+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.Protocol.Dto
+{
+ public class AFN10_F10_AnalysisDto
+ {
+ ///
+ /// 本次电能表/交流采样装置配置数量 n
+ ///
+ public int ConfigNum { get; set; }
+
+ ///
+ /// 电能表/交流采样装置配置信息
+ ///
+ public List AFN10F10Entitys { get; set; } = new List();
+ }
+
+
+ public class AFN10F10Entity
+ {
+ ///
+ /// 电能表/交流采样装置序号
+ ///
+ public int SerialNum { get; set; }
+
+ ///
+ /// 所属测量点号
+ ///
+ public int Point { get; set; }
+
+ ///
+ /// 通信速率
+ ///
+ public int BaudRate { get; set; }
+
+ ///
+ /// 端口号
+ ///
+ public int Port { get; set; }
+
+
+ ///
+ /// 通信协议类型
+ ///
+ public string RuleType { get; set; }
+
+ ///
+ /// 通信地址
+ ///
+ public string ComAddress { get; set; }
+
+ ///
+ /// 通信密码
+ ///
+ public string ComPwd { get; set; }
+
+
+ ///
+ /// 电能费率个数
+ ///
+ public int ElectricityRatesNum { get; set; }
+
+
+ ///
+ /// 有功电能示值整数位及小数位个数
+ ///
+ public int IntegerBitsNum { get; set; }
+
+ ///
+ /// 有功电能示值小数位个数
+ ///
+ public int DecimalPlacesNum { get; set; }
+
+ ///
+ /// 所属采集器通信地址
+ ///
+ public string CollectorAddress{ get; set; }
+
+ ///
+ /// 用户大类号
+ ///
+ public int UserCategoryNum { get; set;}
+
+ ///
+ /// 用户小类号
+ ///
+ public int UserSubclassNum { get; set; }
+ }
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F66_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F66_AnalysisDto.cs
new file mode 100644
index 0000000..c3c8306
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN10_F66_AnalysisDto.cs
@@ -0,0 +1,45 @@
+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.Protocol.Dto
+{
+ public class AFN10_F66_AnalysisDto
+ {
+ ///
+ /// 定时发送周期
+ /// 1:用 D6~D7 编码表示,取值 0~3 依次表示分、时、日、月
+ /// 2:用 D0~D5 表示,为定时上报数据的时间周期
+ ///
+ public int Cycle { get; set; }
+ ///
+ /// 定时发送周期(单位)
+ ///
+ public int Unit { get; set; }
+ ///
+ /// 发送基准时间
+ ///
+ public DateTime BaseTime { get; set; }
+
+ ///
+ /// 曲线数据提取倍率
+ ///
+ public int CurveRatio { get; set; }
+
+ ///
+ /// 任务号
+ ///
+ public int Pn { get; set; }
+
+ public List Details { get; set; } = new List();
+ }
+
+ public class SetAutoItemCodeDetails
+ {
+ public int Pn { get; set; }
+ public int Fn { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F129_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F129_AnalysisDto.cs
new file mode 100644
index 0000000..30719e9
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F129_AnalysisDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F129_AnalysisDto : AnalysisBaseDto
+ {
+ public DateTime ReadTime { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F130_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F130_AnalysisDto.cs
new file mode 100644
index 0000000..9a9259b
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F130_AnalysisDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F130_AnalysisDto : AnalysisBaseDto
+ {
+ public DateTime ReadTime { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F131_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F131_AnalysisDto.cs
new file mode 100644
index 0000000..edc5ca7
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F131_AnalysisDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F131_AnalysisDto: AnalysisBaseDto
+ {
+ public DateTime ReadTime { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F132_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F132_AnalysisDto.cs
new file mode 100644
index 0000000..1625f15
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F132_AnalysisDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F132_AnalysisDto: AnalysisBaseDto
+ {
+ public DateTime ReadTime { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F145_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F145_AnalysisDto.cs
new file mode 100644
index 0000000..96f0c37
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F145_AnalysisDto.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F145_AnalysisDto : AnalysisBaseDto
+ {
+ ///
+ /// 最大需量时标
+ ///
+ public string TimeSpan { get; set; }
+
+ public DateTime ReadingDate { get; set; }
+ }
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F149_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F149_AnalysisDto.cs
new file mode 100644
index 0000000..fb9dafe
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F149_AnalysisDto.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F149_AnalysisDto : AnalysisBaseDto
+ {
+ ///
+ /// 最大需量时标
+ ///
+ public string TimeSpan { get; set; }
+
+ public DateTime ReadingDate { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F188_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F188_AnalysisDto.cs
new file mode 100644
index 0000000..1afb8ff
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F188_AnalysisDto.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F188_AnalysisDto : AnalysisBaseDto
+ {
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F25_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F25_AnalysisDto.cs
new file mode 100644
index 0000000..ca8b8ff
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F25_AnalysisDto.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F25_AnalysisDto: AnalysisBaseDto
+ {
+ ///
+ /// 读取时间
+ ///
+ public DateTime ReadTime { get; set; }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F2_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F2_AnalysisDto.cs
new file mode 100644
index 0000000..e069382
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F2_AnalysisDto.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F2_AnalysisDto: AnalysisBaseDto
+ {
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F33_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F33_AnalysisDto.cs
new file mode 100644
index 0000000..b917969
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F33_AnalysisDto.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN12_F33_AnalysisDto
+ {
+ ///
+ /// 终端抄表时间
+ ///
+ public string ReadTime { get; set; }
+
+ ///
+ /// 费率数M(1≤M≤12)
+ ///
+ public int RatingCount { get; set; }
+ ///
+ /// 当前正向有功总电能示值
+ ///
+ public ParentNodes F_A_Kwh { get; set; }
+ ///
+ /// 当前正向无功(组合无功1)总电能示值
+ ///
+ public ParentNodes R_R_Kvarh { get; set; }
+
+ ///
+ /// 当前一象限无功总电能示值
+ ///
+ public ParentNodes Q1_R_Kvarh { get; set; }
+ ///
+ /// 当前四象限无功总电能示值
+ ///
+ public ParentNodes Q4_R_Kvarh { get; set; }
+ }
+
+ public class ParentNodes
+ {
+ ///
+ /// 总电能示值
+ ///
+ public decimal Total_Value { get; set; }
+ public List childNodes { get; set; }
+ }
+ public class ChildNodes
+ {
+ ///
+ /// 费率总电能示值
+ ///
+ public decimal Value { get; set; }
+
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F49_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F49_AnalysisDto.cs
new file mode 100644
index 0000000..ce0aeb7
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN12_F49_AnalysisDto.cs
@@ -0,0 +1,15 @@
+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.Protocol.Dto
+{
+ public class AFN12_F49_AnalysisDto: AnalysisBaseDto
+ {
+ }
+
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN9_F1_AnalysisDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN9_F1_AnalysisDto.cs
new file mode 100644
index 0000000..7b7bc3a
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AFN9_F1_AnalysisDto.cs
@@ -0,0 +1,38 @@
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AFN9_F1_AnalysisDto
+ {
+ public int FocusID { get; set; }
+ public string? AreaCode { get; set; }
+ public string? Address { get; set; }
+
+ ///
+ /// 厂商代号
+ ///
+ public string? MakerNo { get; set; }
+ ///
+ /// 设备编号
+ ///
+ public string? DeviceNo { get; set; }
+ ///
+ /// 终端软件版本号
+ ///
+ public string? SoftwareVersion { get; set; }
+ ///
+ /// 终端软件发布日期:日月年
+ ///
+ public string? SoftwareReleaseDate { get; set; }
+
+ ///
+ /// 硬件软件版本号
+ ///
+ public string? HardwareVersion { get; set; }
+ ///
+ /// 硬件软件发布日期:日月年
+ ///
+ public string? HardwareReleaseDate { get; set; }
+
+ public string? AddDate { get; set; }
+ }
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AnalysisBaseDto.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AnalysisBaseDto.cs
new file mode 100644
index 0000000..49f9054
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/AnalysisBaseDto.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Protocol.Dto
+{
+ public class AnalysisBaseDto
+ {
+
+ ///
+ /// 是否有效数据
+ ///
+ public bool ValidData { get; set; } = true;
+
+ ///
+ /// 数据类型
+ ///
+ public string DataType { get; set; }
+
+ ///
+ /// 错误码信息
+ ///
+ public string ErrorCodeMsg { get; set; }
+
+ ///
+ /// 字段名
+ ///
+ public string FiledName { get; set; }
+
+ ///
+ /// 字段描述
+ ///
+ public string FiledDesc { get; set; }
+ }
+
+ public class AnalysisBaseDto : AnalysisBaseDto
+ {
+ ///
+ /// 抄读值
+ ///
+ public T? DataValue { get; set; }
+ }
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/UnitDataAnalysis.cs b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/UnitDataAnalysis.cs
new file mode 100644
index 0000000..3a03923
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/Protocol/Dto/UnitDataAnalysis.cs
@@ -0,0 +1,36 @@
+namespace JiShe.CollectBus.Protocol.Dto
+{
+ public class UnitDataAnalysis
+ {
+ ///
+ /// 集中器地址
+ ///
+ public string? Code { get; set; }
+
+ ///
+ /// AFN功能码
+ ///
+ public int AFN { get; set; }
+
+ ///
+ /// 信息点
+ ///
+ public int Pn { get; set; }
+
+ ///
+ /// 信息类
+ ///
+ public int Fn { get; set; }
+
+
+ }
+
+ public class UnitDataAnalysis: UnitDataAnalysis
+ {
+ ///
+ /// 数据
+ ///
+ public T? Data { get; set; }
+ }
+
+}
diff --git a/protocols/JiShe.CollectBus.Protocol/QGDW3761Config.cs b/protocols/JiShe.CollectBus.Protocol/QGDW3761Config.cs
new file mode 100644
index 0000000..88f6bcb
--- /dev/null
+++ b/protocols/JiShe.CollectBus.Protocol/QGDW3761Config.cs
@@ -0,0 +1,70 @@
+using JiShe.CollectBus.Protocol.Contracts.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using JiShe.CollectBus.Common.Extensions;
+
+namespace JiShe.CollectBus.Protocol.Contracts
+{
+ public class QGDW3761Config
+ {
+ private static List _commandList = null;
+ public static List CommandList
+ {
+ get
+ {
+ if (_commandList == null)
+ {
+ var filePath = AppDomain.CurrentDomain.BaseDirectory + "cmd3761Matching.txt";
+
+ try
+ {
+ var fileStr = "";
+ if (File.Exists(filePath))
+ fileStr = File.ReadAllText(filePath, Encoding.UTF8);
+
+ if (!string.IsNullOrWhiteSpace(fileStr))
+ {
+ _commandList = fileStr.FromJson>();
+ }
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ return _commandList;
+ }
+ }
+
+ private static List _commandTdcList = null;
+ public static List CommandTdcList
+ {
+ get
+ {
+ if (_commandTdcList == null)
+ {
+ var filePath = AppDomain.CurrentDomain.BaseDirectory + "cmd3761TdcMatching.txt";
+
+ try
+ {
+ var fileStr = "";
+ if (File.Exists(filePath))
+ fileStr = File.ReadAllText(filePath, Encoding.UTF8);
+
+ if (!string.IsNullOrWhiteSpace(fileStr))
+ {
+ _commandTdcList = fileStr.FromJson>();
+ }
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ return _commandTdcList;
+ }
+ }
+ }
+}
diff --git a/protocols/JiShe.CollectBus.Protocol.Contracts/Services/ProtocolService.cs b/protocols/JiShe.CollectBus.Protocol/Services/ProtocolService.cs
similarity index 100%
rename from protocols/JiShe.CollectBus.Protocol.Contracts/Services/ProtocolService.cs
rename to protocols/JiShe.CollectBus.Protocol/Services/ProtocolService.cs
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/JiShe.CollectBus.Application.csproj b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
index b97fd0f..6f71f34 100644
--- a/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
+++ b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
@@ -22,7 +22,6 @@
-
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index 750b938..7173813 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -138,6 +138,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))
{
@@ -198,11 +219,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 电表采集处理
@@ -695,6 +717,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 = T645PacketItemCodeConst.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
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs
index fbe667a..d451b2a 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/EnergySystemScheduledMeterReadingService.cs
@@ -311,7 +311,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
}
//任务记录入库
- _ = _dbProvider.BatchInsertAsync(metadata, taskList);
+ await _dbProvider.BatchInsertAsync(metadata, taskList);
//任务信息推送Kafka
_ = DeviceGroupBalanceControl.ProcessWithThrottleAsync(
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/T645PacketItemCodeConst.cs b/shared/JiShe.CollectBus.Common/Consts/T645PacketItemCodeConst.cs
index 449ef9a..3b94e07 100644
--- a/shared/JiShe.CollectBus.Common/Consts/T645PacketItemCodeConst.cs
+++ b/shared/JiShe.CollectBus.Common/Consts/T645PacketItemCodeConst.cs
@@ -11,6 +11,7 @@ namespace JiShe.CollectBus.Common.Consts
///
public class T645PacketItemCodeConst
{
+ #region 下行报文编码
#region 跳合闸、报警、保电
///
/// 跳闸
@@ -55,5 +56,6 @@ namespace JiShe.CollectBus.Common.Consts
///
public const string C08 = "08";
#endregion
+ #endregion
}
}