diff --git a/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs b/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs
index 374ca04..2907e27 100644
--- a/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs
+++ b/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs
@@ -30,7 +30,7 @@ namespace JiShe.CollectBus.Core.Plugins
var messageHexString = Convert.ToHexString(e.ByteBlock.Span);
client.Logger.Info($"[TCP] 已从{client.GetIPPort()}接收到信息:{messageHexString}");
-
+ protocolPlugin?.Received(e);
await e.InvokeNext();
}
diff --git a/JiShe.CollectBus.Protocol.Contracts/Models/Enums.cs b/JiShe.CollectBus.Protocol.Contracts/Models/Enums.cs
index 0b4a5a6..878d45c 100644
--- a/JiShe.CollectBus.Protocol.Contracts/Models/Enums.cs
+++ b/JiShe.CollectBus.Protocol.Contracts/Models/Enums.cs
@@ -121,7 +121,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Models
///
/// 通信协议类型 数值0-255
///
- public enum ProtocolType
+ public enum CommunicationProtocolType
{
DLT6451997 = 1,
交流采样装置 = 2,
diff --git a/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs b/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs
index 1d6761d..55756cd 100644
--- a/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs
+++ b/JiShe.CollectBus.Protocol.Contracts/Models/ReqParameter.cs
@@ -46,7 +46,7 @@ namespace JiShe.CollectBus.Protocol.Contracts.Models
///
public int Port { get; set; }
- public ProtocolType ProtocolType { get; set; }
+ public CommunicationProtocolType ProtocolType { get; set; }
///
/// 通信地址 0~999999999999
///
diff --git a/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
index ccdafce..1f7a7a1 100644
--- a/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
+++ b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
@@ -5,6 +5,7 @@ using JiShe.CollectBus.Protocol.Contracts.DependencyInjection;
using JiShe.CollectBus.Protocol.Contracts.Models;
using Microsoft.Extensions.Caching.Distributed;
using System.Data;
+using System.Net.Sockets;
using TouchSocket.Sockets;
namespace JiShe.CollectBus.Protocol
@@ -23,6 +24,18 @@ namespace JiShe.CollectBus.Protocol
private const int tPLen = 6;
+ static object locker = new object();
+ static List MSA = new List();
+ static Dictionary> usingMSA = new Dictionary>();
+
+ static StandardProtocolPlugin()
+ {
+ for (int i = 1; i <= 127; i++)
+ {
+ MSA.Add(i);
+ }
+ }
+
public override ProtocolInfo Get()
{
@@ -50,25 +63,431 @@ namespace JiShe.CollectBus.Protocol
throw new NotImplementedException();
}
+ ///
+ /// Gets the msa.
+ ///
+ /// The mark.
+ ///
+ public static int GetMSA(string mark)
+ {
+ lock (locker)
+ {
+ if (!usingMSA.Keys.Contains(mark))
+ usingMSA.Add(mark, new List());
+
+ int msa = MSA.Except(usingMSA[mark]).FirstOrDefault();
+ //if (msa == 1) msa = 2;//msa=1为自定义指令保留
+ usingMSA[mark].Add(msa);
+
+ if (msa == 127)
+ usingMSA[mark].RemoveAll(m => true);
+
+ return msa;
+ }
+ }
+
+ #region 上行命令
+
+ //68
+ //32 00
+ //32 00
+ //68
+ //C9 1100'1001. 控制域C。
+ // D7=1, (终端发送)上行方向。
+ // D6=1, 此帧来自启动站。
+ // D5=0, (上行方向)要求访问位。表示终端无事件数据等待访问。
+ // D4=0, 保留
+ // D3~D0=9, 功能码。链路测试
+
+ //20 32 行政区划码
+ //90 26 终端地址
+ //00 主站地址和组地址标志。终端为单地址。 //3220 09 87 2
+ // 终端启动的发送帧的 MSA 应为 0, 其主站响应帧的 MSA 也应为 0.
+ //02 应用层功能码。AFN=2, 链路接口检测
+ //70 0111'0000. 帧序列域。无时间标签、单帧、需要确认。
+ //00 00 信息点。DA1和DA2全为“0”时,表示终端信息点。
+ //01 00 信息类。F1, 登录。
+ //44 帧尾,包含用户区数据校验和
+ //16 帧结束标志
+
+ ///
+ /// 解析上行命令
+ ///
+ ///
+ ///
+ public CommandReulst? AnalysisCmd(string cmd)
+ {
+ CommandReulst? commandReulst = null;
+ var hexStringList = DataConvert.StringToPairs(cmd);
+
+ if (hexStringList.Count < hearderLen)
+ {
+ return commandReulst;
+ }
+ //验证起始字符
+ if (hexStringList[0] != stx || hexStringList[5] != stx)
+ {
+ return commandReulst;
+ }
+
+ var lenHexStr = $"{hexStringList[2]}{hexStringList[1]}";
+ var lenBin = DataConvert.HexToBin(lenHexStr);
+ var len = DataConvert.BinToDec(lenBin.Remove(lenBin.Length - 2));
+ //验证长度
+ if (hexStringList.Count - 2 != hearderLen + len)
+ return commandReulst;
+
+ var userDataIndex = hearderLen;
+ var c = hexStringList[userDataIndex];//控制域 1字节
+ userDataIndex += 1;
+
+ var aHexList = hexStringList.Skip(userDataIndex).Take(5).ToList();//地址域 5字节
+ var a = AnalysisA(aHexList);
+ var a3Bin = DataConvert.HexToBin(aHexList[4]).PadLeft(8, '0');
+ var mSA = DataConvert.BinToDec(a3Bin.Substring(0, 7));
+ userDataIndex += 5;
+
+ var aFN = (AFN)DataConvert.HexToDec(hexStringList[userDataIndex]);//1字节
+ userDataIndex += 1;
+
+ var seq = DataConvert.HexToBin(hexStringList[userDataIndex]).PadLeft(8, '0');
+ var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1));
+ var fIRFIN = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2));
+ var cON = (CON)Convert.ToInt32(seq.Substring(3, 1));
+ var prseqBin = seq.Substring(4, 4);
+ userDataIndex += 1;
+
+ // (DA2 - 1) * 8 + DA1 = pn
+ var da1Bin = DataConvert.HexToBin(hexStringList[userDataIndex]);
+ var da1 = da1Bin == "0" ? 0 : da1Bin.Length;
+ userDataIndex += 1;
+ var da2 = DataConvert.HexToDec(hexStringList[userDataIndex]);
+ userDataIndex += 1;
+ var pn = da2 == 0 ? 0 : (da2 - 1) * 8 + da1;
+
+ //(DT2*8)+DT1=fn
+ var dt1Bin = DataConvert.HexToBin(hexStringList[userDataIndex]);
+ var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0;
+ userDataIndex += 1;
+ var dt2 = DataConvert.HexToDec(hexStringList[userDataIndex]);
+ userDataIndex += 1;
+ var fn = dt2 * 8 + dt1;
+
+ //数据单元
+ var datas = hexStringList.Skip(userDataIndex).Take(len + hearderLen - userDataIndex).ToList();
+
+ //EC
+ //Tp
+ commandReulst = new CommandReulst()
+ {
+ A = a,
+ MSA = mSA,
+ AFN = aFN,
+ Seq = new Seq()
+ {
+ TpV = tpV,
+ FIRFIN = fIRFIN,
+ CON = cON,
+ PRSEQ = DataConvert.BinToDec(prseqBin),
+ },
+ CmdLength = len,
+ Pn = pn,
+ Fn = fn,
+ HexDatas = datas
+ };
+
+ return commandReulst;
+ }
+
+ ///
+ /// 解析地址
+ ///
+ ///
+ ///
+ private string AnalysisA(List aHexList)
+ {
+ var a1 = aHexList[1] + aHexList[0];
+ var a2 = aHexList[3] + aHexList[2];
+ var a2Dec = DataConvert.HexToDec(a2);
+ var a3 = aHexList[4];
+ var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}";
+ return a;
+ }
+
+ ///
+ /// 解析上行命令数据包
+ ///
+ ///
+ public void AnalysisData(CommandReulst commandReulst)
+ {
+ switch (commandReulst.AFN)
+ {
+ case AFN.确认或否认:
+ //commandReulst.fn
+ //1:全部确认
+ //2:全部否认
+ //3:按数据单元表示确认和否认
+ //4 硬件安全认证错误应答
+ break;
+ case AFN.复位:
+ break;
+ case AFN.链路接口检测:
+ AnalysisAFN02(commandReulst);
+ break;
+ case AFN.中继站命令:
+ break;
+ case AFN.设置参数:
+ break;
+ case AFN.控制命令:
+ break;
+ case AFN.身份认证及密钥协商:
+ break;
+ case AFN.备用:
+ break;
+ case AFN.请求被级联终端主动上报:
+ break;
+ case AFN.请求终端配置:
+ break;
+ case AFN.查询参数:
+ break;
+ case AFN.请求任务数据:
+ break;
+ case AFN.请求实时数据:
+ break;
+ case AFN.请求历史数据:
+ break;
+ case AFN.请求事件数据:
+ break;
+ case AFN.文件传输:
+ break;
+ case AFN.数据转发:
+ break;
+ default:
+ break;
+ }
+ }
+
+ //终端启动发送帧的MSA应为零,其主站响应帧的MSA也应为零
+ public void AnalysisAFN02(CommandReulst commandReulst)
+ {
+ if (commandReulst.Fn == 1) //登录
+ {
+ Console.WriteLine($"{commandReulst.A},登录:{DateTime.Now}");
+ var reqParam = new ReqParameter2()
+ {
+ AFN = AFN.确认或否认,
+ CMasterStationFunCode = CMasterStationFunCode.链路测试,
+ PRM = PRM.从动站报文,
+ A = commandReulst.A,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.不需要对该帧进行确认,
+ PRSEQ = commandReulst.Seq.PRSEQ,
+ },
+ MSA = commandReulst.MSA,
+ Pn = 0,
+ Fn = 1
+ };
+ commandReulst.ReplyBytes = GetCommandBytes(reqParam);
+ }
+ else if (commandReulst.Fn == 2)//退出登录
+ {
+ Console.WriteLine($"{commandReulst.A},退出登录:{DateTime.Now}");
+ }
+ else if (commandReulst.Fn == 3)//心跳
+ {
+ Console.WriteLine($"{commandReulst.A},心跳:{DateTime.Now}");
+ AnalysisHeartbeat(commandReulst);
+ }
+ }
+
+ public void AnalysisHeartbeat(CommandReulst commandReulst)
+ {
+ if (commandReulst.Seq.TpV == TpV.附加信息域中带时间标签)
+ {
+ //解析
+
+ }
+ if (commandReulst.Seq.CON == CON.需要对该帧进行确认)
+ {
+ var reqParam = new ReqParameter2()
+ {
+ AFN = AFN.确认或否认,
+ CMasterStationFunCode = CMasterStationFunCode.链路测试,
+ PRM = PRM.从动站报文,
+ A = commandReulst.A,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.不需要对该帧进行确认,
+ PRSEQ = commandReulst.Seq.PRSEQ,
+ },
+ MSA = commandReulst.MSA,
+ Pn = 0,
+ Fn = 1
+ };
+ commandReulst.ReplyBytes = GetCommandBytes(reqParam);
+ }
+ }
+
+ ///
+ /// 解析时间标签
+ ///
+ ///
+ private void AnalysisTp(List hexDatas)
+ {
+ var pFC = DataConvert.HexToDec(hexDatas[0]);//启动帧帧序号计数器
+ 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 = DataConvert.HexToDec(hexDatas[5]);//延迟时间 min
+ }
+
+ ///
+ /// 解析电表档案
+ ///
+ ///
+ ///
+ public List AnalysisAFN04F10DataUnit(List hexDatas)
+ {
+ var meterList = new List();
+ var count = DataConvert.HexToDec($"{hexDatas[1]}{hexDatas[0]}");
+ //if (2 + count * 27 != hexDatas.Count - pWLen - tPLen - 2)
+ // return;
+ var index = 2;//数量
+ for (int i = 1; i <= count; i++)
+ {
+ var meterNumber = DataConvert.HexToDec($"{hexDatas[index + 1]}{hexDatas[index]}");
+ index += 2;
+
+ var pn = DataConvert.HexToDec($"{hexDatas[index + 1]}{hexDatas[index]}");
+ index += 2;
+
+ var baudRateAndPortBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
+ var baudRate = DataConvert.BinToDec(baudRateAndPortBin.Substring(0, 3));
+ var port = DataConvert.BinToDec(baudRateAndPortBin.Substring(3, 5));
+ index += 1;
+
+ var protocolType = (CommunicationProtocolType)DataConvert.HexToDec(hexDatas[index]);
+ index += 1;
+
+ var addressHexList = hexDatas.Skip(index).Take(6).ToList();
+ addressHexList.Reverse();
+ var address = string.Join("", addressHexList);
+ index += 6;
+
+ var pwdHexList = hexDatas.Skip(index).Take(6).ToList();
+ pwdHexList.Reverse();
+ var password = string.Join("", pwdHexList.Take(3).ToList());
+ index += 6;
+
+ var rateNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
+ var rateNumber = DataConvert.BinToDec(rateNumberBin.Substring(4));
+ index += 1;
+
+ var intBitAndDecBitNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
+ var intBitNumber = DataConvert.BinToDec(intBitAndDecBitNumberBin.Substring(4, 2)) + 4;
+ var decBitNumber = DataConvert.BinToDec(intBitAndDecBitNumberBin.Substring(6, 2)) + 1;
+ index += 1;
+
+ // hexDatas.GetRange()
+ var collectorAddressHexList = hexDatas.Skip(index).Take(6).ToList();
+ collectorAddressHexList.Reverse();
+ var collectorAddress = string.Join("", collectorAddressHexList);
+ index += 6;
+
+ var userClassNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
+ var userClass = DataConvert.BinToDec(userClassNumberBin.Substring(0, 4));
+ var userSubClass = DataConvert.BinToDec(userClassNumberBin.Substring(4, 4));
+ index += 1;
+
+ meterList.Add(new MeterParameter()
+ {
+ Pn = pn,
+ BaudRate = baudRate,
+ Port = port,
+ ProtocolType = protocolType,
+ Address = address,
+ Password = password,
+ RateNumber = rateNumber,
+ IntegerBitNumber = intBitNumber,
+ DecimalBitNumber = decBitNumber,
+ CollectorAddress = collectorAddress,
+ UserCategoryNumber = userClass,
+ UserSubclassNumber = userSubClass,
+ });
+ }
+ return meterList;
+ }
+
+ ///
+ /// 解析实时数据F129
+ ///
+ ///
+ private void AnalysisAFN0CF129DataUnit(List hexDatas)
+ {
+ var minutes = Convert.ToInt32(hexDatas[0]); // 获取当前分钟数
+ var hours = Convert.ToInt32(hexDatas[1]); // 获取当前小时数
+ var day = Convert.ToInt32(hexDatas[2]); // 获取当前日期的日数
+ var month = Convert.ToInt32(hexDatas[3]); // 获取当前月份
+ var year = Convert.ToInt32(hexDatas[4]); // 获取当前日期的年份
+
+ var rateNumber = Convert.ToInt32(hexDatas[5]);
+ var kwhTotal = hexDatas.Skip(5).Take(5).ToList();
+ var kwhList = new List();
+ var index = 11;
+ for (int i = 0; i < rateNumber; i++)
+ {
+ var kwhHexList = hexDatas.Skip(11).Take(5).ToList();
+ kwhHexList.Reverse();
+ var integerStr = $"{kwhHexList.Take(0)}{kwhHexList.Take(1)}{kwhHexList.Take(2)}";
+ var decimalValStr = $"{kwhHexList[3]}{kwhHexList[4]}";
+ var val = decimal.Parse($"{integerStr}{decimalValStr}");
+ kwhList.Add(val);
+ index += 5;
+ }
+ }
+
+ #endregion
+
#region 下行命令
///
/// 设置电表档案
///
- ///
+ /// 集中器地址
///
- public void GetAFN04F10DataUnit(ReqParameter reqParameter, List meterParameters)
+ public void GetSetAmmeterParameter(string a, List meterParameters)
{
var dataUnit = GetAFN04F10DataUnit(meterParameters);
- var bytes = GetCommandBytes(reqParameter, dataUnit);
+ var bytes = GetCommandBytes(new ReqParameter2()
+ {
+ AFN = AFN.设置参数,
+ CMasterStationFunCode = CMasterStationFunCode.请求1级数据,
+ A = a,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.需要对该帧进行确认,
+ PRSEQ = 10,
+ },
+ MSA = GetMSA(a),
+ Pn = 0,
+ Fn = 10
+ }, dataUnit);
}
///
/// 查询电表档案
///
- ///
+ ///
/// 对象序号
- public void GetAFN10F10DataUnit(ReqParameter reqParameter, List meterNumberList)
+ public void GetAmmeterParameter(string a, List meterNumberList)
{
var dataUnit = new List();
var countHex = DataConvert.DecToHex(meterNumberList.Count()).PadLeft(4, '0');
@@ -83,10 +502,46 @@ namespace JiShe.CollectBus.Protocol
numberHexPairs.Reverse();
dataUnit.AddRange(numberHexPairs);
}
- var bytes = GetCommandBytes(reqParameter, dataUnit);
+ var bytes = GetCommandBytes(new ReqParameter2()
+ {
+ AFN = AFN.查询参数,
+ CMasterStationFunCode = CMasterStationFunCode.请求2级数据,
+ A = a,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.不需要对该帧进行确认,
+ PRSEQ = 0,
+ },
+ MSA = GetMSA(a),
+ Pn = 0,
+ Fn = 10
+ }, dataUnit);
}
-
+
+ public void GetAmmterReading(string a,int pn)
+ {
+ var bytes = GetCommandBytes(new ReqParameter2()
+ {
+ AFN = AFN.请求实时数据,
+ CMasterStationFunCode = CMasterStationFunCode.请求2级数据,
+ A = a,
+ Seq = new Seq()
+ {
+ TpV = TpV.附加信息域中无时间标签,
+ FIRFIN = FIRFIN.单帧,
+ CON = CON.不需要对该帧进行确认,
+ PRSEQ = 2,
+ },
+ MSA = GetMSA(a),
+ Pn = pn,
+ Fn = 129
+ });
+ }
+
+
///
/// 组装电表阀控
///
@@ -549,368 +1004,6 @@ namespace JiShe.CollectBus.Protocol
#endregion
- #region 上行命令
-
- //68
- //32 00
- //32 00
- //68
- //C9 1100'1001. 控制域C。
- // D7=1, (终端发送)上行方向。
- // D6=1, 此帧来自启动站。
- // D5=0, (上行方向)要求访问位。表示终端无事件数据等待访问。
- // D4=0, 保留
- // D3~D0=9, 功能码。链路测试
-
- //20 32 行政区划码
- //90 26 终端地址
- //00 主站地址和组地址标志。终端为单地址。 //3220 09 87 2
- // 终端启动的发送帧的 MSA 应为 0, 其主站响应帧的 MSA 也应为 0.
- //02 应用层功能码。AFN=2, 链路接口检测
- //70 0111'0000. 帧序列域。无时间标签、单帧、需要确认。
- //00 00 信息点。DA1和DA2全为“0”时,表示终端信息点。
- //01 00 信息类。F1, 登录。
- //44 帧尾,包含用户区数据校验和
- //16 帧结束标志
-
- ///
- /// 解析上行命令
- ///
- ///
- ///
- public CommandReulst? AnalysisCmd(string cmd)
- {
- CommandReulst? commandReulst = null;
- var hexStringList = DataConvert.StringToPairs(cmd);
- if (hexStringList.Count < hearderLen)
- {
- return commandReulst;
- }
- if (hexStringList[0] != stx || hexStringList[5] != stx)
- {
- return commandReulst;
- }
-
- var lenHexStr = $"{hexStringList[2]}{hexStringList[1]}";
- var lenBin = DataConvert.HexToBin(lenHexStr);
- var len = DataConvert.BinToDec(lenBin.Remove(lenBin.Length - 2));
- if (hexStringList.Count - 2 != hearderLen + len)
- return commandReulst;
-
- var userDataIndex = hearderLen;
- var c = hexStringList[userDataIndex];//控制域 1字节
- userDataIndex += 1;
-
- var aHexList = hexStringList.Skip(userDataIndex).Take(5).ToList();//地址域 5字节
- var a = AnalysisA(aHexList);
- var a3Bin = DataConvert.HexToBin(aHexList[4]).PadLeft(8, '0');
- var mSA = DataConvert.BinToDec(a3Bin.Substring(0, 7));
- userDataIndex += 5;
-
- var aFN = (AFN)DataConvert.HexToDec(hexStringList[userDataIndex]);//1字节
- userDataIndex += 1;
-
- var seq = DataConvert.HexToBin(hexStringList[userDataIndex]).PadLeft(8, '0');
- var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1));
- var fIRFIN = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2));
- var cON = (CON)Convert.ToInt32(seq.Substring(3, 1));
- var prseqBin = seq.Substring(4, 4);
- userDataIndex += 1;
-
- // (DA2 - 1) * 8 + DA1 = pn
- var da1Bin = DataConvert.HexToBin(hexStringList[userDataIndex]);
- var da1 = da1Bin == "0" ? 0 : da1Bin.Length;
- userDataIndex += 1;
- var da2 = DataConvert.HexToDec(hexStringList[userDataIndex]);
- userDataIndex += 1;
- var pn = da2 == 0 ? 0 : (da2 - 1) * 8 + da1;
-
- //(DT2*8)+DT1=fn
- var dt1Bin = DataConvert.HexToBin(hexStringList[userDataIndex]);
- var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0;
- userDataIndex += 1;
- var dt2 = DataConvert.HexToDec(hexStringList[userDataIndex]);
- userDataIndex += 1;
- var fn = dt2 > 0 ? dt2 * 8 + dt1 : 0;
-
- //数据单元
- var datas = hexStringList.Skip(userDataIndex).Take(len + hearderLen - userDataIndex).ToList();
-
- //EC
- //Tp
- commandReulst = new CommandReulst()
- {
- A = a,
- MSA = mSA,
- AFN = aFN,
- Seq = new Seq()
- {
- TpV = tpV,
- FIRFIN = fIRFIN,
- CON = cON,
- PRSEQ = DataConvert.BinToDec(prseqBin),
- },
- CmdLength = len,
- Pn = pn,
- Fn = fn,
- HexDatas = datas
- };
-
- return commandReulst;
- }
-
- ///
- /// 解析地址
- ///
- ///
- ///
- private string AnalysisA(List aHexList)
- {
- var a1 = aHexList[1] + aHexList[0];
- var a2 = aHexList[3] + aHexList[2];
- var a2Dec = DataConvert.HexToDec(a2);
- var a3 = aHexList[4];
- var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}";
- return a;
- }
-
- ///
- /// 解析上行命令数据包
- ///
- ///
- public void AnalysisData(CommandReulst commandReulst)
- {
- switch (commandReulst.AFN)
- {
- case AFN.确认或否认:
- //commandReulst.fn
- //1:全部确认
- //2:全部否认
- //3:按数据单元表示确认和否认
- //4 硬件安全认证错误应答
- break;
- case AFN.复位:
- break;
- case AFN.链路接口检测:
- AnalysisAFN02(commandReulst);
- break;
- case AFN.中继站命令:
- break;
- case AFN.设置参数:
- break;
- case AFN.控制命令:
- break;
- case AFN.身份认证及密钥协商:
- break;
- case AFN.备用:
- break;
- case AFN.请求被级联终端主动上报:
- break;
- case AFN.请求终端配置:
- break;
- case AFN.查询参数:
- break;
- case AFN.请求任务数据:
- break;
- case AFN.请求实时数据:
- break;
- case AFN.请求历史数据:
- break;
- case AFN.请求事件数据:
- break;
- case AFN.文件传输:
- break;
- case AFN.数据转发:
- break;
- default:
- break;
- }
- }
-
- public void AnalysisAFN02(CommandReulst commandReulst)
- {
- if (commandReulst.Fn == 1) //登录
- {
- Console.WriteLine($"{commandReulst.A},登录:{DateTime.Now}");
- var reqParam = new ReqParameter2()
- {
- AFN = AFN.确认或否认,
- CMasterStationFunCode = CMasterStationFunCode.链路测试,
- PRM = PRM.从动站报文,
- A = commandReulst.A,
- Seq = new Seq()
- {
- TpV = TpV.附加信息域中无时间标签,
- FIRFIN = FIRFIN.单帧,
- CON = CON.不需要对该帧进行确认,
- PRSEQ = commandReulst.Seq.PRSEQ,
- },
- MSA = commandReulst.MSA,
- Pn = 0,
- Fn = 1
- };
- commandReulst.ReplyBytes = GetCommandBytes(reqParam);
- }
- else if (commandReulst.Fn == 2)//退出登录
- {
- Console.WriteLine($"{commandReulst.A},退出登录:{DateTime.Now}");
- }
- else if (commandReulst.Fn == 3)//心跳
- {
- Console.WriteLine($"{commandReulst.A},心跳:{DateTime.Now}");
- AnalysisHeartbeat(commandReulst);
- }
- }
-
- public void AnalysisHeartbeat(CommandReulst commandReulst)
- {
- if (commandReulst.Seq.TpV == TpV.附加信息域中带时间标签)
- {
- //解析
-
- }
- if (commandReulst.Seq.CON == CON.需要对该帧进行确认)
- {
- var reqParam = new ReqParameter2()
- {
- AFN = AFN.确认或否认,
- CMasterStationFunCode = CMasterStationFunCode.链路测试,
- PRM = PRM.从动站报文,
- A = commandReulst.A,
- Seq = new Seq()
- {
- TpV = TpV.附加信息域中无时间标签,
- FIRFIN = FIRFIN.单帧,
- CON = CON.不需要对该帧进行确认,
- PRSEQ = commandReulst.Seq.PRSEQ,
- },
- MSA = commandReulst.MSA,
- Pn = 0,
- Fn = 1
- };
- //commandReulst.ReplyBytes = GetCommandBytes(reqParam);
- }
- }
-
- ///
- /// 解析时间标签
- ///
- ///
- private void AnalysisTp(List hexDatas)
- {
- var pFC = DataConvert.HexToDec(hexDatas[0]);//启动帧帧序号计数器
- 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 = DataConvert.HexToDec(hexDatas[5]);//延迟时间 min
- }
-
- ///
- /// 解析电表档案
- ///
- ///
- ///
- public List AnalysisAFN04F10DataUnit(List hexDatas)
- {
- var meterList = new List();
- var count = DataConvert.HexToDec($"{hexDatas[1]}{hexDatas[0]}");
- //if (2 + count * 27 != hexDatas.Count - pWLen - tPLen - 2)
- // return;
- var index = 2;//数量
- for (int i = 1; i <= count; i++)
- {
- var meterNumber = DataConvert.HexToDec($"{hexDatas[index + 1]}{hexDatas[index]}");
- index += 2;
-
- var pn = DataConvert.HexToDec($"{hexDatas[index + 1]}{hexDatas[index]}");
- index += 2;
-
- var baudRateAndPortBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
- var baudRate = DataConvert.BinToDec(baudRateAndPortBin.Substring(0, 3));
- var port = DataConvert.BinToDec(baudRateAndPortBin.Substring(3, 5));
- index += 1;
-
- var protocolType = (ProtocolType)DataConvert.HexToDec(hexDatas[index]);
- index += 1;
-
- var addressHexList = hexDatas.Skip(index).Take(6).ToList();
- addressHexList.Reverse();
- var address = string.Join("", addressHexList);
- index += 6;
-
- var pwdHexList = hexDatas.Skip(index).Take(6).ToList();
- pwdHexList.Reverse();
- var password = string.Join("", pwdHexList.Take(3).ToList());
- index += 6;
-
- var rateNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
- var rateNumber = DataConvert.BinToDec(rateNumberBin.Substring(4));
- index += 1;
-
- var intBitAndDecBitNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
- var intBitNumber = DataConvert.BinToDec(intBitAndDecBitNumberBin.Substring(4, 2)) + 4;
- var decBitNumber = DataConvert.BinToDec(intBitAndDecBitNumberBin.Substring(6, 2)) + 1;
- index += 1;
-
- // hexDatas.GetRange()
- var collectorAddressHexList = hexDatas.Skip(index).Take(6).ToList();
- collectorAddressHexList.Reverse();
- var collectorAddress = string.Join("", collectorAddressHexList);
- index += 6;
-
- var userClassNumberBin = DataConvert.HexToBin(hexDatas[index]).PadLeft(8, '0');
- var userClass = DataConvert.BinToDec(userClassNumberBin.Substring(0, 4));
- var userSubClass = DataConvert.BinToDec(userClassNumberBin.Substring(4, 4));
- index += 1;
-
- meterList.Add(new MeterParameter()
- {
- Pn = pn,
- BaudRate = baudRate,
- Port = port,
- ProtocolType = protocolType,
- Address = address,
- Password = password,
- RateNumber = rateNumber,
- IntegerBitNumber = intBitNumber,
- DecimalBitNumber = decBitNumber,
- CollectorAddress = collectorAddress,
- UserCategoryNumber = userClass,
- UserSubclassNumber = userSubClass,
- });
- }
- return meterList;
- }
-
- ///
- /// 解析实时数据F129
- ///
- ///
- private void AnalysisAFN0CF129DataUnit(List hexDatas)
- {
- var minutes = Convert.ToInt32(hexDatas[0]); // 获取当前分钟数
- var hours = Convert.ToInt32(hexDatas[1]); // 获取当前小时数
- var day = Convert.ToInt32(hexDatas[2]); // 获取当前日期的日数
- var month = Convert.ToInt32(hexDatas[3]); // 获取当前月份
- var year = Convert.ToInt32(hexDatas[4]); // 获取当前日期的年份
-
- var rateNumber = Convert.ToInt32(hexDatas[5]);
- var kwhTotal = hexDatas.Skip(5).Take(5).ToList();
- var kwhList = new List();
- var index = 11;
- for (int i = 0; i < rateNumber; i++)
- {
- var kwhHexList = hexDatas.Skip(11).Take(5).ToList();
- kwhHexList.Reverse();
- var integerStr = $"{kwhHexList.Take(0)}{kwhHexList.Take(1)}{kwhHexList.Take(2)}";
- var decimalValStr = $"{kwhHexList[3]}{kwhHexList[4]}";
- var val = decimal.Parse($"{integerStr}{decimalValStr}");
- kwhList.Add(val);
- index += 5;
- }
- }
-
- #endregion
+
}
}