网上找了一大堆,终于找到可用的方法,特别记录一下
一、引入包
<!-- 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()方法,吧我需要的数据整理了一下,系统自带的toString()方法,会打印所有的详细信息,读者根据自己需要区改动。
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();
}
}
}