
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,相关类实现代码如下:
CommonUtilsusing 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