HJ212环境监测数据传输协议

813 阅读3分钟

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<SocketChannel>() {

                 @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<String> {

 

    @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<String, String> rtdData = new HashMap<>();

    private Map<String, String> 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