首页 - 关于研博 - 技术笔记 - HJ212环境监测数据传输协议
HJ212环境监测数据传输协议
2025.02.14

     HJ212-2017是中国环境保护部发布的环境监测数据传输协议,主要用于环境监测设备与监控中心之间的数据传输。该协议定义了数据传输的格式、内容、通信方式等,广泛应用于空气质量、水质等环境监测领域。本文将详细介绍HJ212-2017协议的结构,并通过Java语言和Netty框架实现一个简单的协议解析。

一、HJ212-2017协议概述

     HJ212-2017协议采用ASCII码进行数据传输,数据包由多个字段组成,每个字段以分号(;)分隔。协议的基本结构如下:

ST=xx;CN=xx;PW=xx;MN=xx;Flag=xx;CP=xx;CRC=xx\r\n
  • ST:系统类型,表示数据来源的系统类型。

  • CN:命令编号,表示数据包的类型。

  • PW:密码,用于身份验证。

  • MN:设备编号,唯一标识设备。

  • Flag:标志位,表示数据的传输状态。

  • CP:数据段,包含具体的监测数据。

  • CRC:校验码,用于数据完整性校验。

数据段(CP)结构

     数据段(CP)是HJ212-2017协议中最重要的部分,包含了具体的监测数据。数据段由多个数据项组成,每个数据项以逗号(,)分隔,格式如下:

DataTime=xx;xxx-Rtd=xx,xxx-Flag=xx;...
  • DataTime:数据时间,表示数据采集的时间。

  • xxx-Rtd:实时数据值,xxx表示监测因子代码,Rtd表示实时数据。
  • xxx-Flag:数据标志,表示数据的有效性。

二、基于Netty的HJ212-2017协议解析

1. 创建Netty服务器

     创建一个简单的Netty服务器,用于接收HJ212-2017协议数据。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class HJ212Server {

    private final int port;

    public HJ212Server(int port) {
        this.port = port;
    }

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer() {
                 @Override
                 public void initChannel(SocketChannel ch) {
                     ch.pipeline().addLast(new StringDecoder(), new StringEncoder(), new HJ212Handler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)
             .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        new HJ212Server(port).run();
    }
}

2. 实现HJ212协议解析处理器

     实现一个HJ212Handler用于解析HJ212-2017协议数据

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class HJ212Handler extends SimpleChannelInboundHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        // 解析HJ212协议数据
        HJ212Data data = parseHJ212Data(msg);
        if (data != null) {
            System.out.println("Received HJ212 Data: " + data);
        } else {
            System.out.println("Invalid HJ212 Data: " + msg);
        }
    }

    private HJ212Data parseHJ212Data(String data) {
        HJ212Data hj212Data = new HJ212Data();
        String[] fields = data.split(";");
        for (String field : fields) {
            String[] keyValue = field.split("=");
            if (keyValue.length == 2) {
                String key = keyValue[0];
                String value = keyValue[1];
                switch (key) {
                    case "ST":
                        hj212Data.setSt(value);
                        break;
                    case "CN":
                        hj212Data.setCn(value);
                        break;
                    case "PW":
                        hj212Data.setPw(value);
                        break;
                    case "MN":
                        hj212Data.setMn(value);
                        break;
                    case "Flag":
                        hj212Data.setFlag(value);
                        break;
                    case "CP":
                        parseCP(hj212Data, value);
                        break;
                    case "CRC":
                        hj212Data.setCrc(value);
                        break;
                    default:
                        break;
                }
            }
        }
        return hj212Data;
    }

    private void parseCP(HJ212Data hj212Data, String cp) {
        String[] cpFields = cp.split(",");
        for (String cpField : cpFields) {
            String[] keyValue = cpField.split("=");
            if (keyValue.length == 2) {
                String key = keyValue[0];
                String value = keyValue[1];
                if (key.endsWith("-Rtd")) {
                    String factor = key.substring(0, key.length() - 4);
                    hj212Data.addRtdData(factor, value);
                } else if (key.endsWith("-Flag")) {
                    String factor = key.substring(0, key.length() - 5);
                    hj212Data.addFlagData(factor, value);
                } else if (key.equals("DataTime")) {
                    hj212Data.setDataTime(value);
                }
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

3. HJ212数据实体类

import java.util.HashMap;
import java.util.Map;

public class HJ212Data {
    private String st;
    private String cn;
    private String pw;
    private String mn;
    private String flag;
    private String dataTime;
    private String crc;
    private Map rtdData = new HashMap<>();
    private Map flagData = new HashMap<>();

    // Getters and Setters

    public void addRtdData(String factor, String value) {
        rtdData.put(factor, value);
    }

    public void addFlagData(String factor, String value) {
        flagData.put(factor, value);
    }

    @Override
    public String toString() {
        return "HJ212Data{" +
                "st='" + st + '\'' +
                ", cn='" + cn + '\'' +
                ", pw='" + pw + '\'' +
                ", mn='" + mn + '\'' +
                ", flag='" + flag + '\'' +
                ", dataTime='" + dataTime + '\'' +
                ", crc='" + crc + '\'' +
                ", rtdData=" + rtdData +
                ", flagData=" + flagData +
                '}';
    }
}

4. 运行与测试

     启动HJ212Server后,你可以通过TCP客户端向服务器发送HJ212-2017协议格式的数据,例如

ST=32;CN=2011;PW=123456;MN=88888880000001;Flag=4;CP=DataTime=20231010120000;w01018-Rtd=12.5,w01018-Flag=N;w01019-Rtd=0.8,w01019-Flag=N;CRC=ABCD\r\n

 

 

获取相关资料
下载地址将会发送至您填写的邮箱
相关新闻
电能表DLT645协议解析
2025-02-07
水文SL651协议解析
2025-01-17
JT/T808 协议解析
2025-01-10
  • 在线客服
  • 电话咨询
  • 微信
  • 短视频