From e20b7753d2ea27f2fa3987aa864c1e328fa656a5 Mon Sep 17 00:00:00 2001 From: Dai Mr <1822802785@qq.com> Date: Fri, 8 Nov 2024 14:53:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E4=B8=8B=E5=8F=91=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/WeatherForecastController.cs | 107 +++- .../JiShe.CollectBus.Api.csproj | 5 + .../Extensions/HexStringExtensions.cs | 456 +++++++++++++++++- .../Models/ReqParameter.cs | 9 +- .../Abstracts/BaseProtocolPlugin.cs | 396 +-------------- .../StandardProtocolPlugin.cs | 6 +- 6 files changed, 569 insertions(+), 410 deletions(-) rename {JiShe.CollectBus.Protocol.Contracts => JiShe.CollectBus.Common}/Models/ReqParameter.cs (90%) diff --git a/JiShe.CollectBus.Api/Controllers/WeatherForecastController.cs b/JiShe.CollectBus.Api/Controllers/WeatherForecastController.cs index dd9e64a..1cdb5fd 100644 --- a/JiShe.CollectBus.Api/Controllers/WeatherForecastController.cs +++ b/JiShe.CollectBus.Api/Controllers/WeatherForecastController.cs @@ -1,4 +1,10 @@ +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.Protocol.Contracts.Models; +using JiShe.CollectBus.RabbitMQ.Senders; using Microsoft.AspNetCore.Mvc; +using TouchSocket.Sockets; namespace JiShe.CollectBus.Api.Controllers { @@ -12,9 +18,11 @@ namespace JiShe.CollectBus.Api.Controllers }; private readonly ILogger _logger; + private readonly INSender _nSender; - public WeatherForecastController(ILogger logger) + public WeatherForecastController(INSender nSender, ILogger logger) { + _nSender = nSender; _logger = logger; } @@ -29,5 +37,102 @@ namespace JiShe.CollectBus.Api.Controllers }) .ToArray(); } + + [HttpGet(Name = "AmmeterParameterSend")] + public async Task AmmeterParameterSendAsync() { + + var listMeter = new List() { new AmmeterParameter(){ + Pn = 1, + BaudRate = 3, + Port = 2, + ProtocolType = CommunicationProtocolType.DLT6452007, + Address = "312408006642", + Password = "000000", + RateNumber = 4, + IntegerBitNumber = 4, + DecimalBitNumber = 4, + CollectorAddress = "000000000000", + UserCategoryNumber = 0, + UserSubclassNumber = 0 + }}; + var bytes = HexStringExtensions.BuildAmmeterParameterSetSendCmd(new ReqParameter2() + { + AFN = AFN.设置参数, + FunCode = (int)CMasterStationFunCode.请求1级数据, + A = "322009872", + Seq = new Seq() + { + TpV = TpV.附加信息域中无时间标签, + FIRFIN = FIRFIN.单帧, + CON = CON.需要对该帧进行确认, + PRSEQ = 10, + }, + MSA = 13, + Pn = 0, + Fn = 10 + }, listMeter); + + // await _nSender.SendToIssuedAsync(new MessageIssuedEvent { DeviceNo = "322009872", Message = bytes, Type = IssuedEventType.Data,MessageId = Guid.NewGuid().ToString() }); + return true; + } + + [HttpGet(Name = "AmmeterParameterReading")] + public bool AmmeterParameterReading() + { + HexStringExtensions.BuildAmmeterParameterReadingSendCmd(new ReqParameter2() + { + AFN = AFN.查询参数, + FunCode = (int)CMasterStationFunCode.请求2级数据, + A = "322009872", + Seq = new Seq() + { + TpV = TpV.附加信息域中无时间标签, + FIRFIN = FIRFIN.单帧, + CON = CON.不需要对该帧进行确认, + PRSEQ = 2, + }, + MSA = 13, + Pn = 0, + Fn = 10 + }, new List() { 1, 2 }); + + return true; + } + + [HttpGet(Name = "ActivePowerIndicationReading")] + public bool ActivePowerIndicationReading() + { + + //var str = "68A600A6006888203290261A0A6200000201010001000100621E426622082431000000000000040300000000000000CA16"; + //var cmdResult = new BuildCommand().AnalysisCmd(str); + //if(cmdResult != null) + //{ + // var list = new BuildCommand().AnalysisAFN04F10DataUnit(cmdResult.HexDatas); + //} + HexStringExtensions.BuildSendCommandBytes(new ReqParameter2() + { + AFN = AFN.请求实时数据, + FunCode = (int)CMasterStationFunCode.请求2级数据, + A = "322009872", + Seq = new Seq() + { + TpV = TpV.附加信息域中无时间标签, + FIRFIN = FIRFIN.单帧, + CON = CON.不需要对该帧进行确认, + PRSEQ = 2, + }, + MSA = 13, + Pn = 1, + Fn = 129 + }); + + //HexStringExtensions.AmmeterValveControl("312408006642", "", "000000", true); + + return true; + } + + + + } } diff --git a/JiShe.CollectBus.Api/JiShe.CollectBus.Api.csproj b/JiShe.CollectBus.Api/JiShe.CollectBus.Api.csproj index 9daa180..f86353b 100644 --- a/JiShe.CollectBus.Api/JiShe.CollectBus.Api.csproj +++ b/JiShe.CollectBus.Api/JiShe.CollectBus.Api.csproj @@ -10,4 +10,9 @@ + + + + + diff --git a/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs b/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs index c76d447..5f12944 100644 --- a/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs +++ b/JiShe.CollectBus.Common/Extensions/HexStringExtensions.cs @@ -1,12 +1,5 @@ 锘縰sing JiShe.CollectBus.Common.Enums; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; using JiShe.CollectBus.Common.Models; -using System.Runtime.CompilerServices; namespace JiShe.CollectBus.Common.Extensions { @@ -25,7 +18,6 @@ namespace JiShe.CollectBus.Common.Extensions private const int FixedLength = 18; - public static object GetAnalyzeValue(this List hexStringList, CommandChunkEnum chunk) { if (hexStringList.Count < hearderLen || hexStringList[0] != startStr || hexStringList[5] != startStr || hexStringList.Count < FixedLength) @@ -84,6 +76,454 @@ namespace JiShe.CollectBus.Common.Extensions } } + public static bool IsStartStr(this string str) + { + return str == startStr ? true : false; + } + + #region 涓嬭鍛戒护 + + /// + /// 鏋勫缓鐢佃〃鍙傛暟璁剧疆-涓嬪彂鍛戒护 + /// + /// + /// + /// + public static byte[] BuildAmmeterParameterSetSendCmd(ReqParameter reqParameter, List meterParameters) + { + var dataUnit = BuildAmmeterParameterSendDataUnit(meterParameters); + var bytes = BuildSendCommandBytes(reqParameter, dataUnit); + return bytes; + } + + /// + /// 鏋勫缓鐢佃〃鍙傛暟璇诲彇-涓嬪彂鍛戒护 + /// + /// + /// 瀵硅薄搴忓彿 + public static void BuildAmmeterParameterReadingSendCmd(ReqParameter reqParameter, List meterNumberList) + { + var dataUnit = new List(); + var countHex = meterNumberList.Count().DecToHex().PadLeft(4, '0'); + var countHexPairs = countHex.StringToPairs(); + countHexPairs.Reverse(); + dataUnit.AddRange(countHexPairs); + + foreach (var number in meterNumberList) + { + var numberHex = number.DecToHex().PadLeft(4, '0'); + var numberHexPairs = numberHex.StringToPairs(); + numberHexPairs.Reverse(); + dataUnit.AddRange(numberHexPairs); + } + var bytes = BuildSendCommandBytes(reqParameter, dataUnit); + } + + + /// + /// 鏋勫缓閫忔槑杞彂-涓嬪彂鏁版嵁鍗曞厓 + /// + /// 缁堢閫氫俊绔彛 1~31 + /// 0~7 瀵瑰簲300,600,1200,2400,4800,7200,9600,19200 + /// + /// + /// + /// + public static List BuildTransparentForwardingSendDataUnit(int port, BaudRate baudRate, StopBit stopBit, Parity parity, DataBit dataBit, + int waitContentTimeout, int waitByteTimeout, List datas) + { + var dataUnit = new List(); + + var portHex = port.DecToHex().PadLeft(2, '0'); + dataUnit.Add(portHex); + + var baudRateBin = ((int)baudRate).DecToBin().PadLeft(3, '0'); + var stopBitBin = ((int)stopBit).DecToBin(); + var parityBin = parity != Parity.None ? $"1{((int)parity).DecToBin()}" : $"0{((int)parity).DecToBin()}"; + var dataBitBin = ((int)dataBit).DecToBin().PadLeft(2, '0'); + var controlHex = $"{baudRateBin}{stopBitBin}{parityBin}{dataBitBin}".BinToHex().PadLeft(2, '0'); ; + dataUnit.Add(controlHex); + + var waitContentTimeoutBin = $"1{waitContentTimeout.DecToBin().PadLeft(7, '0')}"; + var waitContentTimeoutHex = waitContentTimeoutBin.BinToHex().PadLeft(2, '0'); + var waitByteTimeoutHex = waitByteTimeout.DecToHex().PadLeft(2, '0'); + + dataUnit.Add(waitContentTimeoutHex); + dataUnit.Add(waitByteTimeoutHex); + + var countHex = datas.Count.DecToHex().PadLeft(4, '0'); + var countHexPairs = countHex.StringToPairs(); + countHexPairs.Reverse(); + dataUnit.AddRange(countHexPairs); + + dataUnit.AddRange(datas); + + return dataUnit; + } + + /// + /// 鏋勫缓涓嬪彂鍛戒护 + /// + /// + /// + /// + public static byte[] BuildSendCommandBytes(ReqParameter reqParameter, List? dataUnit = null) + { + var cmdStrList = new List(); + var userDatas = BuildUserData(reqParameter, dataUnit); + var hearders = BuildHeaders(userDatas.Count); + var cs = GetCS(userDatas); + cmdStrList.AddRange(hearders); + cmdStrList.AddRange(userDatas); + cmdStrList.Add(cs); + cmdStrList.Add(endStr); + var bytes = cmdStrList.Select(x => Convert.ToByte(x, 16)).ToArray(); + return bytes; + } + + /// + /// 缁勮鐢佃〃闃鎺т笅鍙戞暟鎹崟鍏 + /// + /// 鐢佃〃鍦板潃 + /// 鐗规畩鎺у埗鐮 + /// 瀵嗙爜 + /// 鏄惁涓哄紑闃 + /// + public static List BuildAmmeterValveControlSendDataUnit(string address, string specialnocode, string password, bool state, string modelCode = "") + { + address = address.Trim().TrimStart('0'); + if (address.Length < 12) address = address.PadLeft(12, '0'); + string Code = string.Empty; + + if (state) + { + if (string.IsNullOrEmpty(specialnocode)) + Code = "1B"; + else + Code = specialnocode == "1B" || specialnocode == "1C" ? specialnocode : "1C"; + } + else + Code = "1A";//璺抽椄 + + if (specialnocode == "1W") + { + if (state) + Code = "1A"; + else + Code = "1C"; + } + + var pwdLevel = "02"; + if (modelCode == "HL_DTSU2625" || modelCode == "DDZY9866") + pwdLevel = "04"; + else if (modelCode == "DDS2705") + pwdLevel = "03"; + + if (!string.IsNullOrWhiteSpace(password) && password.Contains("|")) + { + var sp = password.Split('|'); + pwdLevel = sp[1]; + password = sp[0]; + } + + string strDate = DateTime.Now.AddYears(3).ToString("000012ddMMyy").StrAddSpan(); + if (specialnocode == "1D" || modelCode == "SZBD_DDZY1225") + strDate = "FF FF FF FF FF FF"; + string strP = password.StrAddSpan().StrReverseOrder(); + string strSJY = " " + pwdLevel + " " + strP + " 01 00 00 00 " + Code + " 00 " + strDate; + string strLen = (strSJY.Replace(" ", "").Length / 2).ToString("X2"); + string strReturn = "68 " + address.StrAddSpan().StrReverseOrder() + " 68 1C " + strLen + " " + StrAddHex33(strSJY) + " "; + string strSum = strReturn.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select(i => Convert.ToInt32(i, 16)).Sum().ToString("X"); + strReturn += strSum.Substring(strSum.Length - 2) + " 16"; + + return strReturn.Split(' ').ToList(); + } + + + /// + /// 鏋勫缓鐢佃〃鍙傛暟璁剧疆-涓嬪彂鏁版嵁鍗曞厓 + /// + /// + /// + private static List BuildAmmeterParameterSendDataUnit(List meterParameters) + { + var hexDatas = new List(); + + var countHex = meterParameters.Count().DecToHex().PadLeft(4, '0'); + hexDatas.Add(countHex); + + //TODO 浼樺寲浠g爜锛氱洰鏍囨暟鎹叆鍙傦紝杩斿洖绫诲瀷涓哄嚭鍙 + for (int i = 0; i <= meterParameters.Count - 1; i++) + { + var meter = meterParameters[i]; + + var indexHex = (i + 1).DecToHex().PadLeft(4, '0'); + hexDatas.Add(indexHex); + + var pnHex = meter.Pn.DecToHex().PadLeft(4, '0'); + hexDatas.Add(pnHex); + + var baudRateBin = meter.BaudRate.DecToBin().PadLeft(3, '0'); + var portBin = meter.Port.DecToBin().PadLeft(5, '0'); + var baudRateAndPortHex = $"{baudRateBin}{portBin}".BinToHex().PadLeft(2, '0'); + hexDatas.Add(baudRateAndPortHex); + + var protocolTypeHex = ((int)meter.ProtocolType).DecToHex().PadLeft(2, '0'); + hexDatas.Add(protocolTypeHex); + + hexDatas.Add(meter.Address); + + hexDatas.Add(meter.Password.PadLeft(12, '0')); + + var rateNumberBin = $"0000{meter.RateNumber.DecToBin().PadLeft(4, '0')}"; + var rateNumberHex = rateNumberBin.BinToHex().PadLeft(2, '0'); + hexDatas.Add(rateNumberHex); + + var intBitNumberBin = (meter.IntegerBitNumber - 4).DecToBin().PadLeft(2, '0'); + var decBitNumberBin = (meter.DecimalBitNumber - 1).DecToBin().PadLeft(2, '0'); + var intAndDecBitNumberBin = $"0000{intBitNumberBin}{decBitNumberBin}"; + var intAndDecBitNumberHex = intAndDecBitNumberBin.BinToHex().PadLeft(2, '0'); + hexDatas.Add(intAndDecBitNumberHex); + + hexDatas.Add(meter.CollectorAddress.PadLeft(12, '0')); + + var userCategoryNumberBin = meter.UserCategoryNumber.DecToBin().PadLeft(4, '0'); + var userSubclassNumberBin = meter.UserSubclassNumber.DecToBin().PadLeft(4, '0'); + var userNumberHex = $"{userCategoryNumberBin}{userSubclassNumberBin}".BinToHex().PadLeft(2, '0'); + hexDatas.Add(userNumberHex); + } + + //楂樹綅鍦ㄥ墠锛屼綆浣嶅湪鍚 + var datas = new List(); + foreach (var hexData in hexDatas) + { + if (hexData.Length == 2) + datas.Add(hexData); + else + { + var lst = hexData.StringToPairs(); + lst.Reverse(); + datas.AddRange(lst); + } + } + datas.AddRange(GetPW()); + return datas; + } + + + //AUX=娑堟伅璁よ瘉鐮佸瓧娈碉紙PW,16涓瓧鑺傦級 + private static List GetPW() + { + var str = "00"; + var pWList = Enumerable.Repeat(str, pWLen).ToList(); + return pWList; + } + + + + /// + /// 甯ф牎楠屽拰 + /// + /// 鐢ㄦ埛鏁版嵁鍖 + /// + private static string GetCS(List userData) + { + byte sum = 0; + foreach (var d in userData) + { + var b = Convert.ToByte(d, 16); + sum += b; + } + return sum.ToString("X2"); + } + + /// + /// 鐢ㄦ埛鏁版嵁鍖 + /// + /// + /// + private static List BuildUserData(ReqParameter reqParameter, List? dataUnit) + { + var c = BuildC(reqParameter.FunCode, reqParameter.PRM); + var a = BuildAList(reqParameter.A, reqParameter.MSA); + + var linkUserData = BuildLinkUserData(reqParameter.AFN, reqParameter.Seq, + ((ReqParameter2)reqParameter).Pn, ((ReqParameter2)reqParameter).Fn, dataUnit); + + var list = new List() { c }; + list.AddRange(a); + list.AddRange(linkUserData); + return list; + } + + /// + /// 鍥哄畾闀垮害鐨勬姤鏂囧ご 璧峰瀛楃+闀垮害+闀垮害+璧峰瀛楃 + /// + /// + /// + private static List BuildHeaders(int length) + { + var headers = new List(); + headers.Add(startStr); + var l = BuildLength(length); + headers.AddRange(l); + headers.AddRange(l); + headers.Add(startStr); + return headers; + } + + /// + /// 闀垮害 2瀛楄妭 [鐢ㄦ埛鏁版嵁鍖洪暱搴 + /// + /// + private static List BuildLength(int length1) + { + var binaryLen = length1.DecToBin(); + var protocolIdentification = Enum.Format(typeof(ProtocolIdentification), + ProtocolIdentification.鏈绾︿娇鐢, "d").PadLeft(2, '0'); + var lenStr = $"{binaryLen}{protocolIdentification}"; + var hexLen = lenStr.BinToHex(); + hexLen = hexLen.PadLeft(4, '0'); + var list = hexLen.StringToPairs(); + list.Reverse(); + return list; + } + + /// + /// 鎺у埗鍩 + /// + /// 鍔熻兘鐮 + /// + /// + /// + private static string BuildC(int funCode, PRM pRM, int fcb = 0, FCV fcv = FCV.FCB浣嶆棤鏁) + { + var cMasterStationFunCodeHex = funCode.DecToBin(); + cMasterStationFunCodeHex = cMasterStationFunCodeHex.ToString().PadLeft(4, '0'); + var strC = $"{(int)DIR.涓荤珯涓嬭鎶ユ枃}{(int)pRM}{fcb}{(int)fcv}{cMasterStationFunCodeHex}"; + var hexC = strC.BinToHex().PadLeft(2, '0'); + return hexC; + } + + + /// + /// 鍦板潃鍩 3220 09872 + /// + /// 琛屾斂鍖哄垝鐮 BCD鐮 3220=2032 + /// 閫昏緫鍦板潃 BIN 09872=2690=>9026 + /// 涓荤珯鍦板潃 BIN 0~127 + /// + private static List BuildAList(string a, int mSA) + { + var list = new List(); + + var a1 = a.Substring(0, 4); + var a1Pairs = a1.StringToPairs(); + a1Pairs.Reverse(); + list.AddRange(a1Pairs); + + var a2 = Convert.ToInt32(a.Substring(4)); + var decA2 = a2.DecToHex(); + var a2Pairs = decA2.PadLeft(4, '0').StringToPairs(); + a2Pairs.Reverse(); + list.AddRange(a2Pairs); + + //TODO:涓荤珯鍦板潃鍜岀粍鍦板潃鏍囧織 + var a3Bin = $"{mSA.DecToBin().PadLeft(7, '0')}0"; + list.Add(a3Bin.BinToHex().PadLeft(2, '0')); + + return list; + } + + private static List BuildLinkUserData(AFN aFN, Seq seq, int pn, int fn, List? dataUnit) + { + var aFNValue = ((int)aFN).DecToHex().PadLeft(2, '0'); + var sEQ = BuildSEQ(seq.TpV, seq.FIRFIN, seq.CON, seq.PRSEQ); + var dA = BuildDA(pn); + var dT = BuildDT(fn); + var list = new List() { aFNValue, sEQ }; + list.AddRange(dA); + list.AddRange(dT); + + if (dataUnit != null) + { + list.AddRange(dataUnit); + } + //list.AddRange(GetDataUnit(aFN,seq)); + + if (seq.TpV == TpV.闄勫姞淇℃伅鍩熶腑甯︽椂闂存爣绛) + list.AddRange(BuildTp("00")); + + return list; + } + + /// + /// 甯у簭鍒楀煙 + /// + /// + /// + /// + /// + private static string BuildSEQ(TpV tpV, FIRFIN fIRFIN, CON cON, int pRSEQ) + { + var tpVValue = Enum.Format(typeof(TpV), + tpV, "d"); + var fIRFINValue = Enum.Format(typeof(FIRFIN), + fIRFIN, "d"); + var cONValue = (int)cON; + var sEQBin = $"{tpVValue}{fIRFINValue}{cONValue}{pRSEQ.DecToBin().PadLeft(4, '0')}"; + var hexSEQ = sEQBin.BinToHex().PadLeft(2, '0'); + return hexSEQ; + } + + /// + /// 淇℃伅鐐规爣璇 + /// + /// 璁¢噺鐐 + /// + private static List BuildDA(int pn) + { + if (pn == 0) + return new List() { "00", "00" }; + var dA2 = (pn - 1) / 8 + 1;//淇℃伅鐐圭粍浠1寮濮 绗嚑缁 + var dA1 = pn - (dA2 - 1) * 8;//pn % 8 + var dA1Hex = "1".PadRight(dA1, '0').BinToHex();//瀵逛綅淇℃伅 绗嚑浣 浜岃繘鍒舵湁鏁堜綅 + var dA2Hex = dA2.DecToHex(); + return new List() { dA1Hex.PadLeft(2, '0'), dA2Hex.PadLeft(2, '0') }; + + } + + /// + /// 鏁版嵁鍗曞厓鏍囪瘑 + /// + /// + /// + private static List BuildDT(int fn) + { + var dT2 = (fn - 1) / 8;//浠庨浂寮濮 绗嚑缁 + var dT1 = fn - dT2 * 8; + var dT1Hex = "1".PadRight(dT1, '0').BinToHex();//瀵逛綅淇℃伅 绗嚑浣 浜岃繘鍒舵湁鏁堜綅 + var dT2Hex = dT2.DecToHex(); + return new List() { dT1Hex.PadLeft(2, '0'), dT2Hex.PadLeft(2, '0') }; + } + + /// + /// 鏃堕棿鏍囩 + /// + /// 鍚姩甯у抚搴忓彿璁℃暟鍣≒FC 1瀛楄妭 + /// 鍏佽鍙戦佷紶杈撳欢鏃舵椂闂 min 1瀛楄妭 + /// + private static List BuildTp(string pFC = "00", int delayTime = 0) + { + var now = DateTime.Now; // 鑾峰彇褰撳墠鏃堕棿 + var seconds = now.Second.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠绉掓暟 + var minutes = now.Minute.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠鍒嗛挓鏁 + var hours = now.Hour.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠灏忔椂鏁 + var day = now.Day.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠鏃ユ湡鐨勬棩鏁 + return new List() { pFC, seconds, minutes, hours, day, delayTime.ToString().PadLeft(2, '0') }; + } + + #endregion } } diff --git a/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs b/JiShe.CollectBus.Common/Models/ReqParameter.cs similarity index 90% rename from JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs rename to JiShe.CollectBus.Common/Models/ReqParameter.cs index 6e3b881..dba22df 100644 --- a/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs +++ b/JiShe.CollectBus.Common/Models/ReqParameter.cs @@ -1,12 +1,7 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Text; -using JiShe.CollectBus.Common; +锘 using JiShe.CollectBus.Common.Enums; -using JiShe.CollectBus.Common.Models; -namespace JiShe.CollectBus.Protocol.Contracts.Models +namespace JiShe.CollectBus.Common.Models { public class ReqParameter { diff --git a/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs index 43a017a..09ae408 100644 --- a/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs +++ b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs @@ -11,14 +11,9 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts { public abstract class BaseProtocolPlugin(ILogger logger) : IProtocolPlugin { - //璧峰瀛楃 - public const string stx = "68"; - //缁撴潫瀛楃 - public const string end = "16"; + //澶撮儴瀛楄妭闀垮害 - public const int hearderLen = 6; - //娑堟伅璁よ瘉鐮佸瓧娈甸暱搴 - public const int pWLen = 16; + public const int hearderLen = 6; public const int tPLen = 6; @@ -57,7 +52,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts Pn = 0, Fn = 1 }; - var bytes = BuildSendCommandBytes(reqParam); + var bytes = HexStringExtensions.BuildSendCommandBytes(reqParam); if (sendAction != null) { sendAction(bytes); @@ -99,7 +94,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts Pn = 0, Fn = 1 }; - var bytes = BuildSendCommandBytes(reqParam); + var bytes = HexStringExtensions.BuildSendCommandBytes(reqParam); if (sendAction != null) { sendAction(bytes); @@ -636,388 +631,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts #endregion - #region 涓嬭鍛戒护 - - /// - /// 鏋勫缓鐢佃〃鍙傛暟璁剧疆-涓嬪彂鍛戒护 - /// - /// - /// - /// - public byte[] BuildAmmeterParameterSetSendCmd(ReqParameter reqParameter, List meterParameters) - { - var dataUnit = BuildAmmeterParameterSendDataUnit(meterParameters); - var bytes = BuildSendCommandBytes(reqParameter, dataUnit); - return bytes; - } - - /// - /// 鏋勫缓鐢佃〃鍙傛暟璇诲彇-涓嬪彂鍛戒护 - /// - /// - /// 瀵硅薄搴忓彿 - public void BuildAmmeterParameterReadingSendCmd(ReqParameter reqParameter, List meterNumberList) - { - var dataUnit = new List(); - var countHex = meterNumberList.Count().DecToHex().PadLeft(4, '0'); - var countHexPairs = countHex.StringToPairs(); - countHexPairs.Reverse(); - dataUnit.AddRange(countHexPairs); - - foreach (var number in meterNumberList) - { - var numberHex = number.DecToHex().PadLeft(4, '0'); - var numberHexPairs = numberHex.StringToPairs(); - numberHexPairs.Reverse(); - dataUnit.AddRange(numberHexPairs); - } - var bytes = BuildSendCommandBytes(reqParameter, dataUnit); - } - - /// - /// 鏋勫缓鐢佃〃鍙傛暟璁剧疆-涓嬪彂鏁版嵁鍗曞厓 - /// - /// - /// - public List BuildAmmeterParameterSendDataUnit(List meterParameters) - { - var hexDatas = new List(); - - var countHex = meterParameters.Count().DecToHex().PadLeft(4, '0'); - hexDatas.Add(countHex); - - //TODO 浼樺寲浠g爜锛氱洰鏍囨暟鎹叆鍙傦紝杩斿洖绫诲瀷涓哄嚭鍙 - for (int i = 0; i <= meterParameters.Count - 1; i++) - { - var meter = meterParameters[i]; - - var indexHex = (i + 1).DecToHex().PadLeft(4, '0'); - hexDatas.Add(indexHex); - - var pnHex = meter.Pn.DecToHex().PadLeft(4, '0'); - hexDatas.Add(pnHex); - - var baudRateBin = meter.BaudRate.DecToBin().PadLeft(3, '0'); - var portBin = meter.Port.DecToBin().PadLeft(5, '0'); - var baudRateAndPortHex = $"{baudRateBin}{portBin}".BinToHex().PadLeft(2, '0'); - hexDatas.Add(baudRateAndPortHex); - - var protocolTypeHex = ((int)meter.ProtocolType).DecToHex().PadLeft(2, '0'); - hexDatas.Add(protocolTypeHex); - - hexDatas.Add(meter.Address); - - hexDatas.Add(meter.Password.PadLeft(12, '0')); - - var rateNumberBin = $"0000{meter.RateNumber.DecToBin().PadLeft(4, '0')}"; - var rateNumberHex = rateNumberBin.BinToHex().PadLeft(2, '0'); - hexDatas.Add(rateNumberHex); - - var intBitNumberBin = (meter.IntegerBitNumber - 4).DecToBin().PadLeft(2, '0'); - var decBitNumberBin = (meter.DecimalBitNumber - 1).DecToBin().PadLeft(2, '0'); - var intAndDecBitNumberBin = $"0000{intBitNumberBin}{decBitNumberBin}"; - var intAndDecBitNumberHex = intAndDecBitNumberBin.BinToHex().PadLeft(2, '0'); - hexDatas.Add(intAndDecBitNumberHex); - - hexDatas.Add(meter.CollectorAddress.PadLeft(12, '0')); - - var userCategoryNumberBin = meter.UserCategoryNumber.DecToBin().PadLeft(4, '0'); - var userSubclassNumberBin = meter.UserSubclassNumber.DecToBin().PadLeft(4, '0'); - var userNumberHex = $"{userCategoryNumberBin}{userSubclassNumberBin}".BinToHex().PadLeft(2, '0'); - hexDatas.Add(userNumberHex); - } - - //楂樹綅鍦ㄥ墠锛屼綆浣嶅湪鍚 - var datas = new List(); - foreach (var hexData in hexDatas) - { - if (hexData.Length == 2) - datas.Add(hexData); - else - { - var lst = hexData.StringToPairs(); - lst.Reverse(); - datas.AddRange(lst); - } - } - datas.AddRange(GetPW()); - return datas; - } - - /// - /// 鏋勫缓閫忔槑杞彂-涓嬪彂鏁版嵁鍗曞厓 - /// - /// 缁堢閫氫俊绔彛 1~31 - /// 0~7 瀵瑰簲300,600,1200,2400,4800,7200,9600,19200 - /// - /// - /// - /// - public List BuildTransparentForwardingSendDataUnit(int port, BaudRate baudRate, StopBit stopBit, Parity parity, DataBit dataBit, - int waitContentTimeout, int waitByteTimeout, List datas) - { - var dataUnit = new List(); - - var portHex = port.DecToHex().PadLeft(2, '0'); - dataUnit.Add(portHex); - - var baudRateBin = ((int)baudRate).DecToBin().PadLeft(3, '0'); - var stopBitBin = ((int)stopBit).DecToBin(); - var parityBin = parity != Parity.None ? $"1{((int)parity).DecToBin()}" : $"0{((int)parity).DecToBin()}"; - var dataBitBin = ((int)dataBit).DecToBin().PadLeft(2, '0'); - var controlHex = $"{baudRateBin}{stopBitBin}{parityBin}{dataBitBin}".BinToHex().PadLeft(2, '0'); ; - dataUnit.Add(controlHex); - - var waitContentTimeoutBin = $"1{waitContentTimeout.DecToBin().PadLeft(7, '0')}"; - var waitContentTimeoutHex = waitContentTimeoutBin.BinToHex().PadLeft(2, '0'); - var waitByteTimeoutHex = waitByteTimeout.DecToHex().PadLeft(2, '0'); - - dataUnit.Add(waitContentTimeoutHex); - dataUnit.Add(waitByteTimeoutHex); - - var countHex = datas.Count.DecToHex().PadLeft(4, '0'); - var countHexPairs = countHex.StringToPairs(); - countHexPairs.Reverse(); - dataUnit.AddRange(countHexPairs); - - dataUnit.AddRange(datas); - - return dataUnit; - } - - //AUX=娑堟伅璁よ瘉鐮佸瓧娈碉紙PW,16涓瓧鑺傦級 - public List GetPW() - { - var str = "00"; - var pWList = Enumerable.Repeat(str, pWLen).ToList(); - return pWList; - } - - /// - /// 鏋勫缓涓嬪彂鍛戒护 - /// - /// - /// - /// - public byte[] BuildSendCommandBytes(ReqParameter reqParameter, List? dataUnit = null) - { - var cmdStrList = new List(); - var userDatas = GetUserData(reqParameter, dataUnit); - var hearders = GetHeaders(userDatas.Count); - var cs = GetCS(userDatas); - cmdStrList.AddRange(hearders); - cmdStrList.AddRange(userDatas); - cmdStrList.Add(cs); - cmdStrList.Add(end); - logger.LogInformation($"鍥炲锛歿string.Join(" ", cmdStrList)}"); - var bytes = cmdStrList.Select(x => Convert.ToByte(x, 16)).ToArray(); - return bytes; - } - - /// - /// 甯ф牎楠屽拰 - /// - /// 鐢ㄦ埛鏁版嵁鍖 - /// - public string GetCS(List userData) - { - byte sum = 0; - foreach (var d in userData) - { - var b = Convert.ToByte(d, 16); - sum += b; - } - return sum.ToString("X2"); - } - - /// - /// 鐢ㄦ埛鏁版嵁鍖 - /// - /// - /// - public List GetUserData(ReqParameter reqParameter, List? dataUnit) - { - var c = GetC(reqParameter.FunCode, reqParameter.PRM); - var a = GetAList(reqParameter.A, reqParameter.MSA); - - var linkUserData = GetLinkUserData(reqParameter.AFN, reqParameter.Seq, - ((ReqParameter2)reqParameter).Pn, ((ReqParameter2)reqParameter).Fn, dataUnit); - - var list = new List() { c }; - list.AddRange(a); - list.AddRange(linkUserData); - return list; - } - - /// - /// 鍥哄畾闀垮害鐨勬姤鏂囧ご 璧峰瀛楃+闀垮害+闀垮害+璧峰瀛楃 - /// - /// - /// - public List GetHeaders(int length) - { - var headers = new List(); - headers.Add(stx); - var l = GetLength(length); - headers.AddRange(l); - headers.AddRange(l); - headers.Add(stx); - return headers; - } - - /// - /// 闀垮害 2瀛楄妭 [鐢ㄦ埛鏁版嵁鍖洪暱搴 - /// - /// - public List GetLength(int length1) - { - var binaryLen = length1.DecToBin(); - var protocolIdentification = Enum.Format(typeof(ProtocolIdentification), - ProtocolIdentification.鏈绾︿娇鐢, "d").PadLeft(2, '0'); - var lenStr = $"{binaryLen}{protocolIdentification}"; - var hexLen = lenStr.BinToHex(); - hexLen = hexLen.PadLeft(4, '0'); - var list = hexLen.StringToPairs(); - list.Reverse(); - return list; - } - - /// - /// 鎺у埗鍩 - /// - /// 鍔熻兘鐮 - /// - /// - /// - public string GetC(int funCode, PRM pRM, int fcb = 0, FCV fcv = FCV.FCB浣嶆棤鏁) - { - var cMasterStationFunCodeHex = funCode.DecToBin(); - cMasterStationFunCodeHex = cMasterStationFunCodeHex.ToString().PadLeft(4, '0'); - var strC = $"{(int)DIR.涓荤珯涓嬭鎶ユ枃}{(int)pRM}{fcb}{(int)fcv}{cMasterStationFunCodeHex}"; - var hexC = strC.BinToHex().PadLeft(2, '0'); - return hexC; - } - - - /// - /// 鍦板潃鍩 3220 09872 - /// - /// 琛屾斂鍖哄垝鐮 BCD鐮 3220=2032 - /// 閫昏緫鍦板潃 BIN 09872=2690=>9026 - /// 涓荤珯鍦板潃 BIN 0~127 - /// - public List GetAList(string a, int mSA) - { - var list = new List(); - - var a1 = a.Substring(0, 4); - var a1Pairs = a1.StringToPairs(); - a1Pairs.Reverse(); - list.AddRange(a1Pairs); - - var a2 = Convert.ToInt32(a.Substring(4)); - var decA2 = a2.DecToHex(); - var a2Pairs = decA2.PadLeft(4, '0').StringToPairs(); - a2Pairs.Reverse(); - list.AddRange(a2Pairs); - - //TODO:涓荤珯鍦板潃鍜岀粍鍦板潃鏍囧織 - var a3Bin = $"{mSA.DecToBin().PadLeft(7, '0')}0"; - list.Add(a3Bin.BinToHex().PadLeft(2, '0')); - - return list; - } - - public List GetLinkUserData(AFN aFN, Seq seq, int pn, int fn, List? dataUnit) - { - var aFNValue = ((int)aFN).DecToHex().PadLeft(2, '0'); - var sEQ = GetSEQ(seq.TpV, seq.FIRFIN, seq.CON, seq.PRSEQ); - var dA = GetDA(pn); - var dT = GetDT(fn); - var list = new List() { aFNValue, sEQ }; - list.AddRange(dA); - list.AddRange(dT); - - if (dataUnit != null) - { - list.AddRange(dataUnit); - } - //list.AddRange(GetDataUnit(aFN,seq)); - - if (seq.TpV == TpV.闄勫姞淇℃伅鍩熶腑甯︽椂闂存爣绛) - list.AddRange(GetTp("00")); - - return list; - } - - /// - /// 甯у簭鍒楀煙 - /// - /// - /// - /// - /// - public string GetSEQ(TpV tpV, FIRFIN fIRFIN, CON cON, int pRSEQ) - { - var tpVValue = Enum.Format(typeof(TpV), - tpV, "d"); - var fIRFINValue = Enum.Format(typeof(FIRFIN), - fIRFIN, "d"); - var cONValue = (int)cON; - var sEQBin = $"{tpVValue}{fIRFINValue}{cONValue}{pRSEQ.DecToBin().PadLeft(4, '0')}"; - var hexSEQ = sEQBin.BinToHex().PadLeft(2, '0'); - return hexSEQ; - } - - /// - /// 淇℃伅鐐规爣璇 - /// - /// 璁¢噺鐐 - /// - public List GetDA(int pn) - { - if (pn == 0) - return new List() { "00", "00" }; - var dA2 = (pn - 1) / 8 + 1;//淇℃伅鐐圭粍浠1寮濮 绗嚑缁 - var dA1 = pn - (dA2 - 1) * 8;//pn % 8 - var dA1Hex = "1".PadRight(dA1, '0').BinToHex();//瀵逛綅淇℃伅 绗嚑浣 浜岃繘鍒舵湁鏁堜綅 - var dA2Hex = dA2.DecToHex(); - return new List() { dA1Hex.PadLeft(2, '0'), dA2Hex.PadLeft(2, '0') }; - - } - - /// - /// 鏁版嵁鍗曞厓鏍囪瘑 - /// - /// - /// - public List GetDT(int fn) - { - var dT2 = (fn - 1) / 8;//浠庨浂寮濮 绗嚑缁 - var dT1 = fn - dT2 * 8; - var dT1Hex = "1".PadRight(dT1, '0').BinToHex();//瀵逛綅淇℃伅 绗嚑浣 浜岃繘鍒舵湁鏁堜綅 - var dT2Hex = dT2.DecToHex(); - return new List() { dT1Hex.PadLeft(2, '0'), dT2Hex.PadLeft(2, '0') }; - } - - /// - /// 鏃堕棿鏍囩 - /// - /// 鍚姩甯у抚搴忓彿璁℃暟鍣≒FC 1瀛楄妭 - /// 鍏佽鍙戦佷紶杈撳欢鏃舵椂闂 min 1瀛楄妭 - /// - public List GetTp(string pFC = "00", int delayTime = 0) - { - - var now = DateTime.Now; // 鑾峰彇褰撳墠鏃堕棿 - var seconds = now.Second.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠绉掓暟 - var minutes = now.Minute.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠鍒嗛挓鏁 - var hours = now.Hour.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠灏忔椂鏁 - var day = now.Day.ToString().PadLeft(2, '0'); // 鑾峰彇褰撳墠鏃ユ湡鐨勬棩鏁 - return new List() { pFC, seconds, minutes, hours, day, delayTime.ToString().PadLeft(2, '0') }; - } - - #endregion + } } diff --git a/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs index ca11a3d..fe6072d 100644 --- a/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs +++ b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs @@ -89,7 +89,7 @@ namespace JiShe.CollectBus.Protocol return commandReulst; } //楠岃瘉璧峰瀛楃 - if (hexStringList[0] != stx || hexStringList[5] != stx) + if (!hexStringList[0].IsStartStr() || !hexStringList[5].IsStartStr()) { return commandReulst; } @@ -253,7 +253,7 @@ namespace JiShe.CollectBus.Protocol Pn = 0, Fn = 1 }; - commandReulst.ReplyBytes = BuildSendCommandBytes(reqParam); + commandReulst.ReplyBytes = HexStringExtensions.BuildSendCommandBytes(reqParam); } else if (commandReulst.Fn == 2)//閫鍑虹櫥褰 { @@ -292,7 +292,7 @@ namespace JiShe.CollectBus.Protocol Pn = 0, Fn = 1 }; - commandReulst.ReplyBytes = BuildSendCommandBytes(reqParam); + commandReulst.ReplyBytes = HexStringExtensions.BuildSendCommandBytes(reqParam); } } #endregion