java 104规约监听,获取数据,解析数据,电网104规约

网上找了一大堆,终于找到可用的方法,特别记录一下

资源下载:打包加入jar包,可下载

一、引入包

<!--  104协议  -->
<dependency>
<groupId>org.openmuc</groupId>
<artifactId>j60870</artifactId>
<version>1.4.0</version>
</dependency>

二、说明:

1.J60870Client.java、 主站连接

2.J60870ClientListener.java、监听

3.J60870Main.java 运行方法

4.项目基于springboot,如果存在自己没有的包,自行引入或者注释对应代码即可,不会影响实际功能

5.监听收到数据后,我重写了一下toString()方法,吧我需要的数据整理了一下,系统自带的同String()方法,会打印所有的详细信息,读者根据自己需要区改动。

6.获取监听数据后,我是通过post请求将数据发送到客户端,然后客户端做处理的,读者自行参考,可注释。

7.该包已经将104的数据,全部解析为正常的十进制数据,比较方便。

三、60870Client.java

package com.dhproject.device104.j60870104;

import org.openmuc.j60870.ASdu;
import org.openmuc.j60870.ClientConnectionBuilder;
import org.openmuc.j60870.Connection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;

//由于可能要监听多个从站,这里使用多线程处理
public class J60870Client implements Runnable {

    private static final Logger log = LoggerFactory.getLogger(J60870Client.class);

    public static String title = "104协议数据服务 - ";

    private String addrerss;

    int port = 2404;

    int time = 3000;
    //监听类,后面代码会给出
    private J60870ClientListener listener;
    //连接类
    private Connection connection;
    //连接参数,可以配置的参数有好多,比如t0,t1,t2等等
    private ClientConnectionBuilder clientConnectionBuilder;

    /**
     *
     * @param addrerss
     */
    public J60870Client(String addrerss) throws UnknownHostException {
        this.addrerss = addrerss;
        init();
    }

    /**
     *
     * @param addrerss
     * @param port
     */
    public J60870Client(String addrerss,int port) throws UnknownHostException {
        this.addrerss = addrerss;
        this.port = port;
        init();
    }

    /**
     *
     * @param addrerss
     * @param port
     * @param time
     */
    public J60870Client(String addrerss,int port,int time) throws UnknownHostException {
        this.addrerss = addrerss;
        this.port = port;
        this.time = time;
        init();
    }

    /**
     * 初始化
     */
    public void init() throws UnknownHostException {
        //获取server端、从站的ip地址对象,这里使用本地ip
        InetAddress address = InetAddress.getByName(addrerss);
        //创建连接参数对象
        clientConnectionBuilder = new ClientConnectionBuilder(address);

        //设置socket的连接超时时间
        clientConnectionBuilder.setConnectionTimeout(time);

        //设置socket的连接超时时间
        clientConnectionBuilder.setPort(port);

        log.info(title+"J60870Client Init Success By Host "+addrerss);
    }

    /**
     * Runnable的run方法重写
     */
    @Override
    public void run() {
        try {
            //主站与从站连接
            connection = clientConnectionBuilder.build();
            //配置数据回调类
            listener = new J60870ClientListener();

            connection.startDataTransfer(listener);

            log.info(title+"J60870Client Run Success By Listener");

        } catch (Exception e) {

            e.printStackTrace();

            log.info(title+"J60870Client Run Exception By Listener");
        }
    }

    /**
     * 关闭连接
     */
    public void disconnect() {
        try {

            this.connection.close();

            log.info(title+"J60870Client Disconnect Success By Close");

        } catch (Exception e) {

            e.printStackTrace();

            log.info(title+"J60870Client Disconnect Exception By Close");
        }
    }
}

四、J60870ClientListener.java

package com.dhproject.device104.j60870104;

import com.dhproject.common.utils.StringUtils;
import org.openmuc.j60870.ASdu;
import org.openmuc.j60870.ConnectionEventListener;
import org.openmuc.j60870.ie.InformationElement;
import org.openmuc.j60870.ie.InformationObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class J60870ClientListener implements ConnectionEventListener{

    private static final Logger log = LoggerFactory.getLogger(J60870ClientListener.class);

    /**
     * 监听从站发来的数据
     * @param aSdu
     */
    @Override
    public void newASdu(ASdu aSdu) {
        log.info(J60870Client.title+"J60870ClientListener NewASdu Get :"+aSdu.toString());
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("type","0");
        params.add("data",toString(aSdu));
        String res = sendPOSTRequest("http://127.0.0.1:8081/deviceAPI104/post",params);
        log.info(J60870Client.title+"J60870ClientListener NewASdu Post :"+res);
    }

    /**
     * 监听连接关闭
     * @param cause
     */
    @Override
    public void connectionClosed(IOException cause) {
        log.debug(J60870Client.title+"J60870ClientListener ConnectionClosed :"+cause.getMessage());
    }

    /**
     * ASdu类方法重写
     * @param aSdu
     * @return
     */
    public String toString(ASdu aSdu){
        List<String> strList = new ArrayList<>();
        if (aSdu.getInformationObjects() != null) {
            InformationObject[] informationObjects = aSdu.getInformationObjects();
            String str;
            for(int i = 0; i < informationObjects.length; ++i) {
                str = toString(informationObjects[i]);
                if(str!=null){
                    strList.add(str);
                }
            }
        }
        return strList.size()>0? StringUtils.join(strList,"***"):null;
    }

    /**
     * InformationObject类方法重写
     * @param informationObjectRecord
     * @return
     */
    public String toString(InformationObject informationObjectRecord) {
        String str;
        InformationElement[] informationElementSet;
        List<String> strList = new ArrayList<>();
        String split = "Short float value:";
        InformationElement[][] valData = informationObjectRecord.getInformationElements();
        if(valData.length>0){
            for(int i = 0; i < valData.length; ++i) {
                informationElementSet = valData[i];
                for(int ii = 0; ii < informationElementSet.length; ++ii) {
                    /**
                     * 目测可能出现的情况:
                     * Short float value: 18.2
                     * Quality, overflow: false, blocked: false, substituted: false, not topical: false, invalid: false
                     */
                    str = informationElementSet[ii].toString();
                    if(str.contains(split)){
                        strList.add(str.split(split)[1].trim());
                    }
                }
            }
        }
        return strList.size()>0? StringUtils.join(strList,","):null;
    }

    /**
     * 发送POST请求
     * @param url
     * @param params
     * @return
     */
    public String sendPOSTRequest(String url, MultiValueMap<String, String> params) {
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        // 执行HTTP请求,将返回的结构使用String类格式化
        ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }
}

五、J60870Main.java

package com.dhproject.device104.j60870104;

import java.net.UnknownHostException;

public class J60870Main {
    public static void main(String[] args){
        try {
            new J60870Client("192.168.0.253").run();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

}

猜你喜欢

转载自blog.csdn.net/zlxls/article/details/128339852
今日推荐