HJ212协议是环保中一个非常重要的标准协议(字符串协议),之前写了两篇C++ HJ212协议解析的相关博文:
由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。
图4 通讯协议的数据结构
6.1.1通讯包结构组成
名称 | 类型 | 长度 | 描述 |
---|---|---|---|
包头 | 字符 | 2 | 固定为## |
数据段长度 | 十进制整数 | 4 | 数据段的ASCII字符数。例如数据段的字符数为128,则写为“0128” |
数据段 | 字符 | 0<=n<=9999 | 变长的数据 |
CRC校验 | 十六进制 | 4 | 数据段的校验结果,例如C901,如果CRC错,即执行超时 |
包尾 | 字符 | 2 | 回车换行(\r\n) |
数据段结构组成表如下图所示:
《污染物在线监控(监测)系统数据传输标准》简称《HJ212-2017》标准PDF文档可以从中华人民共和国生态环境部的官网下载,具体地址为:HJ212-2017》标准PDF文档
如下图所示:
目前HJ212标准协议已经发布了两个版本,一个是HJ/T 212-2005,另一个是 HJ 212-2017,最新的HJ 212-2017下载地址为:污染物在线监控(监测)系统数据传输标准(HJ 212-2017代替HJ/T 212-2005)
首先创建一个基于C# .Net的库项目,名称为:HJ212ParseLibrary
,相关类实现代码如下:
CommonUtils
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HJ212ParseLibrary
{
/// <summary>
/// 通用工具类
/// </summary>
public class CommonUtils
{
/// <summary>
/// 切分数据
/// </summary>
/// <param name="cp"></param>
/// <returns></returns>
public static List<Dictionary<string, string>> SplitKV(string cp)
{
List<Dictionary<string, string>> resultList = new List<Dictionary<string, string>>();
var arr1 = cp.Split(';');
foreach (var i in arr1)
{
Dictionary<string, string> item = new Dictionary<string, string>();
var arr2 = i.Split(',');
foreach(var j in arr2)
{
var arrKv = j.Split('=');
if (arrKv.Length == 2)
{
item.Add(arrKv[0], arrKv[1]);
}
}
resultList.Add(item);
}
return resultList;
}
/// <summary>
/// 组合数据
/// </summary>
/// <param name=""></param>
/// <returns></returns>
public static string JoinKV(List<Dictionary<string, string>> myList)
{
List<string> item = new List<string>();
foreach (var i in myList)
{
List<string> arrKv = new List<string>();
foreach (var j in i)
{
arrKv.Add(j.Key + "=" + j.Value);
}
item.Add(Join(arrKv, ','));
}
return Join(item, ';');
}
/// <summary>
/// 数据组合字符串
/// </summary>
/// <param name="arrKv">字符串列表</param>
/// <param name="sep">分隔符</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private stat