协议池的应用处理01
This commit is contained in:
parent
57021e2b9c
commit
dec99af6dd
@ -1,7 +1,11 @@
|
||||
using JiShe.CollectBus.Common.Extensions;
|
||||
using JiShe.CollectBus.Common.BuildSendDatas;
|
||||
using JiShe.CollectBus.Common.Enums;
|
||||
using JiShe.CollectBus.Common.Extensions;
|
||||
using JiShe.CollectBus.Common.Models;
|
||||
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;
|
||||
@ -9,7 +13,7 @@ using Volo.Abp.Domain.Repositories;
|
||||
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
{
|
||||
public abstract class ProtocolPlugin:IProtocolPlugin
|
||||
public abstract class ProtocolPlugin : IProtocolPlugin
|
||||
{
|
||||
//头部字节长度
|
||||
public const int hearderLen = 6;
|
||||
@ -20,9 +24,10 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRepository<ProtocolInfo, Guid> _protocolInfoRepository;
|
||||
|
||||
public ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_logger = logger;
|
||||
_protocolInfoRepository = serviceProvider.GetRequiredService<IRepository<ProtocolInfo, Guid>>();
|
||||
}
|
||||
|
||||
@ -43,7 +48,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
//await _protocolInfoCache.Get()
|
||||
}
|
||||
|
||||
public abstract Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? receivedAction = null) where T :class;
|
||||
public abstract Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? receivedAction = null) where T : class;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -78,7 +83,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
DA = Analysis_DA(hexStringList),
|
||||
DT = Analysis_DT(hexStringList)
|
||||
};
|
||||
return tB3761;
|
||||
return tB3761;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -302,7 +307,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
return null;
|
||||
var da1 = baseHexMessage.HexMessageList[0];
|
||||
var da2 = baseHexMessage.HexMessageList[1];
|
||||
DA da = new DA()
|
||||
DA da = new DA()
|
||||
{
|
||||
BaseHexMessage = baseHexMessage,
|
||||
Pn = CalculatePn(da1, da2)
|
||||
@ -369,13 +374,18 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
||||
/// <returns></returns>
|
||||
public int CalculateFn(string dt1, string dt2) => dt2.HexToDec() * 8 + (8 - dt1.HexTo4BinZero().IndexOf("1"));
|
||||
|
||||
#region 下行命令构建
|
||||
|
||||
/// <summary>
|
||||
/// 组装透明转发报文
|
||||
/// 组装报文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="entity">设备数据实体</param>
|
||||
/// <param name="afnFnCode">映射读取执行方法的Code,例如10_1,表示 10H_F1_00000,10H_F1_00001,统一英文下划线分隔</param>
|
||||
/// <returns></returns>
|
||||
public abstract Task<List<string>> GenerateAFN10HContent<T>(T entity) where T : class;
|
||||
public abstract Task<BuildResponse> BuildAsync(BuildRequest request);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ using JiShe.CollectBus.Common.Models;
|
||||
using JiShe.CollectBus.IotSystems.MessageReceiveds;
|
||||
using JiShe.CollectBus.IotSystems.Protocols;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Models;
|
||||
using JiShe.CollectBus.Protocol.Contracts.SendData;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.Interfaces
|
||||
@ -19,10 +20,12 @@ namespace JiShe.CollectBus.Protocol.Contracts.Interfaces
|
||||
TB3761? Analysis3761(string messageReceived);
|
||||
|
||||
/// <summary>
|
||||
/// 组装透明转发报文
|
||||
/// 组装报文
|
||||
/// </summary>
|
||||
/// <typeparam name="T">是否需要转发的扩展协议入参对象</typeparam>
|
||||
/// <param name="afnFnCode">映射读取执行方法的Code,例如10_1,表示10H_F1</param>
|
||||
/// <returns></returns>
|
||||
Task<List<string>> GenerateAFN10HContent<T>(T entity) where T : class;
|
||||
Task<BuildResponse> BuildAsync(BuildRequest request);
|
||||
|
||||
//Task LoginAsync(MessageReceivedLogin messageReceived);
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文构建参数
|
||||
/// </summary>
|
||||
public class BuildRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 集中器地址
|
||||
/// </summary>
|
||||
public required string FocusAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 抄读计量点,也就是终端电表对应端口
|
||||
/// </summary>
|
||||
public int Pn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 3761协议构建组合功能码
|
||||
/// </summary>
|
||||
public required string ItemCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 集中器转发协议构建组合功能码
|
||||
/// </summary>
|
||||
public string SubItemCode { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文构建返回结果
|
||||
/// </summary>
|
||||
public class BuildResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 帧功能域AFN
|
||||
/// </summary>
|
||||
public int AFn { get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// 帧功能域FN
|
||||
/// </summary>
|
||||
public int Fn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帧序列域SEQ
|
||||
/// </summary>
|
||||
public int Seq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址域A3的主站地址MSA
|
||||
/// </summary>
|
||||
public int MSA { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文体
|
||||
/// </summary>
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,51 +1,42 @@
|
||||
using JiShe.CollectBus.Common.Enums;
|
||||
using JiShe.CollectBus.Common.BuildSendDatas;
|
||||
using JiShe.CollectBus.Common.Enums;
|
||||
using JiShe.CollectBus.Common.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建下发报文,只适用与定时抄读
|
||||
/// 构建3761下发报文
|
||||
/// </summary>
|
||||
public static class TelemetryPacketBuilder
|
||||
public static class Telemetry3761PacketBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建报文的委托
|
||||
/// </summary>
|
||||
/// <param name="request.FocusAddress"></param>
|
||||
/// <param name="request.Fn"></param>
|
||||
/// <param name="request.Pn"></param>
|
||||
public delegate TelemetryPacketResponse AFNDelegate(TelemetryPacketRequest request);
|
||||
/// </summary>
|
||||
public delegate Telemetry3761PacketResponse T3761Delegate(Telemetry3761PacketRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 编码与方法的映射表
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string, AFNDelegate> AFNHandlersDictionary = new();
|
||||
public static readonly Dictionary<string, T3761Delegate> T3761AFNHandlers = new();
|
||||
|
||||
static TelemetryPacketBuilder()
|
||||
static Telemetry3761PacketBuilder()
|
||||
{
|
||||
// 初始化时自动注册所有符合命名规则的方法
|
||||
var methods = typeof(TelemetryPacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public);
|
||||
var methods = typeof(Telemetry3761PacketBuilder).GetMethods(BindingFlags.Static | BindingFlags.Public);
|
||||
foreach (var method in methods)
|
||||
{
|
||||
if (method.Name.StartsWith("AFN") && method.Name.EndsWith("_Fn_Send"))
|
||||
{
|
||||
string code = method.Name;
|
||||
var delegateInstance = (AFNDelegate)Delegate.CreateDelegate(typeof(AFNDelegate), method);
|
||||
AFNHandlersDictionary[code] = delegateInstance;
|
||||
var delegateInstance = (T3761Delegate)Delegate.CreateDelegate(typeof(T3761Delegate), method);
|
||||
T3761AFNHandlers[code] = delegateInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region AFN_00H 确认∕否认
|
||||
public static TelemetryPacketResponse AFN00_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN00_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -64,13 +55,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region AFN_01H 复位命令
|
||||
public static TelemetryPacketResponse AFN01_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN01_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -89,13 +80,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region AFN_02H 链路接口检测
|
||||
public static TelemetryPacketResponse AFN02_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN02_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -114,12 +105,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AFN_04H 设置参数
|
||||
public static TelemetryPacketResponse AFN04_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN04_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -138,13 +129,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AFN_05H 控制命令
|
||||
public static TelemetryPacketResponse AFN05_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN05_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -163,12 +154,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AFN_09H 请求终端配置及信息
|
||||
public static TelemetryPacketResponse AFN09_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN09_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -187,13 +178,13 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AFN_0AH 查询参数
|
||||
public static TelemetryPacketResponse AFN0A_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN0A_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -212,12 +203,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AFN_0CH 请求一类数据
|
||||
public static TelemetryPacketResponse AFN0C_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN0C_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -236,12 +227,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AFN_0DH 请求二类数据
|
||||
public static TelemetryPacketResponse AFN0D_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN0D_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -260,12 +251,12 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AFN10H 数据转发
|
||||
public static TelemetryPacketResponse AFN10_Fn_Send(TelemetryPacketRequest request)
|
||||
public static Telemetry3761PacketResponse AFN10_Fn_Send(Telemetry3761PacketRequest request)
|
||||
{
|
||||
var reqParameter = new ReqParameter2()
|
||||
{
|
||||
@ -284,7 +275,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
Fn = request.Fn
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParameter, request.DataUnit);
|
||||
return new TelemetryPacketResponse() { Seq = reqParameter.Seq, Data = bytes, MSA = reqParameter.MSA, };
|
||||
return new Telemetry3761PacketResponse() { Seq = reqParameter.Seq.PRSEQ, Data = bytes, MSA = reqParameter.MSA, };
|
||||
}
|
||||
|
||||
#region SpecialAmmeter 特殊电表转发
|
||||
@ -1,20 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文构建参数
|
||||
/// 构建3761报文参数
|
||||
/// </summary>
|
||||
public class TelemetryPacketRequest
|
||||
public class Telemetry3761PacketRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 集中器地址
|
||||
/// </summary>
|
||||
public string FocusAddress { get; set; }
|
||||
public required string FocusAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 抄读功能码
|
||||
@ -24,7 +18,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
/// <summary>
|
||||
/// 抄读计量点,也就是终端电表对应端口
|
||||
/// </summary>
|
||||
public int Pn { get; set; }
|
||||
public int Pn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 透明转发单元
|
||||
@ -0,0 +1,23 @@
|
||||
namespace JiShe.CollectBus.Protocol.Contracts.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回3761报文结果
|
||||
/// </summary>
|
||||
public class Telemetry3761PacketResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 帧序列域SEQ
|
||||
/// </summary>
|
||||
public int Seq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址域A3的主站地址MSA
|
||||
/// </summary>
|
||||
public int MSA { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文体
|
||||
/// </summary>
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ using JiShe.CollectBus.Common.Models;
|
||||
using JiShe.CollectBus.IotSystems.MessageReceiveds;
|
||||
using JiShe.CollectBus.IotSystems.Protocols;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Abstracts;
|
||||
using JiShe.CollectBus.Protocol.Contracts.SendData;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
@ -26,5 +27,10 @@ namespace JiShe.CollectBus.Protocol.Test
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<BuildResponse> BuildAsync(BuildRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建645-2007下发报文
|
||||
/// </summary>
|
||||
public static class Telemetry645PacketBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建报文的委托
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public delegate Telemetry645PacketResponse T645Delegate(Telemetry645PacketRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 编码与方法的映射表
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string, T645Delegate> T645ControlHandlers = new();
|
||||
|
||||
static Telemetry645PacketBuilder()
|
||||
{
|
||||
// 初始化时自动注册所有符合命名规则的方法
|
||||
var methods = typeof(Telemetry645PacketBuilder).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);
|
||||
T645ControlHandlers[code] = delegateInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region 1CH 跳合闸、报警、保电
|
||||
|
||||
/// <summary>
|
||||
/// 1CH 跳合闸
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public static Telemetry645PacketResponse C1C_01_Send(Telemetry645PacketRequest 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 Telemetry645PacketResponse() { Data = dataList };
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 1CH 保电
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public static Telemetry645PacketResponse C1C_02_Send(Telemetry645PacketRequest 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 Telemetry645PacketResponse() { Data = dataList };
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
namespace JiShe.CollectBus.Protocol.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建645报文参数
|
||||
/// </summary>
|
||||
public class Telemetry645PacketRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 表地址
|
||||
/// </summary>
|
||||
public required string MeterAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public required string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作码
|
||||
/// </summary>
|
||||
public required string ItemCode { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
namespace JiShe.CollectBus.Protocol.SendData
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回645报文结果
|
||||
/// </summary>
|
||||
public class Telemetry645PacketResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文体
|
||||
/// </summary>
|
||||
public List<string> Data { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using DeviceDetectorNET.Parser.Device;
|
||||
using Azure.Core;
|
||||
using DeviceDetectorNET.Parser.Device;
|
||||
using JiShe.CollectBus.Common.BuildSendDatas;
|
||||
using JiShe.CollectBus.Common.Consts;
|
||||
using JiShe.CollectBus.Common.Enums;
|
||||
@ -13,6 +14,9 @@ using JiShe.CollectBus.Kafka.Producer;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Abstracts;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Interfaces;
|
||||
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 Newtonsoft.Json.Linq;
|
||||
@ -29,17 +33,23 @@ namespace JiShe.CollectBus.Protocol
|
||||
|
||||
private readonly IRepository<Device, Guid> _deviceRepository;
|
||||
private readonly ITcpService _tcpService;
|
||||
|
||||
public readonly Dictionary<string, Telemetry3761PacketBuilder.T3761Delegate> T3761AFNHandlers;
|
||||
public readonly Dictionary<string, Telemetry645PacketBuilder.T645Delegate> T645ControlHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StandardProtocolPlugin"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">The service provider.</param>
|
||||
public StandardProtocolPlugin(IServiceProvider serviceProvider,ILogger<StandardProtocolPlugin> logger, ITcpService tcpService) : base(serviceProvider, logger)
|
||||
public StandardProtocolPlugin(IServiceProvider serviceProvider, ILogger<StandardProtocolPlugin> logger, ITcpService tcpService) : base(serviceProvider, logger)
|
||||
{
|
||||
_logger = logger;
|
||||
//_logger = serviceProvider.GetRequiredService<ILogger<StandardProtocolPlugin>>();
|
||||
_producerService = serviceProvider.GetRequiredService<IProducerService>();
|
||||
_deviceRepository = serviceProvider.GetRequiredService<IRepository<Device, Guid>>();
|
||||
_tcpService = tcpService;
|
||||
T3761AFNHandlers = Telemetry3761PacketBuilder.T3761AFNHandlers;
|
||||
T645ControlHandlers = Telemetry645PacketBuilder.T645ControlHandlers;
|
||||
}
|
||||
|
||||
public sealed override ProtocolInfo Info => new(nameof(StandardProtocolPlugin), "376.1", "TCP", "376.1协议", "DTS1980");
|
||||
@ -72,7 +82,7 @@ namespace JiShe.CollectBus.Protocol
|
||||
await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -88,7 +98,7 @@ namespace JiShe.CollectBus.Protocol
|
||||
/// <param name="msa"></param>
|
||||
/// <param name="pseq"></param>
|
||||
/// <returns></returns>
|
||||
public async Task LoginAsync(ITcpSessionClient client,string messageReceived, string code, int? msa, int? pseq)
|
||||
public async Task LoginAsync(ITcpSessionClient client, string messageReceived, string code, int? msa, int? pseq)
|
||||
{
|
||||
string oldClientId = $"{client.Id}";
|
||||
await client.ResetIdAsync(code);
|
||||
@ -135,7 +145,7 @@ namespace JiShe.CollectBus.Protocol
|
||||
AFN = AFN.确认或否认,
|
||||
FunCode = (int)CFromStationFunCode.链路数据,
|
||||
PRM = PRM.从动站报文,
|
||||
A =code,
|
||||
A = code,
|
||||
Seq = new Seq()
|
||||
{
|
||||
TpV = TpV.附加信息域中无时间标签,
|
||||
@ -148,11 +158,12 @@ namespace JiShe.CollectBus.Protocol
|
||||
Fn = 1
|
||||
};
|
||||
var bytes = Build3761SendData.BuildSendCommandBytes(reqParam);
|
||||
var issuedEventMessage = new IssuedEventMessage
|
||||
{
|
||||
ClientId = messageReceivedLoginEvent.ClientId,
|
||||
DeviceNo = messageReceivedLoginEvent.DeviceNo,
|
||||
Message = bytes, Type = IssuedEventType.Login,
|
||||
var issuedEventMessage = new IssuedEventMessage
|
||||
{
|
||||
ClientId = messageReceivedLoginEvent.ClientId,
|
||||
DeviceNo = messageReceivedLoginEvent.DeviceNo,
|
||||
Message = bytes,
|
||||
Type = IssuedEventType.Login,
|
||||
MessageId = messageReceivedLoginEvent.MessageId
|
||||
};
|
||||
//await _producerBus.PublishAsync(ProtocolConst.SubscriberLoginIssuedEventName, new IssuedEventMessage { ClientId = messageReceived.ClientId, DeviceNo = messageReceived.DeviceNo, Message = bytes, Type = IssuedEventType.Login, MessageId = messageReceived.MessageId });
|
||||
@ -174,7 +185,7 @@ namespace JiShe.CollectBus.Protocol
|
||||
/// <param name="msa"></param>
|
||||
/// <param name="pseq"></param>
|
||||
/// <returns></returns>
|
||||
public async Task HeartbeatAsync(ITcpSessionClient client,string messageReceived, string code, int? msa, int? pseq)
|
||||
public async Task HeartbeatAsync(ITcpSessionClient client, string messageReceived, string code, int? msa, int? pseq)
|
||||
{
|
||||
|
||||
string clientId = code;
|
||||
@ -240,7 +251,7 @@ namespace JiShe.CollectBus.Protocol
|
||||
};
|
||||
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 });
|
||||
|
||||
|
||||
IssuedEventMessage issuedEventMessage = new IssuedEventMessage
|
||||
{
|
||||
ClientId = messageReceivedHeartbeatEvent.ClientId,
|
||||
@ -263,14 +274,67 @@ namespace JiShe.CollectBus.Protocol
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 组装透明转发报文
|
||||
/// 组装报文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="entity">设备数据实体</param>
|
||||
/// <param name="afnFnCode">映射读取执行方法的Code,例如10_1,表示 10H_F1_00000,10H_F1_00001,统一英文下划线分隔</param>
|
||||
/// <returns></returns>
|
||||
public override async Task<List<string>> GenerateAFN10HContent<T>(T entity) where T : class
|
||||
public override async Task<BuildResponse> BuildAsync(BuildRequest request)
|
||||
{
|
||||
return await Task.FromResult(new List<string>());
|
||||
var itemCodeArr = request.ItemCode.Split('_');
|
||||
var aFNStr = itemCodeArr[0];
|
||||
var aFN = (AFN)aFNStr.HexToDec();
|
||||
var fn = int.Parse(itemCodeArr[1]);
|
||||
Telemetry3761PacketResponse builderResponse = null;
|
||||
|
||||
List<string> dataUnit = new List<string>();
|
||||
//10H_F1_1CH
|
||||
if (aFNStr == "10" && string.IsNullOrWhiteSpace(request.SubItemCode) == false)
|
||||
{
|
||||
|
||||
var subItem = $"C{request.SubItemCode}_Send";
|
||||
Telemetry645PacketResponse t645PacketResponse = null;
|
||||
|
||||
if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(subItem
|
||||
, out var cchandler))
|
||||
{
|
||||
t645PacketResponse = cchandler(new Telemetry645PacketRequest()
|
||||
{
|
||||
MeterAddress = "",
|
||||
Password = "",
|
||||
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 BuildResponse();
|
||||
}
|
||||
|
||||
var result = builderResponse.Adapt<BuildResponse>();
|
||||
result.IsSuccess = true;
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ using JiShe.CollectBus.Common.Extensions;
|
||||
using JiShe.CollectBus.Common.Helpers;
|
||||
using JiShe.CollectBus.Enums;
|
||||
using JiShe.CollectBus.Interceptors;
|
||||
using JiShe.CollectBus.IotSystems.Ammeters;
|
||||
using JiShe.CollectBus.IotSystems.Devices;
|
||||
using JiShe.CollectBus.IotSystems.MessageReceiveds;
|
||||
using JiShe.CollectBus.Kafka.Producer;
|
||||
|
||||
@ -11,6 +11,7 @@ using JiShe.CollectBus.IoTDB.Interface;
|
||||
using JiShe.CollectBus.IoTDB.Model;
|
||||
using JiShe.CollectBus.IoTDB.Options;
|
||||
using JiShe.CollectBus.IoTDB.Provider;
|
||||
using JiShe.CollectBus.IotSystems.Ammeters;
|
||||
using JiShe.CollectBus.IotSystems.PrepayModel;
|
||||
using JiShe.CollectBus.Kafka.Attributes;
|
||||
using JiShe.CollectBus.Kafka.Internal;
|
||||
|
||||
@ -7,6 +7,7 @@ using JiShe.CollectBus.Common.Enums;
|
||||
using JiShe.CollectBus.Common.Extensions;
|
||||
using JiShe.CollectBus.Common.Helpers;
|
||||
using JiShe.CollectBus.Common.Models;
|
||||
using JiShe.CollectBus.EnergySystems.Entities;
|
||||
using JiShe.CollectBus.GatherItem;
|
||||
using JiShe.CollectBus.IoTDB.Context;
|
||||
using JiShe.CollectBus.IoTDB.Interface;
|
||||
@ -19,6 +20,7 @@ using JiShe.CollectBus.IotSystems.Watermeter;
|
||||
using JiShe.CollectBus.Kafka.Internal;
|
||||
using JiShe.CollectBus.Kafka.Producer;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Interfaces;
|
||||
using JiShe.CollectBus.Protocol.Contracts.SendData;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -27,6 +29,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.CompilerServices.RuntimeHelpers;
|
||||
|
||||
namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
{
|
||||
@ -41,8 +44,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
private readonly IRedisDataCacheService _redisDataCacheService;
|
||||
private readonly KafkaOptionConfig _kafkaOptions;
|
||||
private readonly IoTDBRuntimeContext _runtimeContext;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
private readonly IProtocolService _protocolService;
|
||||
|
||||
int pageSize = 3000;
|
||||
|
||||
public BasicScheduledMeterReadingService(
|
||||
@ -51,7 +54,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
IRedisDataCacheService redisDataCacheService,
|
||||
IIoTDbProvider dbProvider,
|
||||
IoTDBRuntimeContext runtimeContext,
|
||||
IServiceProvider serviceProvider,
|
||||
IProtocolService protocolService,
|
||||
IOptions<KafkaOptionConfig> kafkaOptions)
|
||||
{
|
||||
_logger = logger;
|
||||
@ -60,7 +63,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
_producerService = producerService;
|
||||
_redisDataCacheService = redisDataCacheService;
|
||||
_kafkaOptions = kafkaOptions.Value;
|
||||
_serviceProvider = serviceProvider;
|
||||
_protocolService = protocolService;
|
||||
|
||||
_runtimeContext.UseTableSessionPool = true;
|
||||
}
|
||||
@ -145,15 +148,15 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
timeDensity: timeDensity,
|
||||
nextTaskTime: currentTaskTime,
|
||||
meterType: MeterTypeEnum.Ammeter,
|
||||
taskCreateAction: (timeDensity, data, groupIndex, timestamps) =>
|
||||
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||
{
|
||||
var tempTask = AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
||||
var tempTask = await AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
||||
if (tempTask == null || tempTask.Count <= 0)
|
||||
{
|
||||
_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||
return;
|
||||
}
|
||||
_dbProvider.BatchInsertAsync(metadata, tempTask);
|
||||
_ = _dbProvider.BatchInsertAsync(metadata, tempTask);
|
||||
});
|
||||
}
|
||||
else if (meteryType == MeterTypeEnum.WaterMeter.ToString())
|
||||
@ -163,16 +166,16 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
timeDensity: timeDensity,
|
||||
nextTaskTime: currentTaskTime,
|
||||
meterType: MeterTypeEnum.WaterMeter,
|
||||
taskCreateAction: (timeDensity, data, groupIndex, timestamps) =>
|
||||
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||
{
|
||||
var tempTask = WatermeterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
||||
var tempTask = await WatermeterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
||||
|
||||
if (tempTask == null || tempTask.Count <= 0)
|
||||
{
|
||||
_logger.LogWarning($"水表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||
return;
|
||||
}
|
||||
_dbProvider.BatchInsertAsync(metadata, tempTask);
|
||||
_ = _dbProvider.BatchInsertAsync(metadata, tempTask);
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -500,11 +503,20 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
/// <param name="groupIndex">集中器所在分组</param>
|
||||
/// <param name="timestamps">采集频率对应的时间戳</param>
|
||||
/// <returns></returns>
|
||||
private List<MeterReadingTelemetryPacketInfo> AmmerterCreatePublishTaskAction(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps)
|
||||
private async Task<List<MeterReadingTelemetryPacketInfo>> AmmerterCreatePublishTaskAction(int timeDensity, AmmeterInfo ammeterInfo, int groupIndex, DateTime timestamps)
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
|
||||
var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary;
|
||||
//根据电表型号获取协议插件
|
||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
||||
if (protocolPlugin == null)
|
||||
{
|
||||
//_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
||||
//return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//todo 检查需要待补抄的电表的时间点信息,保存到需要待补抄的缓存中。如果此线程异常,该如何补偿?
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ammeterInfo.ItemCodes))
|
||||
@ -601,43 +613,18 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
continue;
|
||||
}
|
||||
|
||||
var itemCodeArr = tempItem.Split('_');
|
||||
var aFNStr = itemCodeArr[0];
|
||||
var aFN = (AFN)aFNStr.HexToDec();
|
||||
var fn = int.Parse(itemCodeArr[1]);
|
||||
TelemetryPacketResponse builderResponse = null;
|
||||
if (ammeterInfo.AutomaticReport.Equals(1) && aFN == AFN.请求实时数据)
|
||||
{
|
||||
//实时数据
|
||||
builderResponse = TelemetryPacketBuilder.AFN0C_Fn_Send(new TelemetryPacketRequest()
|
||||
{
|
||||
FocusAddress = ammeterInfo.FocusAddress,
|
||||
Fn = fn,
|
||||
Pn = ammeterInfo.MeteringCode
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
string methonCode = $"AFN{aFNStr}_Fn_Send";
|
||||
//特殊表暂不处理
|
||||
if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode
|
||||
, out var handler))
|
||||
{
|
||||
builderResponse = handler(new TelemetryPacketRequest()
|
||||
{
|
||||
FocusAddress = ammeterInfo.FocusAddress,
|
||||
Fn = fn,
|
||||
Pn = ammeterInfo.MeteringCode
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning($"{nameof(AmmerterCreatePublishTaskAction)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}无效编码。");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//TODO:特殊表
|
||||
//var itemCodeArr = tempItem.Split('_');
|
||||
//var aFNStr = itemCodeArr[0];
|
||||
//var aFN = (AFN)aFNStr.HexToDec();
|
||||
//var fn = int.Parse(itemCodeArr[1]);
|
||||
|
||||
//TODO:特殊表
|
||||
BuildResponse builderResponse = await protocolPlugin.BuildAsync(new BuildRequest()
|
||||
{
|
||||
FocusAddress = ammeterInfo.FocusAddress,
|
||||
Pn = ammeterInfo.MeteringCode,
|
||||
ItemCode = tempItem,
|
||||
});
|
||||
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
||||
{
|
||||
//_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。");
|
||||
@ -645,7 +632,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
}
|
||||
|
||||
|
||||
string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, ammeterInfo.MeteringCode, builderResponse.MSA, builderResponse.Seq.PRSEQ);
|
||||
string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, ammeterInfo.MeteringCode, builderResponse.MSA, builderResponse.Seq);
|
||||
var meterReadingRecords = new MeterReadingTelemetryPacketInfo()
|
||||
{
|
||||
SystemName = SystemType,
|
||||
@ -657,9 +644,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
PendingCopyReadTime = timestamps,
|
||||
CreationTime = currentTime,
|
||||
MeterAddress = ammeterInfo.AmmerterAddress,
|
||||
AFN = (int)aFN,
|
||||
Fn = fn,
|
||||
Seq = builderResponse.Seq.PRSEQ,
|
||||
AFN = builderResponse.AFn,
|
||||
Fn = builderResponse.Fn,
|
||||
Seq = builderResponse.Seq,
|
||||
MSA = builderResponse.MSA,
|
||||
ItemCode = tempItem,
|
||||
TaskMark = taskMark,
|
||||
@ -851,10 +838,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
/// <param name="groupIndex">集中器所在分组</param>
|
||||
/// <param name="timestamps">时间格式的任务批次名称</param>
|
||||
/// <returns></returns>
|
||||
private List<MeterReadingTelemetryPacketInfo> WatermeterCreatePublishTaskAction(int timeDensity
|
||||
private async Task<List<MeterReadingTelemetryPacketInfo>> WatermeterCreatePublishTaskAction(int timeDensity
|
||||
, WatermeterInfo watermeter, int groupIndex, DateTime timestamps)
|
||||
{
|
||||
var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary;
|
||||
var currentTime = DateTime.Now;
|
||||
|
||||
string typeName;
|
||||
@ -912,10 +898,12 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
tempCodes = new List<string>() { "10_1" };
|
||||
}
|
||||
|
||||
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
|
||||
//根据电表型号获取协议插件
|
||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(watermeter.Code);
|
||||
if (protocolPlugin == null)
|
||||
{
|
||||
_logger.LogError("协议不存在!");
|
||||
//_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
||||
//return;
|
||||
}
|
||||
|
||||
foreach (var tempItem in tempCodes)
|
||||
@ -931,28 +919,40 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
continue;
|
||||
}
|
||||
|
||||
var itemCodeArr = tempItem.Split('_');
|
||||
var aFNStr = itemCodeArr[0];
|
||||
var aFN = (AFN)aFNStr.HexToDec();
|
||||
var fn = int.Parse(itemCodeArr[1]);
|
||||
TelemetryPacketResponse builderResponse = null;
|
||||
//var itemCodeArr = tempItem.Split('_');
|
||||
//var aFNStr = itemCodeArr[0];
|
||||
//var aFN = (AFN)aFNStr.HexToDec();
|
||||
//var fn = int.Parse(itemCodeArr[1]);
|
||||
//TelemetryPacketResponse builderResponse = null;
|
||||
|
||||
string methonCode = $"AFN{aFNStr}_Fn_Send";
|
||||
//特殊表暂不处理
|
||||
if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode
|
||||
, out var handler))
|
||||
//string methonCode = $"AFN{aFNStr}_Fn_Send";
|
||||
////特殊表暂不处理
|
||||
//if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode
|
||||
// , out var handler))
|
||||
//{
|
||||
// builderResponse = handler(new TelemetryPacketRequest()
|
||||
// {
|
||||
// FocusAddress = watermeter.FocusAddress,
|
||||
// Fn = fn,
|
||||
// Pn = watermeter.MeteringCode,
|
||||
// DataUnit = Build188SendData.Build188WaterMeterReadingSendDataUnit(watermeter.Address),
|
||||
// });
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// _logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name}采集项{tempItem}无效编码。");
|
||||
// continue;
|
||||
//}
|
||||
|
||||
BuildResponse builderResponse = await protocolPlugin.BuildAsync(new BuildRequest()
|
||||
{
|
||||
builderResponse = handler(new TelemetryPacketRequest()
|
||||
{
|
||||
FocusAddress = watermeter.FocusAddress,
|
||||
Fn = fn,
|
||||
Pn = watermeter.MeteringCode,
|
||||
DataUnit = Build188SendData.Build188WaterMeterReadingSendDataUnit(watermeter.Address),
|
||||
});
|
||||
}
|
||||
else
|
||||
FocusAddress = watermeter.FocusAddress,
|
||||
Pn = watermeter.MeteringCode,
|
||||
ItemCode = tempItem,
|
||||
});
|
||||
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
||||
{
|
||||
_logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name}采集项{tempItem}无效编码。");
|
||||
//_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -963,7 +963,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
}
|
||||
|
||||
|
||||
string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, watermeter.MeteringCode, builderResponse.MSA, builderResponse.Seq.PRSEQ);
|
||||
string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, watermeter.MeteringCode, builderResponse.MSA, builderResponse.Seq);
|
||||
var meterReadingRecords = new MeterReadingTelemetryPacketInfo()
|
||||
{
|
||||
SystemName = SystemType,
|
||||
@ -975,9 +975,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
PendingCopyReadTime = timestamps,
|
||||
CreationTime = currentTime,
|
||||
MeterAddress = watermeter.MeterAddress,
|
||||
AFN = (int)aFN,
|
||||
Fn = fn,
|
||||
Seq = builderResponse.Seq.PRSEQ,
|
||||
AFN = builderResponse.AFn,
|
||||
Fn = builderResponse.Fn,
|
||||
Seq = builderResponse.Seq,
|
||||
MSA = builderResponse.MSA,
|
||||
ItemCode = tempItem,
|
||||
TaskMark = taskMark,
|
||||
@ -1101,7 +1101,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
int pageNumber = 0;
|
||||
bool hasNext;
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
options.PageIndex = pageNumber++;
|
||||
|
||||
@ -16,6 +16,7 @@ using JiShe.CollectBus.IotSystems.Watermeter;
|
||||
using JiShe.CollectBus.Kafka.Internal;
|
||||
using JiShe.CollectBus.Kafka.Producer;
|
||||
using JiShe.CollectBus.Protocol.Contracts.Interfaces;
|
||||
using JiShe.CollectBus.Protocol.Contracts.SendData;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -38,7 +39,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
string serverTagName = string.Empty;
|
||||
private readonly ILogger<BasicScheduledMeterReadingService> _logger;
|
||||
private readonly IIoTDbProvider _dbProvider;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProtocolService _protocolService;
|
||||
|
||||
public EnergySystemScheduledMeterReadingService(
|
||||
ILogger<EnergySystemScheduledMeterReadingService> logger,
|
||||
@ -46,20 +47,20 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
IOptions<KafkaOptionConfig> kafkaOptions,
|
||||
IoTDBRuntimeContext runtimeContext,
|
||||
IProducerService producerService,
|
||||
IServiceProvider serviceProvider,
|
||||
IProtocolService protocolService,
|
||||
IRedisDataCacheService redisDataCacheService)
|
||||
: base(logger,
|
||||
producerService,
|
||||
redisDataCacheService,
|
||||
dbProvider,
|
||||
runtimeContext,
|
||||
serviceProvider,
|
||||
protocolService,
|
||||
kafkaOptions)
|
||||
{
|
||||
serverTagName = kafkaOptions.Value.ServerTagName;
|
||||
_dbProvider = dbProvider;
|
||||
_logger = logger;
|
||||
_serviceProvider = serviceProvider;
|
||||
_protocolService = protocolService;
|
||||
}
|
||||
|
||||
public sealed override string SystemType => SystemTypeConst.Energy;
|
||||
@ -178,14 +179,13 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override async Task AmmeterScheduledAutoValveControl()
|
||||
{
|
||||
var handlerPacketBuilder = TelemetryPacketBuilder.AFNHandlersDictionary;
|
||||
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
string currentTimeStr = $"{currentTime:HH:mm}";
|
||||
|
||||
try
|
||||
{
|
||||
//获取电表阀控配置
|
||||
var settingInfos = await GetAmmeterAutoValveControlSetting(currentTimeStr);
|
||||
|
||||
if (settingInfos == null || settingInfos.Count <= 0)
|
||||
@ -242,45 +242,25 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
_logger.LogError($"集中器[{settingInfo.FocusAddress}],[{settingInfo.MeterId}]阀控命令错误:{settingInfo.TripType},-102");
|
||||
continue;
|
||||
}
|
||||
|
||||
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
|
||||
|
||||
var temCode = "10_01_";
|
||||
|
||||
//根据电表型号获取协议插件
|
||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
||||
if (protocolPlugin == null)
|
||||
{
|
||||
_logger.LogError("协议不存在!");
|
||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
||||
return;
|
||||
}
|
||||
|
||||
var temCode = "10_98";
|
||||
var itemCodeArr = temCode.Split('_');
|
||||
var aFNStr = itemCodeArr[0];
|
||||
var aFN = (AFN)(aFNStr.HexToDec());
|
||||
var fn = int.Parse(itemCodeArr[1]);
|
||||
TelemetryPacketResponse builderResponse = null;
|
||||
string methonCode = $"AFN{aFNStr}_Fn_Send";
|
||||
//特殊表暂不处理
|
||||
if (handlerPacketBuilder != null && handlerPacketBuilder.TryGetValue(methonCode
|
||||
, out var handler))
|
||||
BuildResponse builderResponse = await protocolPlugin.BuildAsync(new BuildRequest()
|
||||
{
|
||||
builderResponse = handler(new TelemetryPacketRequest()
|
||||
{
|
||||
FocusAddress = ammeterInfo.FocusAddress,
|
||||
Fn = fn,
|
||||
Pn = ammeterInfo.MeteringCode,
|
||||
DataUnit = Build645SendData.BuildAmmeterValveControlSendDataUnit(ammeterInfo.AmmerterAddress, "", ammeterInfo.Password, tripStateResult),//生成阀控报文
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{temCode}无效编码,-103");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (builderResponse == null)
|
||||
{
|
||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{temCode}报文构建失败,-104");
|
||||
continue;
|
||||
}
|
||||
|
||||
string taskMark = CommonHelper.GetTaskMark((int)aFN, fn, ammeterInfo.MeteringCode, builderResponse.MSA,builderResponse.Seq.PRSEQ);
|
||||
FocusAddress = ammeterInfo.FocusAddress,
|
||||
Pn = ammeterInfo.MeteringCode,
|
||||
ItemCode = temCode,
|
||||
});
|
||||
|
||||
string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, ammeterInfo.MeteringCode, builderResponse.MSA,builderResponse.Seq);
|
||||
var meterReadingRecords = new MeterReadingTelemetryPacketInfo()
|
||||
{
|
||||
SystemName = SystemType,
|
||||
@ -292,9 +272,9 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
PendingCopyReadTime = currentTime,
|
||||
CreationTime = currentTime,
|
||||
MeterAddress = ammeterInfo.AmmerterAddress,
|
||||
AFN = (int)aFN,
|
||||
Fn = fn,
|
||||
Seq = builderResponse.Seq.PRSEQ,
|
||||
AFN = builderResponse.AFn,
|
||||
Fn = builderResponse.Fn,
|
||||
Seq = builderResponse.Seq,
|
||||
MSA = builderResponse.MSA,
|
||||
ItemCode = temCode,
|
||||
TaskMark = taskMark,
|
||||
@ -310,7 +290,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
}
|
||||
if (taskList == null || taskList.Count <= 0)
|
||||
{
|
||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有自动阀控任务生成,-105");
|
||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有自动阀控任务生成,-106");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -334,9 +314,6 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
throw new NotImplementedException($"{nameof(GetAmmeterInfoList)}请根据不同系统类型进行实现");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -69,6 +69,7 @@ namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
var strP = password.StrAddSpan().StrReverseOrder();
|
||||
var strSJY = " " + pwdLevel + " " + strP + " 01 00 00 00 " + code + " 00 " + strDate;
|
||||
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
|
||||
|
||||
var dataList = Build645SendCommand(ammeterAddress, "1C", dataUnit);
|
||||
return dataList;
|
||||
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
using JiShe.CollectBus.Common.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JiShe.CollectBus.Common.BuildSendDatas
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文构建返回结果
|
||||
/// </summary>
|
||||
public class TelemetryPacketResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 帧序列域SEQ
|
||||
/// </summary>
|
||||
public required Seq Seq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址域A3的主站地址MSA
|
||||
/// </summary>
|
||||
public int MSA { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文体
|
||||
/// </summary>
|
||||
public required byte[] Data { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user