using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static System.Net.WebRequestMethods;
using System.Runtime.InteropServices;
namespace UdpServerCMD
{
internal class Program
{
///
/// 基数【前置位设备数据总数和】
///
//public static int baseNum = 0;
public static int length = 0;//接收数据长度
///
/// 在线用户列表
///
public static List idOnLine = new List();
///
/// 存储IP及Socket--便于服务器与指定客户端通信
///
public static Dictionary OnLineDic = new Dictionary();
public static Socket udpServer;//udp服务器
public static bool memberReply;//是否回复消息
//public static TypeFunctionCode LastType = TypeFunctionCode.默认;
public static int COMPort = 7000;//端口号
public static string IP1 = "172.16.1.49";//连接IP
public static EndPoint serverEnd; //服务端
public static IPEndPoint ipEnd; //发送消息服务端
public static Socket socket; //目标socket
public static Thread connectThread; //连接线程
public static byte[] sendData;//发送的数据
static log4net.ILog log;
static void Main(string[] args)
{
//初始化日志
log4net.Config.XmlConfigurator.Configure();
log = log4net.LogManager.GetLogger("loginfo");
//InitSocket();
init();
Console.ReadKey();
}
///
/// 发送接口初始化
///
public static void InitSocket(EndPoint endP)
{
try
{
//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网
//ipEnd = new IPEndPoint(IPAddress.Parse(IP1), COMPort);
ipEnd = (IPEndPoint)(endP);
//定义套接字类型,在主线程中定义
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//定义服务端
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
serverEnd = (EndPoint)sender;
//print("waiting for sending UDP dgram");
//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息
//SocketSend("connection-successful signal");
}
catch (Exception e)
{
Console.WriteLine("发送初始化:" + e.Message);
}
}
///
/// 发送数据
///
///
public static void SocketSend(string sendStr)
{
//清空发送缓存
sendData = new byte[1024 * 1024 * 2];
//数据类型转换
//sendData = Encoding.Default.GetBytes(sendStr);
StringBuilder stringBuilder = new StringBuilder("");
for (int i = 0; i < sendStr.Length; i++)
{
if (i != 0 && i % 2 != 0) stringBuilder.Append(sendStr[i] + " ");
else stringBuilder.Append(sendStr[i]);
}
log.Info("发送至 " + ipEnd.ToString() + ": " + stringBuilder);
sendData = hexStringToByteArray(sendStr);
//发送给指定服务端
socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
//socket.SendTo(sendData, sendData.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse(ipEnd.Address.ToString()), 0));
}
///
/// 连接关闭
///
public static void SocketQuit()
{
//关闭线程
if (connectThread != null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭socket
if (socket != null)
socket.Close();
}
///
/// 接收接口初始化
///
public static void init()
{
try
{
//var IP = "111.229.30.246";
var IP = "172.17.0.9";
//string IP = "172.16.1.49";
int Port = 12301;
//建立udp服务器,参数2:udp协议以数据报的方式传输,参数3:UDP协议
udpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//为服务器绑定IP
IPAddress ip = IPAddress.Parse(IP);
EndPoint ep = new IPEndPoint(ip, Port);
udpServer.Bind(ep);
//接收数据
EndPoint endP = new IPEndPoint(IPAddress.Any, 0);
string message;
byte[] data = new byte[1024 * 1024 * 2];
length = 0;
//把数据的来源放到第二个参数上
while (true)
{
length = udpServer.ReceiveFrom(data, ref endP);
//message = Encoding.Default.GetString(data, 0, length);
message = byteArrayToHexString(data, length);
log.Info("接收到 " + endP.ToString() + ": " + message);
message = message.Replace(" ", "");
InitSocket(endP);
Console.WriteLine("地址:" + endP.ToString() + "\n");
int baseNum = 0;//基数【前置位设备数据总数和】
var LoginFrame = message[20].ToString() + message[21].ToString();//功能码C
JudgmentFunctionCode(LoginFrame, message, baseNum);
}
}
catch (Exception e)
{
Console.WriteLine("接收初始化:" + e.Message);
}
}
///
/// byte[]直接转Float**
///
///
///
public static float byteToFloat(string message)
{
byte[] bFxianOrg = new byte[4];
var a = stringToByteArray(message, Encoding.Default);
StringBuilder zz = new StringBuilder("");
StringBuilder _zz = new StringBuilder("");
string[] s = new string[4];
int x = 0;
for (int i = 0; i < a.Length; i++)
{
if (x != 0 && i % 2 == 0)
{
zz.Append(int.Parse(hexStr2Str(_zz.ToString())).ToString()).Append("-");
_zz.Clear();
x = 0;
}
_zz.Append(((char)a[i]).ToString());
if (i == a.Length - 1)
{
zz.Append(int.Parse(hexStr2Str(_zz.ToString())).ToString()).Append("-");
_zz.Clear();
}
x++;
}
s = zz.ToString().Split('-');
byte a0 = byte.Parse(s[0].ToString());
byte a1 = byte.Parse(s[1].ToString());
byte a2 = byte.Parse(s[2].ToString());
byte a3 = byte.Parse(s[3].ToString());
bFxianOrg = new byte[4] { a0, a1, a2, a3 };
var b = BitConverter.ToSingle(bFxianOrg, 0);
return b;
}
///
/// 16进制转字符串(十进制)**
///
///
///
public static string hexStr2Str(String hexStr)
{
String str = "0123456789ABCDEF";
char[] hexs = hexStr.ToCharArray();
byte[] bytes = new byte[hexStr.Length / 2];
int n;
for (int i = 0; i < bytes.Length; i++)
{
n = str.IndexOf(hexs[2 * i]) * 16;
n += str.IndexOf(hexs[2 * i + 1]);
bytes[i] = (byte)(n & 0xff);
}
StringBuilder stringBuilder = new StringBuilder("");
for (int i = 0; i < bytes.Length; i++)
{
stringBuilder.Append(bytes[i]);
}
return (stringBuilder.ToString());
}
///
/// 16进制转ASCII码**
///
/// 16进制字符
///
public static StringBuilder hexToASCII(string hexStr)
{
String str = "0123456789ABCDEF";
char[] hexs = hexStr.ToCharArray();
byte[] bytes = new byte[hexStr.Length / 2];
int n;
for (int i = 0; i < bytes.Length; i++)
{
n = str.IndexOf(hexs[2 * i]) * 16;
n += str.IndexOf(hexs[2 * i + 1]);
bytes[i] = (byte)(n & 0xff);
}
StringBuilder VersionNumber = new StringBuilder("");
for (int i = 0; i < bytes.Length; i++)
{
VersionNumber.Append((char)bytes[i]);
}
return VersionNumber;
}
///
/// 获取高四位**
///
///
///
public static int getHeight4(byte data)
{
int height;
height = ((data & 0xf0) >> 4);
return height;
}
///
/// 获取低四位**
///
///
///
public static int getLow4(byte data)
{
int low;
low = (data & 0x0f);
return low;
}
///
/// //16进制转2进制
///
///
///
public static string HexString2BinString(string hexString)
{
try
{
string result = string.Empty;
foreach (char c in hexString)
{
int v = Convert.ToInt32(c.ToString(), 16);
int v2 = int.Parse(Convert.ToString(v, 2));
// 去掉格式串中的空格,即可去掉每个4位二进制数之间的空格,
result += string.Format("{0:d4} ", v2);
}
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
///
/// 二进制算术累加**【计算校验位/码CS】
///
/// 起始
/// 终止
/// “控制位”“数据位”所有数据
///
public static string binAccumulation(int j, int k, string message)
{
StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值
long _parityBitCS = 0;
int x = 0;
for (int i = j; i <= k; i++)
{
if (x % 2 == 0 && x != 0)
{
var a = hexStr2Str(parityBitCS.ToString());
_parityBitCS += int.Parse(a);
parityBitCS.Clear();
x = 0;
}
parityBitCS.Append(message[i]);
if (i == k)
{
var a = hexStr2Str(parityBitCS.ToString());
_parityBitCS += int.Parse(a);
}
x++;
}
_parityBitCS = _parityBitCS & Convert.ToInt64("FF", 16);
return _parityBitCS.ToString("X2");
}
///
/// 每8bit高低位互换
///
/// 起始
/// 终止
/// 需要转换的16进制数据
/// 新的16进制数据
public static string interconvert(int j, int k, string message, bool exchange = true)
{
StringBuilder parityBitCS = new StringBuilder("");//互换后的值
//StringBuilder _parityBitH = new StringBuilder("");//高字节
//StringBuilder _parityBitL = new StringBuilder("");//低字节
//StringBuilder _parityBit = new StringBuilder("");//记录当前字节
//int x = 0;
//for (int i = j; i <= k; i++)//??
//{
// if (x == 4)
// {
// _parityBitL.Append(_parityBit);//记录低字节
// parityBitCS.Append(_parityBitL).Append(_parityBitH);//低字节--高字节
// _parityBitL.Clear();//清空低字节
// _parityBitH.Clear();//清空高字节
// _parityBit.Clear();
// x = 0;
// }
// else if (x == 2)//记录高字节
// {
// _parityBitH.Append(_parityBit);
// _parityBit.Clear();
// }
// _parityBit.Append(message[i]);
// if (i == k)
// {
// _parityBitL.Append(_parityBit);//记录低字节
// parityBitCS.Append(_parityBitL).Append(_parityBitH);//低字节--高字节
// }
// x++;
//}
string[] strings = new string[4] { message[0].ToString() + message[1].ToString(), message[2].ToString() + message[3].ToString(), message[4].ToString() + message[5].ToString(), message[6].ToString() + message[7].ToString() };
for (int i = strings.Length - 1; i >= 0; i--)
{
parityBitCS.Append(strings[i].ToString());
}
return Convert.ToInt32(parityBitCS.ToString(), 16).ToString();
}
#region 暂存
///
/// byte数组转string
///
///
///
public static string byteArrayToString(byte[] data, Encoding encoding)
{
return encoding.GetString(data);
}
///
/// string转 byte数组
///
///
///
public static byte[] stringToByteArray(string data, Encoding encoding)
{
return encoding.GetBytes(data);
}
///
/// byte数组转16进制字符串
///
///
///
public static string byteArrayToHexString(byte[] data, int length = 0)
{
int dataLength = 0;
if (length != 0) dataLength = length;
else dataLength = data.Length;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < dataLength; i++)
{
builder.Append(string.Format("{0:X2} ", data[i]));
}
return builder.ToString().Trim();
}
///
/// 16进制字符串转byte数组
///
///
///
public static byte[] hexStringToByteArray(string data)
{
//string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
List chars = new List();
for (int i = 0; i < data.Length; i++)
{
chars.Add(data[i].ToString());
}
//byte[] _returnBytes = new byte[chars.Count];
byte[] returnBytes = new byte[chars.Count / 2];
//逐个字符变为16进制字节数据
for (int i = 0; i < chars.Count; i++)
{
try
{
if (i % 2 == 0)
{
returnBytes[i / 2] = (byte)(Convert.ToByte(chars[i].ToString() + chars[i + 1].ToString(), 16));
}
}
catch (Exception e)
{
//var a = hexStr2Str(chars[i]);
//short b = short.Parse(a);
//byte c = (byte)(b % 256);
//returnBytes[i] = c;
Console.WriteLine(e.Message);
}
}
return returnBytes;
}
///
/// byte数组转10进制字符串
///
///
///
public static string byteArrayToDecString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i] + " ");
}
return builder.ToString().Trim();
}
///
/// 10进制字符串转byte数组
///
///
///
public static byte[] decStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为10进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 10);
}
return returnBytes;
}
///
/// byte数组转八进制字符串
///
///
///
public static string byteArrayToOtcString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(Convert.ToString(data[i], 8) + " ");
}
return builder.ToString().Trim();
}
///
/// 八进制字符串转byte数组
///
///
///
public static byte[] otcStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为8进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 8);
}
return returnBytes;
}
///
/// 二进制字符串转byte数组
///
///
///
public static byte[] binStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为2进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 2);
}
return returnBytes;
}
///
/// byte数组转二进制字符串
///
///
///
public static string byteArrayToBinString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(Convert.ToString(data[i], 2) + " ");
}
return builder.ToString().Trim();
}
#endregion
#region 正向解析
///
/// 登录帧解析
///
///
public static void LoginFrameAnalysis(string message, IPEndPoint ipEnd, Socket socket)
{
#region 登录帧解析
StringBuilder DataLength = new StringBuilder("");//数据部长度L
for (int i = 4; i <= 7; i++)
{
DataLength.Append(message[i]);
}
int.Parse(hexStr2Str(DataLength.ToString()));
//Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString())));
StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F
if (message[19].ToString() == "F")
{
for (int i = 8; i < 19; i++)
{
SimID.Append(message[i]);
}
}
else
{
for (int i = 8; i <= 19; i++)
{
SimID.Append(message[i]);
}
}
//Console.WriteLine("客户端地址:" + SimID);
StringBuilder _voltage = new StringBuilder("");//电压 --缩小10 倍为实际数值
float voltage;//电压
for (int i = 22; i <= 23; i++)
{
_voltage.Append(message[i]);
}
voltage = float.Parse(_voltage.ToString()) / 10;
//Console.WriteLine("电压:" + voltage);
StringBuilder _signal = new StringBuilder("");//信号 --信号为整数
int signal;
for (int i = 24; i <= 25; i++)
{
_signal.Append(message[i]);
}
signal = int.Parse(_signal.ToString());
//Console.WriteLine("信号:" + signal);
StringBuilder date = new StringBuilder("20");//日期 --(BCD 码)
for (int i = 26; i <= 37; i++)
{
if (i == 27 || i == 29) date.Append(message[i] + "-");
else if (i == 31) date.Append(message[i] + " ");
else if (i == 33 || i == 35) date.Append(message[i] + ":");
else date.Append(message[i]);
}
//Console.WriteLine("日期:" + date);
StringBuilder workPattern = new StringBuilder("");//工作模式 --0x00 定时开机,0x01 实时在线
for (int i = 38; i <= 39; i++)
{
workPattern.Append(message[i]);
}
//switch ((TypeworkPattern)int.Parse(workPattern.ToString()))
//{
// case TypeworkPattern.定时开机:
// Console.WriteLine(TypeworkPattern.定时开机);
// break;
// case TypeworkPattern.实时在线:
// Console.WriteLine(TypeworkPattern.实时在线);
// break;
// default:
// break;
//}
StringBuilder _meterNumber = new StringBuilder("");//仪表数量
StringBuilder meterNumber = new StringBuilder("");//仪表数量
for (int i = 40; i <= 41; i++)
{
_meterNumber.Append(message[i]);
}
meterNumber.Append(int.Parse(_meterNumber.ToString()).ToString() + "台");
//Console.WriteLine("仪表数量:" + meterNumber);
StringBuilder positionNumber = new StringBuilder("");//位置号 --取低 4 位为实际值
for (int i = 42; i <= 43; i++)
{
//if (i == 42) continue;//取低 4 位为实际值
positionNumber.Append(message[i]);
}
//Console.WriteLine("位置号:" + getLow4(byte.Parse(hexStr2Str(positionNumber.ToString()))) + "号");
StringBuilder phenotype = new StringBuilder("");//表型
for (int i = 44; i <= 45; i++)
{
phenotype.Append(message[i]);
}
//typePheno(phenotype);
StringBuilder versionMumber = new StringBuilder("");//版本号 --开始字节4A
for (int i = 46; i <= 87; i++)
{
if (i == 46 || i == 47) continue;
versionMumber.Append(message[i]);
}
versionMumber = hexToASCII(versionMumber.ToString());
//Console.WriteLine("版本号" + versionMumber);
StringBuilder reportingCycle = new StringBuilder("");//上报周期 --开始字节4B。115 :15分钟 ,130:30 分钟,24:24小时
for (int i = 88; i <= 91; i++)
{
if (i == 88 || i == 89) continue;
reportingCycle.Append(message[i]);
}
//if (int.Parse(hexStr2Str(reportingCycle.ToString())) != 24)
//{
// var v = new StringBuilder(hexStr2Str(reportingCycle.ToString()));
// v.Remove(0, 2);
// Console.WriteLine("上报周期: " + v + "h");
//}
//else if (int.Parse(hexStr2Str(reportingCycle.ToString())) == 24)
//{
// Console.WriteLine("上报周期: " + int.Parse(hexStr2Str(reportingCycle.ToString())) + "h");
//}
StringBuilder acquisitionCycle = new StringBuilder("");//采集周期 --开始字节4C。高字节在前,单位:秒
for (int i = 92; i <= 97; i++)
{
if (i == 92 || i == 93) continue;
acquisitionCycle.Append(message[i]);
}
Convert.ToInt64(acquisitionCycle.ToString(), 16);
//Console.WriteLine("采集周期:" + Convert.ToInt64(acquisitionCycle.ToString(), 16) / 60 + "分钟");
StringBuilder factoryCode = new StringBuilder("");//出厂编码 --开始字节4D。ASCII码
for (int i = 98; i <= 127; i++)
{
if (i == 98 || i == 99) continue;
factoryCode.Append(message[i]);
}
hexToASCII(factoryCode.ToString());
//Console.WriteLine("出厂编码:" + hexToASCII(factoryCode.ToString()));
StringBuilder retain = new StringBuilder("");//保留 --开始字节4F。不做处理
for (int i = 128; i <= 145; i++)
{
if (i == 128 || i == 129) continue;
retain.Append(message[i]);
}
//CRC校验
StringBuilder builder = new StringBuilder("");
for (int i = message.Length - 6; i < message.Length - 4; i++)
{
builder.Append(message[i]);
}
if (binAccumulation(4, 145, message).ToUpper() != builder.ToString().ToUpper())
{
Console.WriteLine("接收数据校验失败" + ": " + message);
log.Info("登录帧校验失败" + ": " + message);
return;
}
Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString())));
Console.WriteLine("客户端地址:" + SimID);
Console.WriteLine("电压:" + voltage);
Console.WriteLine("信号:" + signal);
Console.WriteLine("日期:" + date);
switch ((TypeworkPattern)int.Parse(workPattern.ToString()))
{
case TypeworkPattern.定时开机:
Console.WriteLine(TypeworkPattern.定时开机);
break;
case TypeworkPattern.实时在线:
Console.WriteLine(TypeworkPattern.实时在线);
break;
default:
break;
}
Console.WriteLine("仪表数量:" + meterNumber);
Console.WriteLine("位置号:" + getLow4(byte.Parse(hexStr2Str(positionNumber.ToString()))) + "号");
typePheno(phenotype);
Console.WriteLine("版本号" + versionMumber);
if (int.Parse(hexStr2Str(reportingCycle.ToString())) != 24)
{
var v = new StringBuilder(hexStr2Str(reportingCycle.ToString()));
v.Remove(0, 2);
Console.WriteLine("上报周期: " + v + "h");
}
else if (int.Parse(hexStr2Str(reportingCycle.ToString())) == 24)
{
Console.WriteLine("上报周期: " + int.Parse(hexStr2Str(reportingCycle.ToString())) + "h");
}
Console.WriteLine("采集周期:" + Convert.ToInt64(acquisitionCycle.ToString(), 16) / 60 + "分钟");
Console.WriteLine("出厂编码:" + hexToASCII(factoryCode.ToString()));
Console.WriteLine("校验位CS:" + binAccumulation(4, 145, message));
#endregion
longinDecompilation(SimID, ipEnd, socket);
}
///
/// 数据帧1解析
///
///
/// 基数【前置位设备数据总数和】
public static void dataFramesAnalysis(string message, string code, int baseNum)
{
basicsAnalysis(message);
Isgo(message, baseNum);
sendClock(message);
}
///
/// 时钟解析
///
///
public static void clockAnalysis(string message, IPEndPoint ipEnd)
{
StringBuilder DataLength = new StringBuilder("");//数据部长度L
for (int i = 4; i <= 7; i++)
{
DataLength.Append(message[i]);
}
int.Parse(hexStr2Str(DataLength.ToString()));
Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString())));
StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F
if (message[19].ToString() == "F")
{
for (int i = 8; i < 19; i++)
{
SimID.Append(message[i]);
}
}
else
{
for (int i = 8; i <= 19; i++)
{
SimID.Append(message[i]);
}
}
Console.WriteLine("客户端地址:" + SimID);
StringBuilder _clock = new StringBuilder("");
StringBuilder clock = new StringBuilder("");//时钟 --年只取后两位
for (int i = 22; i <= 33; i++)
{
_clock.Append(message[i]);
}
for (int i = 0; i < 6; i++)
{
if (i == 0)
{
clock.Append(hexStr2Str(_clock.ToString()[0].ToString() + _clock.ToString()[1].ToString()));
clock.Append("-");
}
else
{
clock.Append(hexStr2Str(_clock.ToString()[i * 2].ToString() + _clock.ToString()[i * 2 + 1].ToString()));
if (i == 1) clock.Append("-");
else if (i == 2) clock.Append(" ");
else if (i == 3) clock.Append(":");
else if (i == 4) clock.Append(":");
}
}
Console.WriteLine("时钟:20" + clock);
StringBuilder sig = new StringBuilder("");//有无后续帧标识 --0 无后续帧 1 有后续帧
for (int i = 34; i <= 35; i++)
{
sig.Append(message[i]);
}
if (sig.ToString() == "00") Console.WriteLine("无后续帧");
else Console.WriteLine("有后续帧");
StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值
parityBitCS.Append(binAccumulation(4, 35, message.ToString()));
Console.WriteLine("校验位CS:" + parityBitCS);
}
#endregion
#region 反编译
///
/// 登录帧反编译
///
/// 客户端地址A
public static void longinDecompilation(StringBuilder SimID, IPEndPoint ipEnd, Socket socket)
{
if (SimID.Length == 11) SimID.Append("F");
StringBuilder parityBitCS = new StringBuilder("");
StringBuilder message = new StringBuilder("403A" + "0009" + SimID + "01" + "00");
parityBitCS.Append(binAccumulation(4, 23, message.ToString()));
var a = message.Append(parityBitCS).ToString() + "0D0A";
SocketSend(a);
}
///
/// 数据帧反编译
///
/// sim码
/// 功能码
/// 版本号
public static void dataFramesDecompilation(StringBuilder SimID, string code, IPEndPoint ipEnd, Socket socket, string versionNum = "01")
{
if (SimID.Length == 11) SimID.Append("F");
StringBuilder parityBitCS = new StringBuilder("");
StringBuilder message = new StringBuilder("403A" + "000B" + SimID + code + versionNum + "0100");
parityBitCS.Append(binAccumulation(4, 27, message.ToString()));
SocketSend(message.Append(parityBitCS) + "0D0A");
}
///
/// 发送时钟校验
///
///
public static void sendClock(string message)
{
StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F
for (int i = 8; i <= 19; i++)
{
SimID.Append(message[i]);
}
StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值
StringBuilder Clock = new StringBuilder("");//时钟 --年只取后两位
Clock.Append(getClock());
StringBuilder sig = new StringBuilder("00");//有无后续帧标识 --0 无后续帧 1 有后续帧
StringBuilder msg = new StringBuilder("403A" + "000F" + SimID + "05" + Clock + sig);
parityBitCS.Append(binAccumulation(4, 35, msg.ToString()));
SocketSend(msg.Append(parityBitCS).ToString() + "0D0A");
}
///
/// 获取当前时钟的16进制【年只取后两位】
///
///
public static string getClock()
{
StringBuilder builder = new StringBuilder("");
string str = DateTime.Now.ToString();
string[] strings = str.Split(':', '/', ' ');
for (int i = 0; i < strings.Length; i++)
{
if (strings[i].Length == 1) strings[i] = 0 + strings[i].ToString();
}
for (int i = 0; i < strings.Length; i++)
{
if (i == 0) builder.Append(int.Parse(strings[i][2].ToString() + strings[i][3].ToString()).ToString("X2").ToString());
else builder.Append(int.Parse(strings[i]).ToString("X2").ToString());
}
return builder.ToString();
}
#endregion
///
/// 基础解析【长度--采集时间】
///
///
public static void basicsAnalysis(string message)
{
#region 长度--采集时间
StringBuilder DataLength = new StringBuilder("");//数据部长度L
for (int i = 4; i <= 7; i++)
{
DataLength.Append(message[i]);
}
int.Parse(hexStr2Str(DataLength.ToString()));
Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString())));
StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F
if (message[19].ToString() == "F")
{
for (int i = 8; i < 19; i++)
{
SimID.Append(message[i]);
}
}
else
{
for (int i = 8; i <= 19; i++)
{
SimID.Append(message[i]);
}
}
Console.WriteLine("客户端地址:" + SimID);
StringBuilder totalFrames = new StringBuilder("");//总帧数
for (int i = 22; i <= 23; i++)
{
totalFrames.Append(message[i]);
}
Console.WriteLine("总帧数:" + int.Parse(totalFrames.ToString()));
StringBuilder whichFrame = new StringBuilder("");//第几帧
for (int i = 24; i <= 25; i++)
{
whichFrame.Append(message[i]);
}
Console.WriteLine("第几帧:" + int.Parse(whichFrame.ToString()));
StringBuilder currentFrame = new StringBuilder(""); //此帧表数
for (int i = 26; i <= 27; i++)
{
currentFrame.Append(message[i]);
}
Console.WriteLine("此帧表数:" + int.Parse(currentFrame.ToString()));
#region 暂存
//StringBuilder platForm = new StringBuilder("");//站号 --十进制减去64 为实际数值
//for (int i = 28; i <= 29; i++)
//{
// platForm.Append(message[i]);
//}
//var _platForm = int.Parse(hexStr2Str(platForm.ToString())) - 64;
//Console.WriteLine("站号:" + _platForm);
//StringBuilder phenotype = new StringBuilder("");//表型
//for (int i = 30; i <= 31; i++)
//{
// phenotype.Append(message[i]);
//}
//StringBuilder _phenotype = new StringBuilder("");//--表型数字 81 83 84
////_phenotype.Clear().Append(typePheno(phenotype));
//StringBuilder alarmCode = new StringBuilder("");//报警码
//for (int i = 32; i <= 33; i++)
//{
// alarmCode.Append(message[i]);
//}
//typeAlarmcode(alarmCode);
//StringBuilder date = new StringBuilder("20");//采集时间 --(BCD 码)
//for (int i = 34; i <= 43; i++)
//{
// if (i == 35 || i == 37) date.Append(message[i] + "-");
// else if (i == 39) date.Append(message[i] + " ");
// else if (i == 41) date.Append(message[i] + ":");
// else date.Append(message[i]);
//}
//Console.WriteLine("采集时间:" + date);
#endregion
#endregion
}
///
/// 判断后面是否存在仪表数据【有继续】
///
///
/// 表型起始位下标 22 + 6 + baseNum + 2
/// 表型终止位下标 22 + 6 + baseNum + 3
/// 基数【前置位设备数据总数和】
public static void Isgo(string message, int baseNum)
{
try
{
if (message.Length >= 31 + baseNum)
{
StringBuilder go = new StringBuilder(message[30 + baseNum].ToString() + message[31 + baseNum].ToString());//表型
var code = message[20].ToString() + message[21].ToString();//功能码C
StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F
if (message[19].ToString() == "F")
{
for (int i = 8; i < 19; i++)
{
SimID.Append(message[i]);
}
}
else
{
for (int i = 8; i <= 19; i++)
{
SimID.Append(message[i]);
}
}
if (go.ToString() == "84")
{
Console.WriteLine();
phenotype84(message, baseNum);
dataFramesDecompilation(SimID, code, ipEnd, socket);
}
else if ((go.ToString() == "83"))
{
Console.WriteLine();
phenotype83(message, baseNum);
dataFramesDecompilation(SimID, code, ipEnd, socket);
}
else if ((go.ToString() == "81"))
{
Console.WriteLine();
phenotype81(message, baseNum);
dataFramesDecompilation(SimID, code, ipEnd, socket);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
///
/// 0x81、0x83、0x84共用解析【站号、表型 、报警码、采集时间】
///
///
/// 基数(前所有位合计)
public static void shareAnalysis(string message, int multiplier)
{
StringBuilder platForm = new StringBuilder("");//站号 --十进制减去64 为实际数值
for (int i = 28 + multiplier; i <= 29 + multiplier; i++)
{
platForm.Append(message[i]);
}
var _platForm = int.Parse(hexStr2Str(platForm.ToString())) - 64;
Console.WriteLine("站号:" + _platForm);
StringBuilder phenotype = new StringBuilder("");//表型
for (int i = 30 + multiplier; i <= 31 + multiplier; i++)
{
phenotype.Append(message[i]);
}
StringBuilder _phenotype = new StringBuilder("");//--表型数字 81 83 84
_phenotype.Clear().Append(typePheno(phenotype));
StringBuilder alarmCode = new StringBuilder("");//报警码
for (int i = 32 + multiplier; i <= 33 + multiplier; i++)
{
alarmCode.Append(message[i]);
}
typeAlarmcode(alarmCode);
StringBuilder date = new StringBuilder("20");//采集时间 --(BCD 码)
for (int i = 34 + multiplier; i <= 43 + multiplier; i++)
{
if (i == 35 + multiplier || i == 37 + multiplier) date.Append(message[i] + "-");
else if (i == 39 + multiplier) date.Append(message[i] + " ");
else if (i == 41 + multiplier) date.Append(message[i] + ":");
else date.Append(message[i]);
}
Console.WriteLine("采集时间:" + date);
}
///
/// 表型81
///
///
/// 基数【前置位设备数据总数和】
public static void phenotype81(string message, int baseNum)
{
int multiplier;//基数(前所有位合计)
if (baseNum != 0)
{
//var multiplier = (whatFrame - 1) * 84;
multiplier = baseNum;
baseNum += (68 + 16);
}
else
{
multiplier = 0;
baseNum = (68 + 16);
}
//shareAnalysis(message, multiplier);
StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效
for (int i = 44 + multiplier; i <= 45 + multiplier; i++)
{
validity.Append(message[i]);
}
//if (validity.ToString() == "26")
//{
// Console.WriteLine("抄表数据有效");
//}
//else
//{
// Console.WriteLine("抄表数据无效");
//}
StringBuilder versionNum = new StringBuilder(""); //版本号 --整型
for (int i = 46 + multiplier; i <= 47 + multiplier; i++)
{
versionNum.Append(message[i]);
}
//Console.WriteLine("版本号:" + int.Parse(versionNum.ToString()));
StringBuilder instantaneousFlow = new StringBuilder("");//瞬时流量 --浮点型,缩小 1000 倍为实际值,单位: m3/h
for (int i = 48 + multiplier; i <= 55 + multiplier; i++)
{
instantaneousFlow.Append(message[i]);
}
var _instantaneousFlow = byteToFloat(instantaneousFlow.ToString()) / 1000;
//Console.WriteLine("瞬时流量" + _instantaneousFlow.ToString() + "m3/h");
StringBuilder _positiveFlow = new StringBuilder("");//累积流量 --带符号整型,低字节在前,高字节在后,缩小 10 倍为实际数值,单位: m3。
for (int i = 56 + multiplier; i <= 63 + multiplier; i++)
{
_positiveFlow.Append(message[i]);
}
int positiveFlow = int.Parse(/*hexStr2Str*/(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10;//???
//Console.WriteLine("累积流量:" + positiveFlow + "m3");
StringBuilder waterTemperature = new StringBuilder("");//水温 --浮点型,单位: ℃
for (int i = 64 + multiplier; i <= 71 + multiplier; i++)
{
waterTemperature.Append(message[i]);
}
var _waterTemperature = byteToFloat(waterTemperature.ToString());//???
//Console.WriteLine("水温:" + _waterTemperature + "℃");
StringBuilder _RunTime = new StringBuilder("");//累积运行时间 --带符号整型,低字节在前,高字节在后,单位: h
for (int i = 72 + multiplier; i <= 79 + multiplier; i++)
{
_RunTime.Append(message[i]);
}
int RunTime = int.Parse(/*hexStr2Str*/(interconvert(72 + multiplier, 79 + multiplier, _RunTime.ToString())));//???
//Console.WriteLine("累积运行时间:" + RunTime + "h");
StringBuilder _cellVoltage = new StringBuilder("");//电池电压 --浮点型,低字节在前,高字节在后,单位: v。
for (int i = 80 + multiplier; i <= 87 + multiplier; i++)
{
_cellVoltage.Append(message[i]);
}
//float cellVoltage = float.Parse(/*hexStr2Str*/(interconvert(80 + multiplier, 87 + multiplier, _cellVoltage.ToString())));
float cellVoltage = byteToFloat(_cellVoltage.ToString());//???
//Console.WriteLine("电池电压:" + cellVoltage + "v");
StringBuilder _pipeSize = new StringBuilder("");//管径 --浮点型,单位: mm
for (int i = 88 + multiplier; i <= 95 + multiplier; i++)
{
_pipeSize.Append(message[i]);
}
//float pipeSize = float.Parse(_pipeSize.ToString());
float pipeSize = byteToFloat(_pipeSize.ToString());//???
//Console.WriteLine("管径:" + pipeSize + "mm");
StringBuilder capacity = new StringBuilder("");//量程 --长整型,单位:单位缺失。
for (int i = 96 + multiplier; i <= 103 + multiplier; i++)
{
capacity.Append(message[i]);
}
//Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//???
StringBuilder dampingFactor = new StringBuilder("");//阻尼系数 --ASCII 码
for (int i = 104 + multiplier; i <= 105 + multiplier; i++)
{
dampingFactor.Append(message[i]);
}
//Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString()));
StringBuilder InstrumentType = new StringBuilder("");//仪表类型
for (int i = 106 + multiplier; i <= 107 + multiplier; i++)
{
InstrumentType.Append(message[i]);
}
StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。
for (int i = 108 + multiplier; i <= 109 + multiplier; i++)
{
diagnose.Append(message[i]);
}
//typeMalfunction(diagnose);
//CRC校验
StringBuilder builder = new StringBuilder("");
for (int i = 112 + multiplier; i <= 113 + multiplier; i++)
{
builder.Append(message[i]);
}
if (binAccumulation(4 + multiplier, 111 + multiplier, message).ToUpper() != builder.ToString().ToUpper())
{
Console.WriteLine("接收数据校验失败" + ": " + message);
log.Info("登录帧校验失败" + ": " + message);
Isgo(message, baseNum);
return;
}
shareAnalysis(message, multiplier);
if (validity.ToString() == "26")
{
Console.WriteLine("抄表数据有效");
}
else
{
Console.WriteLine("抄表数据无效");
}
Console.WriteLine("版本号:" + int.Parse(versionNum.ToString()));
Console.WriteLine("瞬时流量" + _instantaneousFlow.ToString() + "m3/h");
Console.WriteLine("累积流量:" + positiveFlow + "m3");
Console.WriteLine("水温:" + _waterTemperature + "℃");
Console.WriteLine("累积运行时间:" + RunTime + "h");
Console.WriteLine("电池电压:" + cellVoltage + "v");
Console.WriteLine("管径:" + pipeSize + "mm");
Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//???
typeMalfunction(diagnose);
//数据校验 --版本号-故障代码
Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 109 + multiplier, message));//版本号--故障码
Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 111 + multiplier, message));//数据部长度--数据校验
Isgo(message, baseNum);
}
///
/// 表型83
///
///
/// 基数【前置位设备数据总数和】
public static void phenotype83(string message, int baseNum)
{
int multiplier;
if (baseNum != 0)
{
//var multiplier = (whatFrame - 1) * 84;
multiplier = baseNum;
baseNum += (84 + 16);
}
else
{
multiplier = 0;
baseNum = (84 + 16);
}
//shareAnalysis(message, multiplier);
StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效
for (int i = 44 + multiplier; i <= 45 + multiplier; i++)
{
validity.Append(message[i]);
}
//if (validity.ToString() == "26")
//{
// Console.WriteLine("抄表数据有效");
//}
//else
//{
// Console.WriteLine("抄表数据无效");
//}
StringBuilder versionNum = new StringBuilder(""); //版本号 --整型
for (int i = 46 + multiplier; i <= 47 + multiplier; i++)
{
versionNum.Append(message[i]);
}
//Console.WriteLine("版本号:" + int.Parse(versionNum.ToString()));
StringBuilder instantaneousFlow = new StringBuilder("");//瞬时流量 --浮点型,缩小 1000 倍为实际值,单位: m3/h
for (int i = 48 + multiplier; i <= 55 + multiplier; i++)
{
instantaneousFlow.Append(message[i]);
}
//Console.WriteLine("瞬时流量" + float.Parse(instantaneousFlow.ToString()) / 1000 + "m3/h");//???
//Console.WriteLine("瞬时流量" + byteToFloat(instantaneousFlow.ToString()) / 1000 + "m3/h");
StringBuilder _positiveFlow = new StringBuilder("");//正累积流量 --带符号整型,低字节在前,高字节在后,缩小 10 倍为实际数值,单位: m3
for (int i = 56 + multiplier; i <= 63 + multiplier; i++)
{
_positiveFlow.Append(message[i]);
}
//int positiveFlow = int.Parse(hexStr2Str(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10;//???
var positiveFlow = float.Parse(/*hexStr2Str*/(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10;
//Console.WriteLine("正累积流量:" + positiveFlow + "m3");
StringBuilder loseFlow = new StringBuilder("");//负累积流量 --BCD 码,缩小10 倍为实际数值,单位:m³
for (int i = 64 + multiplier; i <= 71 + multiplier; i++)
{
loseFlow.Append(message[i]);
}
var _loseFlow = float.Parse(loseFlow.ToString()) / 10;
//Console.WriteLine("负累积流量:" + _loseFlow + "m3");
StringBuilder loseRunTime = new StringBuilder("");//负累积运行时间 --BCD 码,单位: h。
for (int i = 72 + multiplier; i <= 79 + multiplier; i++)
{
loseRunTime.Append(message[i]);
}
var _loseRunTime = int.Parse(loseRunTime.ToString());
//Console.WriteLine("负累积运行时间:" + _loseRunTime + "h");
StringBuilder waterTemperature = new StringBuilder("");//水温 --浮点型,单位: ℃
for (int i = 80 + multiplier; i <= 87 + multiplier; i++)
{
waterTemperature.Append(message[i]);
}
var _waterTemperature = byteToFloat(waterTemperature.ToString());//???
//Console.WriteLine("水温:" + _waterTemperature + "℃");
StringBuilder _RunTime = new StringBuilder("");//累积运行时间 --带符号整型,低字节在前,高字节在后,单位: h
for (int i = 88 + multiplier; i <= 95 + multiplier; i++)
{
_RunTime.Append(message[i]);
}
var RunTime = int.Parse(/*hexStr2Str*/(interconvert(88 + multiplier, 95 + multiplier, _RunTime.ToString())));//???
//Console.WriteLine("累积运行时间:" + RunTime + "h");
StringBuilder _cellVoltage = new StringBuilder("");//电池电压 --浮点型,低字节在前,高字节在后,单位: v。
for (int i = 96 + multiplier; i <= 103 + multiplier; i++)
{
_cellVoltage.Append(message[i]);
}
//float cellVoltage = float.Parse(hexStr2Str(interconvert(96 + multiplier, 103 + multiplier, _cellVoltage.ToString())));//???
float cellVoltage = byteToFloat(_cellVoltage.ToString());
//Console.WriteLine("电池电压:" + cellVoltage + "v");
StringBuilder _pipeSize = new StringBuilder("");//管径 --浮点型,单位: mm
for (int i = 104 + multiplier; i <= 111 + multiplier; i++)
{
_pipeSize.Append(message[i]);
}
//float pipeSize = float.Parse(_pipeSize.ToString());//???
float pipeSize = byteToFloat(_pipeSize.ToString());
//Console.WriteLine("管径:" + pipeSize + "mm");
StringBuilder capacity = new StringBuilder("");//量程 --长整型,单位:单位缺失。
for (int i = 112 + multiplier; i <= 119 + multiplier; i++)
{
capacity.Append(message[i]);
}
//Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//???
StringBuilder dampingFactor = new StringBuilder("");//阻尼系数 --ASCII 码
for (int i = 120 + multiplier; i <= 121 + multiplier; i++)
{
dampingFactor.Append(message[i]);
}
//Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString()));
StringBuilder InstrumentType = new StringBuilder("");//仪表类型
for (int i = 122 + multiplier; i <= 123 + multiplier; i++)
{
InstrumentType.Append(message[i]);
}
StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。
for (int i = 124 + multiplier; i <= 125 + multiplier; i++)
{
diagnose.Append(message[i]);
}
//typeMalfunction(diagnose);
//CRC校验
StringBuilder builder = new StringBuilder("");
for (int i = 128 + multiplier; i <= 129 + multiplier; i++)
{
builder.Append(message[i]);
}
if (binAccumulation(4 + multiplier, 127 + multiplier, message).ToUpper() != builder.ToString().ToUpper())
{
Console.WriteLine("接收数据校验失败" + ": " + message);
log.Info("登录帧校验失败" + ": " + message);
Isgo(message, baseNum);
return;
}
shareAnalysis(message, multiplier);
if (validity.ToString() == "26")
{
Console.WriteLine("抄表数据有效");
}
else
{
Console.WriteLine("抄表数据无效");
}
Console.WriteLine("版本号:" + int.Parse(versionNum.ToString()));
Console.WriteLine("瞬时流量" + byteToFloat(instantaneousFlow.ToString()) / 1000 + "m3/h");
Console.WriteLine("正累积流量:" + positiveFlow + "m3");
Console.WriteLine("负累积流量:" + _loseFlow + "m3");
Console.WriteLine("负累积运行时间:" + _loseRunTime + "h");
Console.WriteLine("水温:" + _waterTemperature + "℃");
Console.WriteLine("累积运行时间:" + RunTime + "h");
Console.WriteLine("电池电压:" + cellVoltage + "v");
Console.WriteLine("管径:" + pipeSize + "mm");
Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//???
//Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString()));
typeMalfunction(diagnose);
//数据校验 --版本号-故障代码
Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 125 + multiplier, message));//版本号--故障码
Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 127 + multiplier, message));//数据部长度--数据校验
Isgo(message, baseNum);
}
///
/// 表型84
///
///
/// 基数【前置位设备数据总数和】
public static void phenotype84(string message, int baseNum)
{
int multiplier;
if (baseNum != 0)
{
//var multiplier = (whatFrame - 1) * 64;
multiplier = baseNum;
baseNum += (64 + 16);
}
else
{
multiplier = 0;
baseNum = (64 + 16);
}
//shareAnalysis(message, multiplier);
StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效
for (int i = 44 + multiplier; i <= 45 + multiplier; i++)
{
validity.Append(message[i]);
}
//if (validity.ToString() == "26")
//{
// Console.WriteLine("抄表数据有效");
//}
//else
//{
// Console.WriteLine("抄表数据无效");
//}
StringBuilder signDelivery = new StringBuilder("");//瞬时流量正负值 --无符号整型,0x00 代表正,0x0a 代表负
for (int i = 46 + multiplier; i <= 47 + multiplier; i++)
{
signDelivery.Append(message[i]);
}
//if (signDelivery.ToString() == "00")
//{
// signDelivery.Clear().Append("");
// Console.WriteLine("瞬时流量为正值");
//}
//else
//{
// signDelivery.Clear().Append("-");
// Console.WriteLine("瞬时流量为负值");
//}
StringBuilder instantaneousFlow = new StringBuilder(""); //瞬时流量 --缩小 1000 倍为实际值,单位: m3/h
for (int i = 48 + multiplier; i <= 55 + multiplier; i++)
{
instantaneousFlow.Append(message[i]);
}
var _instantaneousFlow = float.Parse(instantaneousFlow.ToString()) / 1000;
//Console.WriteLine("瞬时流量:" + signDelivery + _instantaneousFlow + "m3/h");
StringBuilder loseFlow = new StringBuilder("");//负累积流量 --缩小 10 倍为实际数值,单位: m3
for (int i = 56 + multiplier; i <= 63 + multiplier; i++)
{
loseFlow.Append(message[i]);
}
var _loseFlow = float.Parse(loseFlow.ToString()) / 10;
//Console.WriteLine("负累积流量:" + signDelivery + _loseFlow + "m3");
StringBuilder loseRunTime = new StringBuilder("");//负累积运行时间 --单位: h
for (int i = 64 + multiplier; i <= 71 + multiplier; i++)
{
loseRunTime.Append(message[i]);
}
var _loseRunTime = int.Parse(loseRunTime.ToString());
//Console.WriteLine("负累积运行时间:" + _loseRunTime + "h");
StringBuilder positiveFlow = new StringBuilder("");//正累积流量 --缩小 10 倍为实际数值,单位: m3
for (int i = 72 + multiplier; i <= 79 + multiplier; i++)
{
positiveFlow.Append(message[i]);
}
var _positiveFlow = float.Parse(positiveFlow.ToString()) / 10;
//Console.WriteLine("正累积流量:" + _positiveFlow + "m3");
StringBuilder positiveRunTime = new StringBuilder("");//正累积运行时间 --单位: h
for (int i = 80 + multiplier; i <= 87 + multiplier; i++)
{
positiveRunTime.Append(message[i]);
}
var _positiveRunTime = int.Parse(positiveRunTime.ToString());
//Console.WriteLine("正累积运行时间:" + _positiveRunTime + "h");
StringBuilder waterTemperature = new StringBuilder("");//水温 --缩小 100 倍为实际数值,单位: ℃
for (int i = 88 + multiplier; i <= 95 + multiplier; i++)
{
waterTemperature.Append(message[i]);
}
var _waterTemperature = float.Parse(waterTemperature.ToString()) / 100;
//Console.WriteLine("水温:" + _waterTemperature + "℃");
StringBuilder pressure = new StringBuilder("");//压力 --缩小 1000 倍为实际数值,单位: mpa
for (int i = 96 + multiplier; i <= 103 + multiplier; i++)
{
pressure.Append(message[i]);
}
var _pressure = float.Parse(pressure.ToString()) / 1000;
//Console.WriteLine("压力:" + _pressure + "mpa");
StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。
for (int i = 104 + multiplier; i <= 105 + multiplier; i++)
{
diagnose.Append(message[i]);
}
//typeMalfunction(diagnose);
//CRC校验
StringBuilder builder = new StringBuilder("");
for (int i = 108 + multiplier; i <= 109 + multiplier; i++)
{
builder.Append(message[i]);
}
if (binAccumulation(4 + multiplier, 107 + multiplier, message).ToUpper() != builder.ToString().ToUpper())
{
Console.WriteLine("接收数据校验失败" + ": " + message);
log.Info("登录帧校验失败" + ": " + message);
Isgo(message, baseNum);
return;
}
shareAnalysis(message, multiplier);
if (validity.ToString() == "26")
{
Console.WriteLine("抄表数据有效");
}
else
{
Console.WriteLine("抄表数据无效");
}
if (signDelivery.ToString() == "00")
{
signDelivery.Clear().Append("");
Console.WriteLine("瞬时流量为正值");
}
else
{
signDelivery.Clear().Append("-");
Console.WriteLine("瞬时流量为负值");
}
Console.WriteLine("瞬时流量:" + signDelivery + _instantaneousFlow + "m3/h");
Console.WriteLine("负累积流量:" + signDelivery + _loseFlow + "m3");
Console.WriteLine("负累积运行时间:" + _loseRunTime + "h");
Console.WriteLine("正累积流量:" + _positiveFlow + "m3");
Console.WriteLine("正累积运行时间:" + _positiveRunTime + "h");
Console.WriteLine("水温:" + _waterTemperature + "℃");
Console.WriteLine("压力:" + _pressure + "mpa");
typeMalfunction(diagnose);
//数据校验 --瞬时流量符号-故障代码
Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 105 + multiplier, message));//版本号--故障码
Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 107 + multiplier, message));//数据部长度--数据校验
Isgo(message, baseNum);
}
///
/// 判断功能码类型
///
/// 功能码
///
/// 基数【前置位设备数据总数和】
public static void JudgmentFunctionCode(string str, string message, int baseNum)
{
switch ((TypeFunctionCode)int.Parse(str))
{
case TypeFunctionCode.登录帧:
LoginFrameAnalysis(message, ipEnd, socket);
break;
case TypeFunctionCode.数据帧1:
dataFramesAnalysis(message, str, baseNum);
break;
case TypeFunctionCode.校时命令:
clockAnalysis(message, ipEnd);
break;
default:
Console.WriteLine("无此功能码: " + str);
break;
}
}
///
/// 报文结构类型
///
public enum type
{
起始位,
数据部长度,
客户端地址,//12位正常,11位末加F
功能码,//00 成功,01 错误
有效负载,
校验位,
截止位
};
public enum TypeFunctionCode
{
登录帧 = 1,
数据帧1 = 8,
校时命令 = 5,
默认 = 99
}
///
/// 工作模式为枚举型,取值范围 0x00 定时开机,0x01 实时在线
///
public enum TypeworkPattern
{
定时开机 = 0,
实时在线
}
///
/// 判断表型
///
///
public static string typePheno(StringBuilder phenotype)
{
StringBuilder s = new StringBuilder("");
switch (phenotype.ToString())
{
//--0x81 SCL-61D5/6 单向不锈钢带温度流量计 SCL61D6 单向不锈钢带温度流量计
//--0x83 SCL-61D5/6 双向不锈钢带温度流量计 SCL61D6 双向不锈钢带温度流量计
//--0x84 SCL-61D5/6 不锈钢带压力 SCL61D6 不锈钢带压力
case "81":
s.Append("SCL61D6 单向不锈钢带温度流量计");
Console.WriteLine("表型:" + s);
s.Clear().Append("81");
break;
case "83":
s.Append("SCL61D6 双向不锈钢带温度流量计");
Console.WriteLine("表型:" + s);
s.Clear().Append("83");
break;
case "84":
s.Append("SCL61D6 不锈钢带压力");
Console.WriteLine("表型:" + s);
s.Clear().Append("84");
break;
default:
Console.WriteLine($"无此表型: {phenotype}");
break;
}
return s.ToString().Trim();
}
///
/// 判断报警码**只在使用08 码上报数据时才会存在
///
///
public static void typeAlarmcode(StringBuilder alarmCode)
{
switch (alarmCode.ToString())
{
case "01":
alarmCode.Clear().Append("正向流量超上限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "02":
alarmCode.Clear().Append("正向流量超下限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "04":
alarmCode.Clear().Append("负向流量超上限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "08":
alarmCode.Clear().Append("负向流量超下限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "10":
alarmCode.Clear().Append("压力超上限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "20":
alarmCode.Clear().Append("压力超下限");
Console.WriteLine("报警码:" + alarmCode);
break;
case "40":
alarmCode.Clear().Append("预留");
Console.WriteLine("报警码:" + alarmCode);
break;
case "80":
alarmCode.Clear().Append("预留");
Console.WriteLine("报警码:" + alarmCode);
break;
default:
Console.WriteLine($"无此报警码: {alarmCode}");
break;
}
}
///
/// 判断故障码**当设备上报 0x06 故障时,不应再上报其他故障。
///
///
public static void typeMalfunction(StringBuilder diagnose)
{
switch (diagnose.ToString())
{
case "01":
diagnose.Clear().Append("池电压低于3.37V,需要更换电池");
Console.WriteLine("故障码:" + diagnose);
break;
case "02":
diagnose.Clear().Append("空管或者换能器故障无测量信号");
Console.WriteLine("故障码:" + diagnose);
break;
case "03":
diagnose.Clear().Append("代码01 和代码02 同时发生");
Console.WriteLine("故障码:" + diagnose);
break;
case "04":
diagnose.Clear().Append("电池电压低于3.3V,必须更换电池");
Console.WriteLine("故障码:" + diagnose);
break;
case "05":
diagnose.Clear().Append("传感器和换能器之间通讯故障,无通讯");
Console.WriteLine("故障码:" + diagnose);
break;
case "06":
diagnose.Clear().Append("E2PROM 损坏");
Console.WriteLine("故障码:" + diagnose);
break;
case "10":
diagnose.Clear().Append("供水温度传感器故障(短路、开路)或供水温度低于2℃");
Console.WriteLine("故障码:" + diagnose);
break;
case "20":
diagnose.Clear().Append("供水温度超出150℃");
Console.WriteLine("故障码:" + diagnose);
break;
case "40":
diagnose.Clear().Append("回水温度传感器故障(短路、开路)或回水温度低于2℃");
Console.WriteLine("故障码:" + diagnose);
break;
case "80":
diagnose.Clear().Append("回水温度超出150℃");
Console.WriteLine("故障码:" + diagnose);
break;
default:
break;
}
}
}
}