From d9c54677a90a649ab4a7cdb6e973b1779794c4b3 Mon Sep 17 00:00:00 2001 From: Dai Mr <1822802785@qq.com> Date: Thu, 7 Nov 2024 19:39:05 +0800 Subject: [PATCH] update --- .../Enums/F25DataItemEnum.cs | 62 +++ .../Enums/TransparentForwardingFlagEnum.cs | 21 + .../Extensions/HexStringExtensions.cs | 7 +- .../Abstracts/BaseProtocolPlugin.cs | 376 +++++++++++++++++- 4 files changed, 452 insertions(+), 14 deletions(-) create mode 100644 JiShe.CollectBus.Common/Enums/F25DataItemEnum.cs create mode 100644 JiShe.CollectBus.Common/Enums/TransparentForwardingFlagEnum.cs diff --git a/JiShe.CollectBus.Common/Enums/F25DataItemEnum.cs b/JiShe.CollectBus.Common/Enums/F25DataItemEnum.cs new file mode 100644 index 0000000..60ca270 --- /dev/null +++ b/JiShe.CollectBus.Common/Enums/F25DataItemEnum.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Enums +{ + public enum F25DataItemEnum + { + [Description("终端抄表时间")] + ReadingTime = 0, + //Current + [Description("当前总有功功率")] + CrntTotalActivePower = 5, + [Description("当前A相有功功率")] + CrntActivePowerOfA = 8, + [Description("当前B相有功功率")] + CrntActivePowerOfB = 11, + [Description("当前C相有功功率")] + CrntActivePowerOfC = 14, + [Description("当前总无功功率")] + CrntTotalReactivePower =17, + [Description("当前A相无功功率")] + CrntReactivePowerOfA = 20, + [Description("当前B相无功功率")] + CrntReactivePowerOfB = 23, + [Description("当前C相无功功率")] + CrntReactivePowerOfC = 26, + [Description("当前总功率因数")] + CrntTotalPowerFactor = 29, + [Description("当前A相功率因数")] + CrntPowerFactorOfA = 31, + [Description("当前B相功率因数")] + CrntPowerFactorOfB =33, + [Description("当前C相功率因数")] + CrntPowerFactorOfC = 35, + [Description("当前A相电压")] + CrntVoltageOfA = 37, + [Description("当前B相电压")] + CrntVoltageOfB = 39, + [Description("当前C相电压")] + CrntVoltageOfC = 41, + [Description("当前A相电流")] + CrntCurrentOfA = 43, + [Description("当前B相电流")] + CrntCurrentOfB = 46, + [Description("当前C相电流")] + CrntCurrentOfC = 49, + [Description("当前零序电流")] + CrntZeroSequenceCurrent = 52, + [Description("当前总视在功率")] + CrntTotalApparentPower = 55, + [Description("当前A相视在功率")] + CrntApparentPowerOfA = 58, + [Description("当前B相视在功率")] + CrntApparentPowerOfB = 61, + [Description("当前C相视在功率")] + CrntApparentPowerOfC = 64 + } +} diff --git a/JiShe.CollectBus.Common/Enums/TransparentForwardingFlagEnum.cs b/JiShe.CollectBus.Common/Enums/TransparentForwardingFlagEnum.cs new file mode 100644 index 0000000..74fac36 --- /dev/null +++ b/JiShe.CollectBus.Common/Enums/TransparentForwardingFlagEnum.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Common.Enums +{ + /// + /// 透明转发结果标志 + /// + public enum TransparentForwardingFlagEnum + { + 不能执行转发=0, + 转发接收超时=1, + 转发接收错误=2, + 转发接收确认=3, + 转发接收否认=4, + 转发接收数据=5 + } +} diff --git a/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs b/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs index 8e394a7..c76d447 100644 --- a/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs +++ b/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs @@ -68,10 +68,15 @@ namespace JiShe.CollectBus.Common.Extensions PRSEQ = prseqBin.BinToDec(), TpV = tpV }; - case CommandChunkEnum.Data: + case CommandChunkEnum.Data: var lenIndex = (int)CommandChunkEnum.Len; var lenBin = (hexStringList[lenIndex + 1]+hexStringList[lenIndex]).HexToBin(); var len = lenBin.Remove(lenBin.Length - 2).BinToDec(); + + //验证长度 2=(帧校验和+结束字符) + if (hexStringList.Count - 2 != hearderLen + len) + return null; + var dataHexList = hexStringList.Skip(FixedLength).Take(len + hearderLen - FixedLength).ToList(); return dataHexList; default: diff --git a/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs index aaa99ce..689c55e 100644 --- a/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs +++ b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs @@ -109,7 +109,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts /// /// /// - public virtual async Task AnswerAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + public virtual async Task GetAnswerAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) { var hexStringList = messageReceivedEvent.MessageHexString.StringToPairs(); var fn = hexStringList.GetAnalyzeValue(CommandChunkEnum.FN); @@ -125,10 +125,9 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts /// /// /// - public virtual async Task AmmeterParameterAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + public virtual async Task GetAmmeterParameterAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) { - var hexStringList = messageReceivedEvent.MessageHexString.StringToPairs(); - var hexDatas = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data); + var hexDatas = GetHexDatas(messageReceivedEvent.MessageHexString); var meterList = new List(); var count = (hexDatas[1] + hexDatas[0]).HexToDec(); @@ -206,10 +205,9 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts /// 报文 /// 发送委托 /// - public virtual async Task ActivePowerIndicationAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + public virtual async Task GetActivePowerIndicationAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) { - var hexStringList = messageReceivedEvent.MessageHexString.StringToPairs(); - var hexDatas = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data); + var hexDatas = GetHexDatas(messageReceivedEvent.MessageHexString); var minutes = Convert.ToInt32(hexDatas[0]); // 获取当前分钟数 var hours = Convert.ToInt32(hexDatas[1]); // 获取当前小时数 @@ -239,16 +237,368 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts /// /// /// - public virtual async Task DailyFrozenAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + public virtual async Task GetDailyFrozenAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) { - var hexStringList = messageReceivedEvent.MessageHexString.StringToPairs(); - var hexDatas = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data); + var hexDatas = GetHexDatas(messageReceivedEvent.MessageHexString); + //附录A.20 日月年 + var td_dHex= hexDatas.Take(3).ToList(); + //附录A.15 分时日月年 + var readingTimeHex = hexDatas.Skip(3).Take(5).ToList(); + var rateNumberHex = hexDatas.Skip(8).Take(1).FirstOrDefault().HexToDec(); + //附录A.14 kWh 5字节 + for (int i = 0; i < rateNumberHex; i++) + { + + } } - //TODO:F17 当前总加有功功率 附录A.2 kw 2字节 - //F18 当前总加无功功率 附录A.2 kvar 2字节 - //F25 161 + + //接收<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 + //++++++++++++++++++++++++++++++++++++ + + /// + /// 当前三相及总有/无功功率、功率因数、三相电压、电流、零序电流、视在功率 + /// + /// + /// + /// + public virtual async Task GetF25Async(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + { + var hexDatas = GetHexDatas(messageReceivedEvent.MessageHexString); + //A.15 分时日月年 + var readingTimeHex = hexDatas.Take(5).ToList(); + //A.9 kW + var crntTotalActivePowerHex = hexDatas.Skip((int)F25DataItemEnum.CrntTotalActivePower).Take(3).ToList(); + var crntActivePowerOfA = hexDatas.Skip((int)F25DataItemEnum.CrntActivePowerOfA).Take(3).ToList(); + var crntActivePowerOfB = hexDatas.Skip((int)F25DataItemEnum.CrntActivePowerOfB).Take(3).ToList(); + var crntActivePowerOfC = hexDatas.Skip((int)F25DataItemEnum.CrntActivePowerOfC).Take(3).ToList(); + var crntTotalReactivePower = hexDatas.Skip((int)F25DataItemEnum.CrntTotalReactivePower).Take(3).ToList(); + var crntReactivePowerOfA = hexDatas.Skip((int)F25DataItemEnum.CrntReactivePowerOfA).Take(3).ToList(); + var crntReactivePowerOfB = hexDatas.Skip((int)F25DataItemEnum.CrntReactivePowerOfB).Take(3).ToList(); + var crntReactivePowerOfC = hexDatas.Skip((int)F25DataItemEnum.CrntReactivePowerOfC).Take(2).ToList(); + + //A.5 % + var crntTotalPowerFactor = hexDatas.Skip((int)F25DataItemEnum.CrntTotalPowerFactor).Take(2).ToList(); + var crntPowerFactorOfA = hexDatas.Skip((int)F25DataItemEnum.CrntPowerFactorOfA).Take(2).ToList(); + var crntPowerFactorOfB = hexDatas.Skip((int)F25DataItemEnum.CrntPowerFactorOfB).Take(2).ToList(); + var CrntPowerFactorOfC = hexDatas.Skip((int)F25DataItemEnum.CrntPowerFactorOfC).Take(2).ToList(); + + //A.7 V + var crntVoltageOfA = hexDatas.Skip((int)F25DataItemEnum.CrntVoltageOfA).Take(2).ToList(); + var crntVoltageOfB = hexDatas.Skip((int)F25DataItemEnum.CrntVoltageOfB).Take(2).ToList(); + var crntVoltageOfC = hexDatas.Skip((int)F25DataItemEnum.CrntVoltageOfC).Take(2).ToList(); + + //A.25 A + var crntCurrentOfA = hexDatas.Skip((int)F25DataItemEnum.CrntCurrentOfA).Take(3).ToList(); + var crntCurrentOfB = hexDatas.Skip((int)F25DataItemEnum.CrntCurrentOfB).Take(3).ToList(); + var crntCurrentOfC = hexDatas.Skip((int)F25DataItemEnum.CrntCurrentOfC).Take(3).ToList(); + var crntZeroSequenceCurrent = hexDatas.Skip((int)F25DataItemEnum.CrntZeroSequenceCurrent).Take(3).ToList(); + + //A.9 kVA + var crntTotalApparentPower = hexDatas.Skip((int)F25DataItemEnum.CrntTotalApparentPower).Take(3).ToList(); + var crntApparentPowerOfA = hexDatas.Skip((int)F25DataItemEnum.CrntApparentPowerOfA).Take(3).ToList(); + var crntApparentPowerOfB = hexDatas.Skip((int)F25DataItemEnum.CrntApparentPowerOfB).Take(3).ToList(); + var crntApparentPowerOfC = hexDatas.Skip((int)F25DataItemEnum.CrntApparentPowerOfC).Take(3).ToList(); + + } + + /// + /// 透明转发 命令 应答 + /// + /// + /// + /// + public virtual async Task GetTransparentForwardingResultAsync(MessageReceivedHeartbeatEvent messageReceivedEvent, Action? sendAction = null) + { + var hexDatas = GetHexDatas(messageReceivedEvent.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; + } + + private static List GetHexDatas(string messageHexString) + { + var hexStringList = messageHexString.StringToPairs(); + var hexDatas = (List)hexStringList.GetAnalyzeValue(CommandChunkEnum.Data); + return hexDatas; + } + + /// + /// 解析时间标签 + /// + /// + private void AnalysisTp(List hexDatas) + { + var pFC = hexDatas[0].HexToDec();//启动帧帧序号计数器 + var seconds = Convert.ToInt32(hexDatas[1]); // 获取当前秒数 + var minutes = Convert.ToInt32(hexDatas[2]); // 获取当前分钟数 + var hours = Convert.ToInt32(hexDatas[3]); // 获取当前小时数 + var day = Convert.ToInt32(hexDatas[4]); // 获取当前日期的日数 + var delayTime = hexDatas[5].HexToDec();//延迟时间 min + } + + /// + /// 数据格式05 + /// + /// + /// + private decimal AnalysisA05(string hex1,string hex2) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); + var hundredDigitNumbers = bin1.Substring(1, 3).BinToDec();//百位 + var tenDigitNumber = bin1.Substring(4).BinToDec();//十位 + + var bin2 = hex2.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 + /// + /// + /// + private decimal AnalysisA07(string hex1, string hex2) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); + var tenDigitNumber = bin1.Substring(1, 3).BinToDec();//十位 + var singleDigitNumber = bin1.Substring(4).BinToDec();//个位 + + var bin2 = hex2.HexToBin().PadLeft(8, '0'); + var deciles = bin1.Substring(0, 4).BinToDec();//十分位 + var percentile = bin1.Substring(4).BinToDec();//百分位 + + var value = decimal.Parse($"{tenDigitNumber}{singleDigitNumber}.{deciles}{percentile}"); + return value; + } + + /// + /// 数据格式09 + /// + /// + /// + /// + private decimal AnalysisA09(string hex1, string hex2, string tenAndSingleDigit) + { + 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}.{hex2}{hex1}"); + 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 TODO:待优化 + /// + /// + /// + /// + /// + /// + /// + /// + private string AnalysisA12(string hex1, string hex2, string hex3, string hex4, string hex5, string hex6) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); ; + var hundredBillionsOfPosition = bin1.Substring(0, 4).BinToDec();//千亿位 + var billionsOfPosition = bin1.Substring(4).BinToDec();//百亿位 + + var bin2 = hex2.HexToBin().PadLeft(8, '0'); ; + var billionOfPosition = bin2.Substring(0, 4).BinToDec();//十亿位 + var hundredMillionOfPosition = bin2.Substring(4).BinToDec();//亿位 + + var bin3 = hex3.HexToBin().PadLeft(8, '0'); ; + var millionsOfPosition = bin3.Substring(0, 4).BinToDec();//千万位 + var millionOfPosition = bin3.Substring(4).BinToDec();//百万位 + + var bin4 = hex4.HexToBin().PadLeft(8, '0'); ; + var hundredThousandOfPosition = bin4.Substring(0, 4).BinToDec();//十万位 + var tenThousandOfPosition = bin4.Substring(4).BinToDec();//万位 + + var bin5 = hex5.HexToBin().PadLeft(8, '0'); ; + var thousandOfPosition = bin5.Substring(0, 4).BinToDec();//千位 + var hundredsOfPosition = bin5.Substring(4).BinToDec();//百位 + + var bin6 = hex6.HexToBin().PadLeft(8, '0'); + var tenDigitNumber = bin6.Substring(0, 4).BinToDec();//十位 + var singleDigitNumber = bin6.Substring(4).BinToDec();//个位 + + var value = $"{hundredBillionsOfPosition}{billionsOfPosition}{billionOfPosition}{hundredMillionOfPosition}{millionsOfPosition}" + + $"{hundredThousandOfPosition}{tenThousandOfPosition}{thousandOfPosition}{hundredsOfPosition}{tenDigitNumber}{singleDigitNumber}"; + + return value; + } + + /// + /// 数据格式14 + /// + /// + /// + /// + /// + /// + /// + private decimal AnalysisA14(string hex1, string hex2, string hex3, string hex4, string hex5) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); + var hundredThousandOfPosition = bin1.Substring(0, 4).BinToDec();//十万位 + var tenThousandOfPosition = bin1.Substring(4).BinToDec();//万位 + + var bin2 = hex2.HexToBin().PadLeft(8, '0'); + var thousandOfPosition = bin2.Substring(0, 4).BinToDec();//千位 + var hundredsOfPosition = bin2.Substring(4).BinToDec();//百位 + + var bin3 = hex3.HexToBin().PadLeft(8, '0'); + var tenDigitNumber = bin3.Substring(0, 4).BinToDec();//十位 + var singleDigitNumber = bin3.Substring(4).BinToDec();//个位 + + var bin4 = hex4.HexToBin().PadLeft(8, '0'); + var deciles = bin4.Substring(0, 4).BinToDec();//十分位 + var percentile = bin4.Substring(4).BinToDec();//百分位 + + var bin5 = hex5.HexToBin().PadLeft(8, '0'); + var thousandthPercentile = bin5.Substring(0, 4).BinToDec();//千分位 + var tenThousandPositions = bin5.Substring(4).BinToDec();//万分位 + + var value = decimal.Parse($"{hundredThousandOfPosition}{tenThousandOfPosition}{thousandOfPosition}{hundredsOfPosition}" + + $"{tenDigitNumber}{singleDigitNumber}.{deciles}{percentile}{thousandthPercentile}{tenThousandPositions}"); + + return value; + } + + /// + /// 数据格式A.15 + /// + /// + /// + /// + /// + /// + /// + private DateTime AnalysisA15(string hex1, string hex2, string hex3, string hex4, string hex5) + { + var centuryString = (DateTime.Now.Year / 100).ToString(); + var time = DateTime.Parse($"{centuryString}{hex5}-{hex4}-{hex3} {hex2}:{hex1}: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();//个位 + } + + private void AnalysisA20(string hex1, string hex2, string hex3) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); + var tenDigitNumberOfYear = bin1.Substring(0, 4).BinToDec();//十位 + var singleDigitNumberOfYear = bin1.Substring(4).BinToDec();//个位 + + var bin2 = hex2.HexToBin().PadLeft(8, '0'); + var tenDigitNumberOfMonth = bin2.Substring(0, 4).BinToDec();//十位 + var singleDigitNumberOfMonth = bin2.Substring(4).BinToDec();//个位 + + var bin3 = hex3.HexToBin().PadLeft(8, '0'); + var tenDigitNumberOfDay = bin3.Substring(0, 4).BinToDec();//十位 + var singleDigitNumberOfDay = bin3.Substring(4).BinToDec();//个位 + + } + + /// + /// 数据格式25 + /// + /// + /// + /// + private decimal AnalysisA25(string hex1, string hex2, string hex3) + { + var bin1 = hex1.HexToBin().PadLeft(8, '0'); + var hundredDigitNumbers = bin1.Substring(1, 3).BinToDec();//百位 + var tenDigitNumber = bin1.Substring(4).BinToDec();//十位 + + var bin2 = hex2.HexToBin().PadLeft(8, '0'); + var singleDigitNumber = bin1.Substring(0, 4).BinToDec();//个位 + var deciles = bin1.Substring(4).BinToDec();//十分位 + + var bin3 = hex3.HexToBin().PadLeft(8, '0'); + var percentile = bin3.Substring(0,4).BinToDec();//百分位 + var thousandthPercentile = bin3.Substring(4).BinToDec();//千分位 + + var value = decimal.Parse($"{hundredDigitNumbers}{tenDigitNumber}{singleDigitNumber}.{deciles}{percentile}{thousandthPercentile}"); + return value; + } + + #region 通用解析 public byte[] GetCommandBytes(ReqParameter reqParameter, List? dataUnit = null)