Repository: zengfr/easymodbus4j
Branch: master
Commit: 5749858eb495
Files: 104
Total size: 169.7 KB
Directory structure:
gitextract_pblhxo4a/
├── .gitignore
├── LICENSE
├── README.md
├── easymodbus4j-commandclient/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── github/
│ │ │ └── zengfr/
│ │ │ └── easymodbus4j/
│ │ │ └── app/
│ │ │ ├── client/
│ │ │ │ ├── DeviceClient.java
│ │ │ │ ├── UdpClient.java
│ │ │ │ └── UdpClientHandler.java
│ │ │ ├── common/
│ │ │ │ ├── DeviceArg.java
│ │ │ │ ├── DeviceCommand.java
│ │ │ │ └── FunctionCode.java
│ │ │ ├── gprs/
│ │ │ │ └── juheApi.java
│ │ │ ├── gps/
│ │ │ │ ├── gprsData.java
│ │ │ │ ├── locapiBaiduClientUtil.java
│ │ │ │ ├── locapiCellidClientUtil.java
│ │ │ │ ├── locapiReq.java
│ │ │ │ ├── locapiReqBody.java
│ │ │ │ ├── locapiResp.java
│ │ │ │ └── locapiRespBody.java
│ │ │ ├── repository/
│ │ │ │ ├── access_tokenReq.java
│ │ │ │ ├── access_tokenResp.java
│ │ │ │ ├── autosend_listReq.java
│ │ │ │ ├── autosend_listResp.java
│ │ │ │ ├── autosend_listRespItem.java
│ │ │ │ ├── mainboard_adressResp.java
│ │ │ │ ├── mainboard_adressRespItem.java
│ │ │ │ ├── req.java
│ │ │ │ ├── resp.java
│ │ │ │ ├── update_modbus_valuesReq.java
│ │ │ │ ├── update_modbus_valuesReqItem.java
│ │ │ │ ├── update_slaveipportReq.java
│ │ │ │ └── value.java
│ │ │ ├── sender/
│ │ │ │ ├── UdpSender.java
│ │ │ │ └── UdpSenderFactory.java
│ │ │ └── util/
│ │ │ └── HttpUtil.java
│ │ └── resources/
│ │ └── readme.txt
│ └── test/
│ └── java/
│ ├── ClientTest.java
│ └── CustomUdpClientHandler.java
├── easymodbus4j-example/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── github/
│ │ │ └── zengfr/
│ │ │ └── easymodbus4j/
│ │ │ ├── example/
│ │ │ │ ├── ModbusConfig.java
│ │ │ │ ├── ModbusConsoleApp.java
│ │ │ │ ├── ModbusSetup.java
│ │ │ │ ├── processor/
│ │ │ │ │ ├── ExampleModbusMasterResponseProcessor.java
│ │ │ │ │ └── ExampleModbusSlaveRequestProcessor.java
│ │ │ │ └── schedule/
│ │ │ │ └── ModbusMasterSchedule4ConfigFile.java
│ │ │ ├── example3/
│ │ │ │ ├── Example3.java
│ │ │ │ └── Example4.java
│ │ │ └── main/
│ │ │ └── Example.java
│ │ └── resources/
│ │ ├── autoSend.txt
│ │ ├── logback.xml
│ │ ├── readme.txt
│ │ ├── start0-Server4TcpMaster-Client4TcpSlave.bat
│ │ ├── start1-Server4TcpMaster.bat
│ │ ├── start2-Client4TcpSlave.bat
│ │ ├── start3-Client4TcpMaster.bat
│ │ ├── start4-Server4TcpSlave.bat
│ │ ├── start5-Server4RtuMaster-Client4RtuSlave.bat
│ │ ├── start6-Server4RtuMaster.bat
│ │ ├── start7-Client4RtuSlave.bat
│ │ ├── start8-Client4RtuMaster.bat
│ │ ├── start9-Server4RtuSlave.bat
│ │ └── zip.xml
│ └── test/
│ └── java/
│ └── com/
│ └── github/
│ └── zengfr/
│ └── easymodbus4j/
│ └── AppTest.java
├── easymodbus4j-example2/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── github/
│ │ │ └── zengfr/
│ │ │ └── easymodbus4j/
│ │ │ ├── app/
│ │ │ │ ├── ModbusServer4MasterApp.java
│ │ │ │ ├── cache/
│ │ │ │ │ ├── AbstrctModbusKVCache.java
│ │ │ │ │ ├── ModbusDeviceIdVersionIdCache.java
│ │ │ │ │ ├── ModbusIpPortDeviceIdCache.java
│ │ │ │ │ ├── ModbusKVCacheFactory.java
│ │ │ │ │ └── ModbusVersionIdCache.java
│ │ │ │ ├── plugin/
│ │ │ │ │ ├── DeviceCommandPlugin.java
│ │ │ │ │ ├── DeviceCommandPluginRegister.java
│ │ │ │ │ ├── DevicePlugin.java
│ │ │ │ │ ├── DeviceRepositoryPlugin.java
│ │ │ │ │ ├── DeviceRepositoryPluginRegister.java
│ │ │ │ │ └── impl/
│ │ │ │ │ ├── DeviceCommandAbstractPlugin.java
│ │ │ │ │ ├── DeviceCommandV1PluginImpl.java
│ │ │ │ │ └── DeviceRepositoryV1PluginImpl.java
│ │ │ │ ├── processor/
│ │ │ │ │ └── CustomModbusMasterResponseProcessor.java
│ │ │ │ ├── repository/
│ │ │ │ │ └── DataRestRepository.java
│ │ │ │ ├── schedule/
│ │ │ │ │ ├── ModbusMasterSchedule4All.java
│ │ │ │ │ └── ModbusMasterSchedule4DeviceId.java
│ │ │ │ ├── server/
│ │ │ │ │ └── udp/
│ │ │ │ │ ├── UdpServer.java
│ │ │ │ │ ├── UdpServerHandler.java
│ │ │ │ │ └── UdpServerHandler4SendToServer.java
│ │ │ │ └── util/
│ │ │ │ └── NetworkUtil.java
│ │ │ └── main/
│ │ │ └── Example2.java
│ │ └── resources/
│ │ ├── log4j.properties
│ │ ├── logback.xml
│ │ ├── readme.txt
│ │ ├── start0-Server4TcpMaster-UdpServer.bat
│ │ ├── start6-Server4RtuMaster-UdpServer.bat
│ │ └── zip.xml
│ └── test/
│ └── java/
│ └── com/
│ └── github/
│ └── zengfr/
│ └── easymodbus4j/
│ ├── RegistersUtilTest.java
│ └── app/
│ ├── A.java
│ ├── AppTest.java
│ ├── CaseTest.java
│ └── PrimeTest.java
└── easymodbus4j-extension/
├── pom.xml
└── src/
└── main/
└── java/
└── com/
└── github/
└── zengfr/
└── easymodbus4j/
├── handle/
│ └── impl/
│ ├── ModbusMasterResponseHandler.java
│ └── ModbusSlaveRequestHandler.java
└── processor/
├── AbstractModbusProcessor.java
├── ModbusMasterResponseProcessor.java
├── ModbusProcessor.java
└── ModbusSlaveRequestProcessor.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
*.iml
dbg/
target/
.settings/
.idea/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 zengfr https://github.com/zengfr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

# easymodbus4j [chs]
easymodbus4j是一个高性能和易用的 Modbus 协议的 Java 实现,基于 Netty 开发,可用于 Modbus协议的Java客户端和服务器开发.
# easymodbus4j [en]
A high-performance and ease-of-use implementation of the Modbus protocol written in Java netty support for modbus 8 mode client/server and master/slave.
### easymodbus4j features 特点:
- 1、Netty NIO high performance高性能.
- 2、Modbus Function sync/aync 同步/异步非阻塞。
- 3、Modbus IoT Data Connector Supports工业物联网平台IoT支持。
- 4、支持Modbus TCP\Modbus RTU protocol两种通信协议.
- 5、灵活架构,支持8种生产部署模式,自由组合,满足不同生产要求.
- 6、通用组件包,支持高度自定义接口.
- 7、完全支持Modbus TCP 4种部署模式: TCP服务器master,TCP客户端slave,TCP服务器slave,TCP客户端master。
- 8、完全支持Modbus RTU 4种部署模式: RTU服务器master,RTU客户端slave,RTU服务器slave,RTU客户端master。
- 9、友好的调试以及日志支持bit\bitset\byte\short\int\float\double。
- 10、Supports Function Codes:
* Read Coils (FC1)
* Read Discrete Inputs (FC2)
* Read Holding Registers (FC3)
* Read Input Registers (FC4)
* Write Single Coil (FC5)
* Write Single Register (FC6)
* Write Multiple Coils (FC15)
* Write Multiple Registers (FC16)
* Read/Write Multiple Registers (FC23)
### repositories
- Project Example Code : https://github.com/zengfr/easymodbus4j
- Mvnrepository Repositories: [Repositories Central Sonatype Mvnrepository easymodbus4j](https://mvnrepository.com/artifact/com.github.zengfr/easymodbus4j)
```
artifactId/jar:
easymodbus4j-core.jar Modbus protocol协议
easymodbus4j-codec.jar Modbus 通用编码器解码器
easymodbus4j.jar Modbus General/Common公共通用包
easymodbus4j-client.jar Modbus client客户端
easymodbus4j-server.jar Modbus server服务器端
easymodbus4j-extension.jar Modbus extension扩展包 ModbusMasterResponseProcessor/ModbusSlaveRequestProcessor interface
```
### quick Start快速开发:
#### 第一步step1 ,import jar:
- 1.1 maven:
```
com.github.zengfreasymodbus4j-client0.0.5com.github.zengfreasymodbus4j-server0.0.5com.github.zengfreasymodbus4j-extension0.0.5
```
#### 第二步step2,implement handler:
- 2.1 if master
* 实现implement ResponseHandler接口
see easymodbus4j-example:ModbusMasterResponseHandler.java
* or 实现implement ModbusMasterResponseProcessor 接口 use new ModbusMasterResponseHandler(responseProcessor);
- 2.2 if slave
* 实现implement RequestHandler接口
see easymodbus4j-example:ModbusSlaveRequestHandler.java
* or 实现implement ModbusSlaveRequestProcessor 接口 use new ModbusSlaveRequestHandler(reqProcessor);
#### 第三步step3,
- 3.1 select one master/slave and client/server mode:
```java
modbusServer = ModbusServerTcpFactory.getInstance().createServer4Master(port, responseHandler);
modbusClient = ModbusClientTcpFactory.getInstance().createClient4Slave(host,port, requestHandler);
modbusClient = ModbusClientTcpFactory.getInstance().createClient4Master(host, port, responseHandler);
modbusServer = ModbusServerTcpFactory.getInstance().createServer4Slave(port, requestHandler);
modbusServer = ModbusServerRtuFactory.getInstance().createServer4Master(port, responseHandler);
modbusClient = ModbusClientRtuFactory.getInstance().createClient4Slave(host,port, requestHandler);
modbusClient = ModbusClientRtuFactory.getInstance().createClient4Master(host, port, responseHandler);
modbusServer = ModbusServerRtuFactory.getInstance().createServer4Slave(port, requestHandler);
```
#### 第四步step4 ,FAQs and advanced extensions:
- 4.1 how to send a request ? to send data
```java
Thread.sleep(3*1000);// sleep 3s before,when client or server open connection is async;
Channel channel = client.getChannel());
Channel channel = server.getChannelsBy(...));
ChannelSender sender = ChannelSenderFactory.getInstance().get(channel);
ChannelSender sender2 = new ChannelSender(channel,unitId,protocolIdentifier);
sender.readCoils(...)
sender.readDiscreteInputs(...)
sender.writeSingleRegister(...)
```
- 4.2 how to process request/response? to receive data
see code in processResponseFrame mothod in ModbusMasterResponseHandler.java or ModbusMasterResponseProcessor.java
```java
public void processResponseFrame(Channel channel, int unitId, AbstractFunction reqFunc, ModbusFunction respFunc) {
if (respFunc instanceof ReadCoilsResponse) {
ReadCoilsResponse resp = (ReadCoilsResponse) respFunc;
ReadCoilsRequest req = (ReadCoilsRequest) reqFunc;
//process business logic for req/resp
}
};
```
- 4.3 how to get response to byteArray for custom decode by yourself?
see code in processResponseFrame mothod in ModbusMasterResponseHandler.java or ModbusMasterResponseProcessor.java
```java
public void processResponseFrame(Channel channel, int unitId, AbstractFunction reqFunc, ModbusFunction respFunc) {
if (respFunc instanceof ReadDiscreteInputsResponse) {
ReadDiscreteInputsResponse resp = (ReadDiscreteInputsResponse) respFunc;
byte[] resutArray = resp.getInputStatus().toByteArray();
}
};
```
- 4.4 how to show log?
see ModbusMasterResponseHandler.java in example project.
```java
ModbusFrameUtil.showFrameLog(logger, channel, frame);
```
- 4.5 how to custom a client/server advance by yourself?
```java
ModbusChannelInitializer modbusChannelInitializer=...;
ModbusServerTcpFactory.getInstance().createServer4Master(port,modbusChannelInitializer);
```
#### Example Project Code
- example1
[example1](https://github.com/zengfr/easymodbus4j/tree/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example)
- example3
[example3](https://github.com/zengfr/easymodbus4j/tree/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3)
- other example1
[other example1](https://gitee.com/zengfr/easymodbus4j/tree/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example)
- other example3
[other example3](https://gitee.com/zengfr/easymodbus4j/tree/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3)
- client4Master demo:[client4Master demo](
https://gitee.com/zengfr/easymodbus4j/blob/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3/Example3.java) [最佳简单快速参考实例][Best simple quick demo]
- server4Master demo:[server4Master demo](
https://gitee.com/zengfr/easymodbus4j/blob/master/easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3/Example4.java)[最佳简单快速参考实例][Best simple quick demo]
#### Example run startup:
- 1、unzip file easymodbus4j-example-0.0.5-release.zip.
- 2、for modbus master mode:open autosend.txt file in dir or autosend.txt rsourcefile in easymodbus4j-example-0.0.5.jar
- 3、for modbus master mode:edit autosend.txt file
- 4、start startup.bat.
- 5、you also can edit *.bat for modbus master/salve mode: .
#### Example实例说明:
- 1、解压缩zip文件到文件夹
- 2、java程序 运行不了 则安装jdk8.
- 3、解压后8个bat文件 对应TCP/RTU 服务器master,客户端slave,服务器slave,客户端master 8种模式.
- 4、Master模式 可以设置autosend.txt文件,定时发送读写请求。
- 5、记事本打开bat文件可以编辑相关参数,如定时延时发送时间以及详细日志开关。
#### 开发实例系列教程Develop a series of tutorial examples
[easymodbus4j 开发实例系列教程之1----客户端master模式](https://my.oschina.net/zengfr/blog/4304442)
[easymodbus4j 开发实例系列教程之2----服务端master模式](https://my.oschina.net/zengfr/blog/4305723)
#### capture demo 运行效果图截屏:




#### capture demo 运行效果图截屏2:




================================================
FILE: easymodbus4j-commandclient/pom.xml
================================================
4.0.0com.github.zengfreasymodbus4j-commandclient0.0.5easymodbus4j-commandclienttrue1.8com.github.zengfr.projectparent0.0.2../parent/pom.xmljunitjunittestio.nettynetty-allorg.apache.httpcomponentshttpclientcommons-loggingcommons-loggingorg.slf4jjcl-over-slf4j
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/client/DeviceClient.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.client;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import com.github.zengfr.easymodbus4j.app.common.DeviceCommand;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class DeviceClient extends UdpClient {
private static final int MAX = 10000 * 999;
private static final int MIN = 10000 * 100;
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
private static Random rnd = new Random();
private static class DeviceClientHolder {
private static final DeviceClient INSTANCE = new DeviceClient();
}
public static DeviceClient getInstance() {
return DeviceClientHolder.INSTANCE;
}
private DeviceClient() {
}
public String sendCommand(String host, int port, DeviceCommand cmd) throws InterruptedException {
String uuid = getUUID();
getSender().send(host, port, buildCommandMessage(uuid, cmd));
return uuid;
}
public String sendCommand(String host, int port, String msg) throws InterruptedException {
String uuid = getUUID();
getSender().send(host, port, buildCommandMessage(uuid, msg));
return uuid;
}
protected String buildCommandMessage(String uuid, DeviceCommand cmd) {
return buildCommandMessage(uuid, cmd.toString());
}
protected String buildCommandMessage(String uuid, String cmd) {
return String.format("%s;%s", uuid, cmd);
}
protected String getUUID() {
int randNumber = rnd.nextInt(MAX - MIN + 1) + MIN;
return String.format("%s%s", LocalDateTime.now(ZoneOffset.of("+8")).format(formatter), randNumber);
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/client/UdpClient.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.client;
import com.github.zengfr.easymodbus4j.app.sender.UdpSender;
import com.github.zengfr.easymodbus4j.app.sender.UdpSenderFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class UdpClient {
protected Channel channel;
protected UdpSender sender;
protected boolean isInit = false;
public void setup(UdpClientHandler handler) throws InterruptedException {
setup(handler, false);
}
public void setup(UdpClientHandler handler, boolean wait) throws InterruptedException {
if (!isInit) {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.option(ChannelOption.SO_BROADCAST, true);
b.group(group).channel(NioDatagramChannel.class).handler(handler);
channel = b.bind(0).sync().channel();
sender = UdpSenderFactory.getInstance().get(channel);
isInit = true;
if (wait) {
channel.closeFuture().await();
}
}
}
public UdpSender getSender() {
return this.sender;
}
public Channel getChannel() {
return channel;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/client/UdpClientHandler.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.client;
import org.apache.commons.lang3.StringUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import io.netty.channel.ChannelHandler.Sharable;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
@Sharable
public abstract class UdpClientHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
if(isDoReceived()) {
messageReceived(ctx, packet.content().toString(CharsetUtil.UTF_8));
}
}
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
if (StringUtils.isNotEmpty(msg)) {
String[] args = msg.split(";");
if (args.length >= 11) {
int success = Integer.valueOf(args[0]);
String uuid = args[1];
String deviceId = args[2];
String ip = args[3];
Integer port = Integer.valueOf(args[4]);
String version = args[5];
Integer functionCode = Integer.valueOf(args[6]);
Integer address = Integer.valueOf(args[7]);
String valueType = args[8];
String value = args[9];
String[] values = args[10].split(",");
channelRead0(uuid, deviceId, ip, port, version, functionCode, address, valueType, value, values,
success);
values=null;
}
args=null;
}
}
protected abstract boolean isDoReceived();
protected abstract void channelRead0(String uuid, String deviceId, String ip, Integer port, String version,
Integer functionCode, Integer address, String valueType, String value, String[] values, int success)
throws Exception;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/common/DeviceArg.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.common;
public class DeviceArg {
public String deviceId;
public String ip;
public int port;
public String version;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/common/DeviceCommand.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.common;
import org.apache.commons.lang3.StringUtils;
public class DeviceCommand {
/** 设备标识id(必选) */
private String deviceId;
/** 设备ip(可选) */
private String ip;
/** 设备port(可选) */
private int port;
/** 设备型号(可选) */
private String version;
/** 见classFunctionCode */
private int functionCode;
/** 寄存器地址 */
private int address;
/** 寄存器地址值 */
private T value;
/** 寄存器地址值 */
private T[] values;
/** 值类型 */
private String valueType;
public String getDeviceId() {
return this.deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getIp() {
return this.ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
public int getFunctionCode() {
return this.functionCode;
}
public void setFunctionCode(int functionCode) {
this.functionCode = functionCode;
}
public int getAddress() {
return this.address;
}
public void setAddress(int address) {
this.address = address;
}
public T getValue() {
return this.value;
}
public void setValue(T value) {
this.value = value;
syncValueType();
}
public T[] getValues() {
return this.values;
}
public void setValues(T[] values) {
this.values = values;
syncValueType();
}
public void setValueType(String valueType) {
this.valueType = valueType;
}
public String getValueType() {
return valueType;
}
public void syncValueType() {
setValueType(getValueType(this.value, this.values));
}
@Override
public String toString() {
return String.format("%s;%s;%s;%s;%s;%s;%s;%s;%s", deviceId, ip, port, version, functionCode, address,
getValueType(), value, StringUtils.join(values, ','));
}
private static String getValueType(T v, T[] vv) {
if (v != null && !v.toString().isEmpty()) {
return v.getClass().getSimpleName();
} else if (vv != null && vv.length > 0) {
return vv[0].getClass().getSimpleName();
}
return "";
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/common/FunctionCode.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.common;
public class FunctionCode {
public static final short READ_COILS = 0x01;
public static final short READ_DISCRETE_INPUTS = 0x02;
public static final short READ_HOLDING_REGISTERS = 0x03;
public static final short READ_INPUT_REGISTERS = 0x04;
public static final short WRITE_SINGLE_COIL = 0x05;
public static final short WRITE_SINGLE_REGISTER = 0x06;
public static final short READ_EXCEPTION_STATUS = 0x07;
public static final short DIAGNOSTICS = 0x08;
public static final short GET_COMM_EVENT_COUNTER = 0x0B;
public static final short GET_COMM_EVENT_LOG = 0x0C;
public static final short WRITE_MULTIPLE_COILS = 0x0F;
public static final short WRITE_MULTIPLE_REGISTERS = 0x10;
public static final short REPORT_SLAVEID = 0x11;
public static final short READ_FILE_RECORD = 0x14;
public static final short WRITE_FILE_RECORD = 0x15;
public static final short MASK_WRITE_REGISTER = 0x16;
public static final short READ_WRITE_MULTIPLE_REGISTERS = 0x17;
public static final short READ_FIFO_QUEUE = 0x18;
public static final short ENCAPSULATED_INTERFACE_TRANSPORT = 0x2B;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gprs/juheApi.java
================================================
package com.github.zengfr.easymodbus4j.app.gprs;
import com.alibaba.fastjson.JSON;
import com.github.zengfr.easymodbus4j.app.util.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by zengfr on 2020/11/26.
*/
public class juheApi {
public static class Resp {
public String mcc;
public String mnc;
public String lac;
public String ci;
public String lat;
public String lon;
public String address;
public String radius;
public String rcontent;
}
private final static String api = "https://v.juhe.cn/cell/Triangulation/query.php";
private final static String homePage = "https://www.juhe.cn/docs/api/id/8?bd_vid=7081628664865556502";
public static void main(String... args) throws IOException {
for (int i = 0; i < 10; i++) {
test();
}
}
public static void test() throws IOException {
Resp resp = getGprs("4163", "21297934");
System.out.println(JSON.toJSONString(resp));
}
public static Resp getGprs(String lac, String cId) throws IOException {
return getGprs(lac, cId, false, "UTF-8");
}
public static Resp getGprs(String lac, String cId, boolean isHex, String charest) throws IOException {
String data = String.format("mcc=460&mnc=0&lac=%s&ci=%s&hex=%s", lac, cId, isHex ? 16 : 10);
String org = "https://v.juhe.cn";
String contentString = HttpUtil.post(api, homePage, org, data, charest);
String pat = "\"result\":(.*?)}";
Matcher m = Pattern.compile(pat).matcher(contentString);
String result;
Resp resp = new Resp();
if (m.find()) {
result = m.group(1);
if (result != null && !result.startsWith("null")) {
resp = JSON.parseObject(result + "}", Resp.class);
}
}
if (StringUtils.isEmpty(resp.address)) {
resp.rcontent = contentString;
}
return resp;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/gprsData.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
/** 基站信息结构体 */
public class gprsData{
public int MCC;
public int MNC;
public int LAC;
public int CID;
public int signal;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiBaiduClientUtil.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
/**
* 智能硬件定位 可以通过蓝牙、WI-FI等获取用户定位数据 利用蓝牙、WI-FI等信息,传给服务端进行处理,获取定位信息,完成地图、路线规划、轨迹等功能
* http://lbsyun.baidu.com/index.php?title=webapi/intel-hardware-api
* https://api.map.baidu.com/locapi/v2 根据mcc, mnc,lac,cellid访问百度接口 -gprs移动定位
* 适用于室内、室外多种定位场景,覆盖智能可穿戴设备、车载设备等。
*/
public class locapiBaiduClientUtil {
private static String api = "https://api.map.baidu.com/locapi/v2";
private static String apiKey = "z4Xg8Va4P2u1on5kjrU6ATGn2niaELgg";
public static void main(String... args) throws IOException {
test();
}
public static void test() throws IOException {
String bts = "460,0,4163,21297934,-124";
parse(bts);
gprsData r = new gprsData();
r.MCC = 0;
r.MNC = 0;
r.LAC = 0;
r.CID = 0;
r.signal = -1;
parse(r);
}
public static locapiRespBody parse(gprsData r) throws IOException {
String bts = String.format("%s,%s,%s,%s,%s", r.MCC, r.MNC, r.LAC, r.CID, r.signal);
return parse(bts);
}
public static locapiRespBody parse(String bts) throws IOException {
locapiReqBody body = new locapiReqBody();
body.setAccesstype(0);// 移动接入网络:0 wifi接入网络:1 仅gps坐标转换:2
body.setCdma(0);// 非cdma:0; cdma:1 默认值为:0
body.setNetwork("GPRS");// 无线网络类型 GSM/GPRS/EDGE/HSUPA/HSDPA/WCDMA (注意大写)
body.setImei("18701966811");
body.setBts(bts);
//非CDMA格式为:mcc, mnc,lac,cellid,signal
//CDMA格式为:sid,nid,bid,lon,lat,signal 其中lon,lat可为空,格式为:sid,nid,bid,,,signal
body.setNeed_rgc("Y");// 返回地址信息,默认不返回 Y : 返回rgc结果 N : 不返回rgc结果
body.setCtime("" + LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
body.setOutput("JSON");
locapiReq req = new locapiReq();
req.setVer("1.0");
req.setTrace(false);
req.setSrc("bdl");
req.setProd("bdl");
req.setKey(apiKey);
req.setBody(Lists.newArrayList(body));
return parse(req);
}
protected static locapiRespBody parse(locapiReq req) throws IOException {
StringBuffer sb = new StringBuffer();
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(api);
String reqStr = JSON.toJSONString(req);
StringEntity se = new StringEntity(reqStr);
System.out.println(reqStr);
post.setEntity(se);
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
System.out.println(sb);//740 Failed to authenticate for api loc is forbidden.(服务被禁用,一般不会出现)
return JSON.parseObject(sb.toString(), locapiRespBody.class);
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiCellidClientUtil.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
import com.alibaba.fastjson.JSON;
import com.github.zengfr.easymodbus4j.app.util.HttpUtil;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class locapiCellidClientUtil {
public static class Resp {
public String lat;
public String lng;
public String title;
}
private final static String api = "http://www.cellid.cn/cidInfo.php?lac=%s&cell_id=%s&hex=false&flag=%s";
private final static String homePage = "http://www.cellid.cn/";
public static void main(String... args) throws IOException {
test();
}
public static void test() throws IOException {
Resp resp = parseResp("13876", "1285714605", "UTF-8");
System.out.println(JSON.toJSONString(resp));
}
public static Resp parseResp(String lac, String cId, String charest) throws IOException {
// cidMap(39.941548,116.352661,'(4163,21297934)
// 39.941548,116.352661 北京市西城区西外大街1号')
String flag = getFlag(charest);
String contentString = parse(lac, cId, flag, charest);
Resp resp = new Resp();
String pat = "\\((.*?),(.*?),'(.*?) (.*?)'";
Matcher m = Pattern.compile(pat).matcher(contentString);
if (m.find()) {
resp.lat = m.group(1);
resp.lng = m.group(2);
resp.title = m.group(4);
}
return resp;
}
protected static String getFlag(String charest) throws ClientProtocolException, IOException {
String urlString = homePage;
String contentString = HttpUtil.get(urlString,homePage,homePage,charest);
Matcher m = Pattern.compile("").matcher(contentString);
if (m.find()) {
return m.group(1);
}
return "";
}
protected static String parse(String lac, String cId, String flag, String charest) throws IOException {
String urlString = String.format(api, lac, cId, flag);
String content=HttpUtil.post (urlString,homePage,null,null,charest);
return content;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiReq.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
import java.util.List;
public class locapiReq {
private String ver;
private boolean trace;
private String prod;
private String src;
private String key;
private List body;
public void setVer(String ver) {
this.ver = ver;
}
public String getVer() {
return ver;
}
public void setTrace(boolean trace) {
this.trace = trace;
}
public boolean getTrace() {
return trace;
}
public void setProd(String prod) {
this.prod = prod;
}
public String getProd() {
return prod;
}
public void setSrc(String src) {
this.src = src;
}
public String getSrc() {
return src;
}
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void setBody(List body) {
this.body = body;
}
public List getBody() {
return body;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiReqBody.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
public class locapiReqBody {
private String bts;
private String output;
private int accesstype;
private String macs;
private String imei;
private String ctime;
private String nearbts;
private int cdma;
private String need_rgc;
private String network;
public void setBts(String bts) {
this.bts = bts;
}
public String getBts() {
return bts;
}
public void setOutput(String output) {
this.output = output;
}
public String getOutput() {
return output;
}
public void setAccesstype(int accesstype) {
this.accesstype = accesstype;
}
public int getAccesstype() {
return accesstype;
}
public void setMacs(String macs) {
this.macs = macs;
}
public String getMacs() {
return macs;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getImei() {
return imei;
}
public void setCtime(String ctime) {
this.ctime = ctime;
}
public String getCtime() {
return ctime;
}
public void setNearbts(String nearbts) {
this.nearbts = nearbts;
}
public String getNearbts() {
return nearbts;
}
public void setCdma(int cdma) {
this.cdma = cdma;
}
public int getCdma() {
return cdma;
}
public void setNeed_rgc(String need_rgc) {
this.need_rgc = need_rgc;
}
public String getNeed_rgc() {
return need_rgc;
}
public void setNetwork(String network) {
this.network = network;
}
public String getNetwork() {
return network;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiResp.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
import java.util.List;
public class locapiResp {
private int errcode;
private String msg;
private List body;
public void setErrcode(int errcode) {
this.errcode = errcode;
}
public int getErrcode() {
return errcode;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setBody(List body) {
this.body = body;
}
public List getBody() {
return body;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/gps/locapiRespBody.java
================================================
package com.github.zengfr.easymodbus4j.app.gps;
public class locapiRespBody {
private int type;
private String location;
private int radius;
private String country;
private String province;
private String city;
private String citycode;
private String district;
private String road;
private String ctime;
private String indoor;
private int error;
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void setCountry(String country) {
this.country = country;
}
public String getCountry() {
return country;
}
public void setProvince(String province) {
this.province = province;
}
public String getProvince() {
return province;
}
public void setCity(String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCitycode(String citycode) {
this.citycode = citycode;
}
public String getCitycode() {
return citycode;
}
public void setDistrict(String district) {
this.district = district;
}
public String getDistrict() {
return district;
}
public void setRoad(String road) {
this.road = road;
}
public String getRoad() {
return road;
}
public void setCtime(String ctime) {
this.ctime = ctime;
}
public String getCtime() {
return ctime;
}
public void setIndoor(String indoor) {
this.indoor = indoor;
}
public String getIndoor() {
return indoor;
}
public void setError(int error) {
this.error = error;
}
public int getError() {
return error;
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/access_tokenReq.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class access_tokenReq extends req {
public String client_id;
public String client_secret;
public String grant_type;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/access_tokenResp.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class access_tokenResp {
public String access_token;
public String token_type;
public String expires_in;
public String scope;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/autosend_listReq.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class autosend_listReq extends req{
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/autosend_listResp.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class autosend_listResp extends resp {
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/autosend_listRespItem.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class autosend_listRespItem {
public String function;
public Integer address;
public Integer quantity;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/mainboard_adressResp.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class mainboard_adressResp extends resp {
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/mainboard_adressRespItem.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class mainboard_adressRespItem {
public String model_no;
public String function;
public Integer address;
public Integer quantity;
public String datatype;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/req.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class req {
public String access_token = "";
public String remotIp = "";
public String ip = "";
public Integer port = 0;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/resp.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
import java.util.List;
public class resp {
public String msg;
public Integer status;
public List results;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/update_modbus_valuesReq.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
import java.util.List;
public class update_modbus_valuesReq extends req {
public String mainboard_no;
public Long time_stamp;
public List items;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/update_modbus_valuesReqItem.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class update_modbus_valuesReqItem {
public String function;
public String address;
/**hex*/
public String value;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/update_slaveipportReq.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class update_slaveipportReq extends req {
public String mainboard_no;
public String ip;
public Integer port;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/repository/value.java
================================================
package com.github.zengfr.easymodbus4j.app.repository;
public class value {
public String hex;
public String bitset;
public String byteStr;
public String shortStr;
public String longb;
public String floatb;
public String doubleb;
public String charb;
public String longl;
public String floatl;
public String doublel;
public String charl;
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/sender/UdpSender.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.app.sender;
import java.net.InetSocketAddress;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
public class UdpSender {
protected Channel channel;
public UdpSender(Channel channel) {
this.channel = channel;
}
public void send(DatagramPacket packet) throws InterruptedException {
channel.writeAndFlush(packet).sync();
}
public void send(String host, int port, String msg) throws InterruptedException {
send(new InetSocketAddress(host, port), msg);
}
public void send(InetSocketAddress address, String msg) throws InterruptedException {
send(address, Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
}
public void send(String host, int port, ByteBuf byteBuf) throws InterruptedException {
send(new InetSocketAddress(host, port), byteBuf);
}
public void send(InetSocketAddress address, ByteBuf byteBuf) throws InterruptedException {
send(new DatagramPacket(byteBuf, address));
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/sender/UdpSenderFactory.java
================================================
package com.github.zengfr.easymodbus4j.app.sender;
import java.util.Map;
import com.google.common.collect.Maps;
import io.netty.channel.Channel;
public class UdpSenderFactory {
private static class UdpSenderFactoryHolder {
private static final UdpSenderFactory INSTANCE = new UdpSenderFactory();
}
public static UdpSenderFactory getInstance() {
return UdpSenderFactoryHolder.INSTANCE;
}
private Map channelSendersMap = Maps.newHashMap();
public UdpSender get(Channel channel) {
String key = channel.toString();
if (!channelSendersMap.containsKey(key)) {
channelSendersMap.put(key, new UdpSender(channel));
}
return channelSendersMap.get(key);
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/java/com/github/zengfr/easymodbus4j/app/util/HttpUtil.java
================================================
package com.github.zengfr.easymodbus4j.app.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Created by zengfr on 2020/11/26.
*/
public class HttpUtil {
private static final CloseableHttpClient client ;
private final static String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0";
static {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(500);
connectionManager.setDefaultMaxPerRoute(255);
connectionManager.setValidateAfterInactivity(10000);
client = HttpClients.custom().setConnectionManager(connectionManager).build();
}
public static String get(String urlString, String referer, String origin, String charest) throws IOException {
HttpGet httpGet = new HttpGet(urlString);
return exec( httpGet, referer, origin, null, charest);
}
public static String post(String urlString, String referer, String origin, String data, String charest) throws IOException {
HttpPost post = new HttpPost(urlString);
return exec( post, referer, origin, data, charest);
}
protected static String exec( HttpRequestBase req, String referer, String origin, String data, String charest) throws IOException {
req.setHeader("User-Agent", userAgent);
req.setHeader("Referer", referer);
req.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + charest);
req.setHeader("Sec-Fetch-Dest", "empty");
req.setHeader("Sec-Fetch-Mode", "cors");
req.setHeader("Sec-Fetch-Site", "same-origin");
if (origin != null)
req.setHeader("Origin", origin);
if (data != null)
((HttpEntityEnclosingRequest)req).setEntity(new StringEntity(data));
CloseableHttpResponse resp = client.execute(req);
String content=getContent(resp, charest);
EntityUtils.consume(resp.getEntity());
resp.close();
return content;
}
public static String getContent(HttpResponse resp, String charest) throws IOException {
StringBuffer sb = new StringBuffer();
HttpEntity entity = resp.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent(), charest));
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
return sb.toString();
}
}
================================================
FILE: easymodbus4j-commandclient/src/main/resources/readme.txt
================================================
quick start
client api 1:
DeviceClient.sendCommand(String host, int port, DeviceCommand cmd);
client api 2(when functionCode:
WRITE_MULTIPLE_COILS = 0x0F;
WRITE_MULTIPLE_REGISTERS = 0x10;
DeviceClient.sendCommand2(String host, int port, DeviceCommand cmd);
public class DeviceCommand {
/** 设备标识id(必选) */
public String deviceId;
/** 设备ip(可选) */
public String ip;
/** 设备port(可选) */
public int port;
/** 设备型号(可选) */
public String version;
/** 见class FunctionCode */
public int functionCode;
/** 寄存器地址 */
public int address;
/** 寄存器地址值 */
public T value;
/** 寄存器地址值 */
public T[] values;
}
================================================
FILE: easymodbus4j-commandclient/src/test/java/ClientTest.java
================================================
import org.junit.BeforeClass;
import org.junit.Test;
import com.github.zengfr.easymodbus4j.app.client.DeviceClient;
import com.github.zengfr.easymodbus4j.app.client.UdpClientHandler;
import com.github.zengfr.easymodbus4j.app.common.DeviceCommand;
import com.github.zengfr.easymodbus4j.app.common.FunctionCode;
public class ClientTest {
static UdpClientHandler handler = new CustomUdpClientHandler();
static DeviceClient client = DeviceClient.getInstance();
@BeforeClass
public static void init() throws Exception {
client.setup(handler);
}
@Test
public void test() throws Exception {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println(i);
Thread.sleep(111);
for (int j = 0; j < 111; j++) {
DeviceCommand cmd = new DeviceCommand<>();
cmd.setIp("11.22.33.44");
cmd.setPort(4199);
cmd.setAddress(1);
cmd.setFunctionCode(FunctionCode.WRITE_MULTIPLE_REGISTERS);
cmd.setValue(Float.valueOf("12.6"));
client.sendCommand("192.168.77.88", 54321, cmd);
}
}
}
}
================================================
FILE: easymodbus4j-commandclient/src/test/java/CustomUdpClientHandler.java
================================================
import com.github.zengfr.easymodbus4j.app.client.UdpClientHandler;
public class CustomUdpClientHandler extends UdpClientHandler {
@Override
protected void channelRead0(String uuid, String deviceId, String ip, Integer port, String version,
Integer functionCode, Integer address, String valueType, String value, String[] values, int success)
throws Exception {
}
@Override
protected boolean isDoReceived() {
return false;
}
}
================================================
FILE: easymodbus4j-example/pom.xml
================================================
4.0.0com.github.zengfreasymodbus4j-example0.0.5easymodbus4j-examplefalsecom.github.zengfr.projectparent0.0.2../parent/pom.xmleasymodbus4j-clientcom.github.zengfr0.0.5easymodbus4j-servercom.github.zengfr0.0.5easymodbus4j-extensioncom.github.zengfr0.0.5net.logstash.logbacklogstash-logback-encoder6.2org.apache.maven.pluginsmaven-jar-plugin1.81.8com.github.zengfr.easymodbus4j.main.Exampletruelibs/org.apache.maven.pluginsmaven-compiler-plugin1.81.8UTF-8false
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/ModbusConfig.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.example;
import com.alibaba.fastjson.JSON;
import com.github.zengfr.easymodbus4j.ModbusConsts;
import com.github.zengfr.easymodbus4j.common.util.ParseStringUtil;
import com.github.zengfr.easymodbus4j.ModbusConfs;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ModbusConfig {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ModbusConfig.class);
public int type;
public String host;
public int port;
public boolean showDebugLog;
public boolean autoSend;
public int idleTimeOut;
public int sleep;
public short unit_IDENTIFIER;
public short transactionIdentifierOffset;
public int ignoreLengthThreshold;
public String heartbeat;
public int scheduleFixedDelay;
public int udpPort;
public static ModbusConfig parse(String[] argsArray) {
ModbusConfig cfg = new ModbusConfig();
cfg.type = ParseStringUtil.parseInt(argsArray, 0, 0);
cfg.host = ParseStringUtil.parseString(argsArray, 1, ModbusConsts.DEFAULT_HOTST_IP);
cfg.port = ParseStringUtil.parseInt(argsArray, 2, ModbusConfs.DEFAULT_MODBUS_PORT);
cfg.unit_IDENTIFIER = ParseStringUtil.parseShort(argsArray, 3, ModbusConsts.DEFAULT_UNIT_IDENTIFIER);
cfg.transactionIdentifierOffset = ParseStringUtil.parseShort(argsArray, 4, (short) 0);
cfg.showDebugLog = ParseStringUtil.parseBoolean(argsArray, 5, true);
cfg.idleTimeOut = ParseStringUtil.parseInt(argsArray, 6, ModbusConfs.IDLE_TIMEOUT_SECOND);
cfg.autoSend = ParseStringUtil.parseBoolean(argsArray, 7, true);
cfg.sleep = ParseStringUtil.parseInt(argsArray, 8, 1000 * 15);
cfg.heartbeat = ParseStringUtil.parseString(argsArray, 9, ModbusConsts.HEARTBEAT);
cfg.ignoreLengthThreshold = ParseStringUtil.parseInt(argsArray, 10, ModbusConfs.RESPONS_EFRAME_IGNORE_LENGTH_THRESHOLD);
cfg.udpPort = ParseStringUtil.parseInt(argsArray, 11, ModbusConfs.DEFAULT_MODBUS_PORT5);
logger.info(JSON.toJSONString(cfg));
return cfg;
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/ModbusConsoleApp.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.example;
import java.util.Collection;
import io.netty.channel.Channel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import com.github.zengfr.easymodbus4j.ModbusConsts;
import com.github.zengfr.easymodbus4j.common.util.ConsoleUtil;
import com.github.zengfr.easymodbus4j.common.util.ScheduledUtil;
import com.github.zengfr.easymodbus4j.ModbusConfs;
import com.github.zengfr.easymodbus4j.processor.ModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.processor.ModbusSlaveRequestProcessor;
import com.github.zengfr.easymodbus4j.example.processor.ExampleModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.example.processor.ExampleModbusSlaveRequestProcessor;
import com.github.zengfr.easymodbus4j.example.schedule.ModbusMasterSchedule4ConfigFile;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ModbusConsoleApp {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ModbusConsoleApp.class);
public static void initAndStart(String[] argsArray) throws Exception {
ModbusConfig config = ModbusConfig.parse(argsArray);
start(config);
}
public static void start(ModbusConfig cfg) throws Exception {
ModbusConsts.DEFAULT_UNIT_IDENTIFIER = cfg.unit_IDENTIFIER;
ModbusConsts.HEARTBEAT=cfg.heartbeat;
ModbusConfs.MASTER_SHOW_DEBUG_LOG = cfg.showDebugLog;
ModbusConfs.SLAVE_SHOW_DEBUG_LOG = cfg.showDebugLog;
ModbusConfs.IDLE_TIMEOUT_SECOND = cfg.idleTimeOut;
ModbusConfs.RESPONS_EFRAME_IGNORE_LENGTH_THRESHOLD= cfg.ignoreLengthThreshold;
ModbusMasterResponseProcessor masterProcessor = new ExampleModbusMasterResponseProcessor(cfg.transactionIdentifierOffset);
ModbusSlaveRequestProcessor slaveProcessor = new ExampleModbusSlaveRequestProcessor(cfg.transactionIdentifierOffset);
ModbusSetup setup = new ModbusSetup();
setup.initProperties();
setup.initHandler(masterProcessor, slaveProcessor);
int port = cfg.port;
boolean autoSend = cfg.autoSend;
String host = cfg.host;
int sleep = cfg.sleep;
switch (cfg.type) {
case 6:
setup.setupServer4RtuMaster(port);
sendRequests4Auto(autoSend, sleep, setup.getModbusServer().getChannels());
break;
case 7:
setup.setupClient4RtuSlave(host, port);
break;
case 8:
setup.setupClient4RtuMaster(host, port);
sendRequests4Auto(autoSend, sleep, setup.getModbusClient().getChannels());
break;
case 9:
setup.setupServer4RtuSlave(port);
break;
case 5:
ModbusConfs.SLAVE_SHOW_DEBUG_LOG = false;
setup.setupServer4RtuMaster(port);
setup.setupClient4RtuSlave(host, port);
sendRequests4Auto(autoSend, sleep, setup.getModbusServer().getChannels());
break;
case 1:
setup.setupServer4TcpMaster(port);
sendRequests4Auto(autoSend, sleep, setup.getModbusServer().getChannels());
break;
case 2:
setup.setupClient4TcpSlave(host, port);
break;
case 3:
setup.setupClient4TcpMaster(host, port);
sendRequests4Auto(autoSend, sleep, setup.getModbusClient().getChannels());
break;
case 4:
setup.setupServer4TcpSlave(port);
break;
default:
ModbusConfs.SLAVE_SHOW_DEBUG_LOG = false;
setup.setupServer4TcpMaster(port);
setup.setupClient4TcpSlave(host, port);
sendRequests4Auto(autoSend, sleep, setup.getModbusServer().getChannels());
break;
}
Runnable runnable = () -> ConsoleUtil.clearConsole(true);
ScheduledUtil.getInstance().scheduleAtFixedRate(runnable, sleep * 5);
}
protected static void sendRequests4Auto(boolean autoSend, int sleep, Collection channels) throws InterruptedException {
if (autoSend) {
ModbusMasterSchedule4ConfigFile modbusMasterAutoSender4ConfigFile = new ModbusMasterSchedule4ConfigFile();
modbusMasterAutoSender4ConfigFile.schedule(channels, sleep);
}
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/ModbusSetup.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.example;
import com.github.zengfr.easymodbus4j.client.ModbusClient;
import com.github.zengfr.easymodbus4j.client.ModbusClientRtuFactory;
import com.github.zengfr.easymodbus4j.client.ModbusClientTcpFactory;
import com.github.zengfr.easymodbus4j.handle.impl.ModbusMasterResponseHandler;
import com.github.zengfr.easymodbus4j.handle.impl.ModbusSlaveRequestHandler;
import com.github.zengfr.easymodbus4j.handler.ModbusRequestHandler;
import com.github.zengfr.easymodbus4j.handler.ModbusResponseHandler;
import com.github.zengfr.easymodbus4j.processor.ModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.processor.ModbusSlaveRequestProcessor;
import com.github.zengfr.easymodbus4j.server.ModbusServer;
import com.github.zengfr.easymodbus4j.server.ModbusServerRtuFactory;
import com.github.zengfr.easymodbus4j.server.ModbusServerTcpFactory;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.internal.logging.Slf4JLoggerFactory;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ModbusSetup {
private static final int sleep = 1000;
private ModbusClient modbusClient;
private ModbusServer modbusServer;
private ModbusRequestHandler requestHandler;
private ModbusResponseHandler responseHandler;
public ModbusSetup() {
}
public ModbusClient getModbusClient() {
return this.modbusClient;
}
public ModbusServer getModbusServer() {
return this.modbusServer;
}
public void initProperties() throws Exception {
InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE);
System.setProperty("io.netty.tryReflectionSetAccessible", "true");
// System.setProperty("io.netty.noUnsafe", "false");
// ReferenceCountUtil.release(byteBuf);
// ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
}
public void initHandler(ModbusResponseHandler responseHandler, ModbusRequestHandler requestHandler) throws Exception {
this.requestHandler = requestHandler;
this.responseHandler = responseHandler;
}
public void initHandler(ModbusMasterResponseProcessor masterProcessor, ModbusSlaveRequestProcessor slaveProcessor) throws Exception {
this.requestHandler = new ModbusSlaveRequestHandler(slaveProcessor);
this.responseHandler = new ModbusMasterResponseHandler(masterProcessor);
}
public void setupServer4TcpMaster(int port) throws Exception {
modbusServer = ModbusServerTcpFactory.getInstance().createServer4Master(port, responseHandler);
}
public void setupServer4TcpSlave(int port) throws Exception {
modbusServer = ModbusServerTcpFactory.getInstance().createServer4Slave(port, requestHandler);
}
public void setupClient4TcpSlave(String host, int port) throws Exception {
Thread.sleep(sleep);
modbusClient = ModbusClientTcpFactory.getInstance().createClient4Slave(host, port, requestHandler);
}
public void setupClient4TcpMaster(String host, int port) throws Exception {
Thread.sleep(sleep);
modbusClient = ModbusClientTcpFactory.getInstance().createClient4Master(host, port, responseHandler);
}
public void setupServer4RtuMaster(int port) throws Exception {
modbusServer = ModbusServerRtuFactory.getInstance().createServer4Master(port, responseHandler);
}
public void setupServer4RtuSlave(int port) throws Exception {
modbusServer = ModbusServerRtuFactory.getInstance().createServer4Slave(port, requestHandler);
}
public void setupClient4RtuSlave(String host, int port) throws Exception {
Thread.sleep(sleep);
modbusClient = ModbusClientRtuFactory.getInstance().createClient4Slave(host, port, requestHandler);
}
public void setupClient4RtuMaster(String host, int port) throws Exception {
Thread.sleep(sleep);
modbusClient = ModbusClientRtuFactory.getInstance().createClient4Master(host, port, responseHandler);
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/processor/ExampleModbusMasterResponseProcessor.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/package com.github.zengfr.easymodbus4j.example.processor;
import com.github.zengfr.easymodbus4j.func.AbstractRequest;
import com.github.zengfr.easymodbus4j.func.request.ReadCoilsRequest;
import com.github.zengfr.easymodbus4j.func.request.ReadDiscreteInputsRequest;
import com.github.zengfr.easymodbus4j.func.response.ReadCoilsResponse;
import com.github.zengfr.easymodbus4j.func.response.ReadDiscreteInputsResponse;
import com.github.zengfr.easymodbus4j.handle.impl.ModbusMasterResponseHandler;
import com.github.zengfr.easymodbus4j.processor.AbstractModbusProcessor;
import com.github.zengfr.easymodbus4j.processor.ModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.protocol.ModbusFunction;
import com.github.zengfr.easymodbus4j.util.ModbusFunctionUtil;
import io.netty.channel.Channel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ExampleModbusMasterResponseProcessor extends AbstractModbusProcessor implements ModbusMasterResponseProcessor {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ExampleModbusMasterResponseProcessor.class);
public ExampleModbusMasterResponseProcessor(short transactionIdentifierOffset) {
super(transactionIdentifierOffset, true);
}
public boolean processResponseFrame(Channel channel, int unitId, AbstractRequest reqFunc, ModbusFunction respFunc) {
boolean success=this.isRequestResponseMatch(reqFunc, respFunc);
if (respFunc instanceof ReadCoilsResponse) {
ReadCoilsResponse resp = (ReadCoilsResponse) respFunc;
if (reqFunc instanceof ReadCoilsRequest) {
ReadCoilsRequest req = (ReadCoilsRequest) reqFunc;
// process business logic
success=true;
}
}
if (respFunc instanceof ReadDiscreteInputsResponse) {
ReadDiscreteInputsResponse resp = (ReadDiscreteInputsResponse) respFunc;
byte[] resutArray = resp.getInputStatus().toByteArray();
byte[] valuesArray = ModbusFunctionUtil.getFunctionValues(respFunc);
if (reqFunc instanceof ReadDiscreteInputsRequest) {
ReadDiscreteInputsRequest req = (ReadDiscreteInputsRequest) reqFunc;
// process business logic
success=true;
}
}
logger.debug(String.format("success:%s", success));
return success;
};
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/processor/ExampleModbusSlaveRequestProcessor.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.example.processor;
import java.util.BitSet;
import java.util.Random;
import com.github.zengfr.easymodbus4j.common.util.BitSetUtil;
import com.github.zengfr.easymodbus4j.common.util.RegistersUtil;
import com.github.zengfr.easymodbus4j.func.request.ReadCoilsRequest;
import com.github.zengfr.easymodbus4j.func.request.ReadDiscreteInputsRequest;
import com.github.zengfr.easymodbus4j.func.request.ReadHoldingRegistersRequest;
import com.github.zengfr.easymodbus4j.func.request.ReadInputRegistersRequest;
import com.github.zengfr.easymodbus4j.func.request.WriteMultipleCoilsRequest;
import com.github.zengfr.easymodbus4j.func.request.WriteMultipleRegistersRequest;
import com.github.zengfr.easymodbus4j.func.request.WriteSingleCoilRequest;
import com.github.zengfr.easymodbus4j.func.request.WriteSingleRegisterRequest;
import com.github.zengfr.easymodbus4j.func.response.ReadCoilsResponse;
import com.github.zengfr.easymodbus4j.func.response.ReadDiscreteInputsResponse;
import com.github.zengfr.easymodbus4j.func.response.ReadHoldingRegistersResponse;
import com.github.zengfr.easymodbus4j.func.response.ReadInputRegistersResponse;
import com.github.zengfr.easymodbus4j.func.response.WriteMultipleCoilsResponse;
import com.github.zengfr.easymodbus4j.func.response.WriteMultipleRegistersResponse;
import com.github.zengfr.easymodbus4j.func.response.WriteSingleCoilResponse;
import com.github.zengfr.easymodbus4j.func.response.WriteSingleRegisterResponse;
import com.github.zengfr.easymodbus4j.processor.AbstractModbusProcessor;
import com.github.zengfr.easymodbus4j.processor.ModbusSlaveRequestProcessor;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ExampleModbusSlaveRequestProcessor extends AbstractModbusProcessor implements ModbusSlaveRequestProcessor {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ExampleModbusSlaveRequestProcessor.class);
protected static Random random = new Random();
public ExampleModbusSlaveRequestProcessor(short transactionIdentifierOffset) {
super(transactionIdentifierOffset, true);
}
@Override
public WriteSingleCoilResponse writeSingleCoil(short unitIdentifier, WriteSingleCoilRequest request) {
return new WriteSingleCoilResponse(request.getOutputAddress(), request.isState());
}
@Override
public WriteSingleRegisterResponse writeSingleRegister(short unitIdentifier, WriteSingleRegisterRequest request) {
return new WriteSingleRegisterResponse(request.getRegisterAddress(), request.getRegisterValue());
}
@Override
public ReadCoilsResponse readCoils(short unitIdentifier, ReadCoilsRequest request) {
BitSet coils = new BitSet(request.getQuantityOfCoils());
coils = BitSetUtil.getRandomBits(request.getQuantityOfCoils(), random);
if (coils.size() > 0 && random.nextInt(99) < 66)
coils.set(0, false);
return new ReadCoilsResponse(coils);
}
@Override
public ReadDiscreteInputsResponse readDiscreteInputs(short unitIdentifier, ReadDiscreteInputsRequest request) {
BitSet coils = new BitSet(request.getQuantityOfCoils());
coils = BitSetUtil.getRandomBits(request.getQuantityOfCoils(), random);
//coils.set(0,79,false);
//coils.set(0,true);
return new ReadDiscreteInputsResponse(coils);
}
@Override
public ReadInputRegistersResponse readInputRegisters(short unitIdentifier, ReadInputRegistersRequest request) {
int[] registers = new int[request.getQuantityOfInputRegisters()];
registers = RegistersUtil.getRandomRegisters(registers.length, 1, 1024, random);
return new ReadInputRegistersResponse(registers);
}
@Override
public ReadHoldingRegistersResponse readHoldingRegisters(short unitIdentifier, ReadHoldingRegistersRequest request) {
int[] registers = new int[request.getQuantityOfInputRegisters()];
registers = RegistersUtil.getRandomRegisters(registers.length, 1, 1024, random);
// RegistersFactory.getInstance().getOrInit(unitIdentifier).getHoldingRegister(request.getStartingAddress());
return new ReadHoldingRegistersResponse(registers);
}
@Override
public WriteMultipleCoilsResponse writeMultipleCoils(short unitIdentifier, WriteMultipleCoilsRequest request) {
return new WriteMultipleCoilsResponse(request.getStartingAddress(), request.getQuantityOfOutputs());
}
@Override
public WriteMultipleRegistersResponse writeMultipleRegisters(short unitIdentifier, WriteMultipleRegistersRequest request) {
// RegistersFactory.getInstance().getOrInit(unitIdentifier).setHoldingRegister(request.getStartingAddress(),
// request.getRegisters());
return new WriteMultipleRegistersResponse(request.getStartingAddress(), request.getQuantityOfRegisters());
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example/schedule/ModbusMasterSchedule4ConfigFile.java
================================================
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.zengfr.easymodbus4j.example.schedule;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.zengfr.easymodbus4j.common.util.FileUtil;
import com.github.zengfr.easymodbus4j.common.util.InputStreamUtil;
import com.github.zengfr.easymodbus4j.schedule.ModbusMasterSchedule;
import com.github.zengfr.easymodbus4j.sender.util.ModbusRequestSendUtil.PriorityStrategy;
import com.google.common.collect.Lists;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class ModbusMasterSchedule4ConfigFile extends ModbusMasterSchedule {
private static Logger logger = LoggerFactory
.getLogger(ModbusMasterSchedule4ConfigFile.class.getSimpleName());
protected static String configFileName = "autoSend.txt";
@Override
protected int getFixedDelay() {
return 0;
}
@Override
protected PriorityStrategy getPriorityStrategy() {
return PriorityStrategy.Channel;
}
@Override
protected Logger getLogger() {
return logger;
}
@Override
protected List buildReqsList() {
return parseReqs();
}
protected static List parseReqs() {
List configStrings = readConfig("/" + configFileName);
List reqStrings = parseReqs(configStrings);
return reqStrings;
}
protected static List parseReqs(List configStrings) {
List reqStrings = Lists.newArrayList(configStrings);
if (!configStrings.isEmpty()) {
reqStrings.remove(0);
}
return reqStrings;
}
protected static List readConfig(String fileName) {
logger.info("readConfig:" + fileName);
List strList = Lists.newArrayList();
try {
InputStream input = InputStreamUtil.getStream(fileName);
if (input != null)
strList = FileUtil.readLines(input, StandardCharsets.UTF_8);
} catch (IOException ex) {
logger.error("readConfig:" + fileName + " ex:", ex);
}
return strList;
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3/Example3.java
================================================
package com.github.zengfr.easymodbus4j.example3;
import com.github.zengfr.easymodbus4j.ModbusConfs;
import com.github.zengfr.easymodbus4j.client.ModbusClient4TcpMaster;
import com.github.zengfr.easymodbus4j.client.ModbusClientTcpFactory;
import com.github.zengfr.easymodbus4j.common.util.ConsoleUtil;
import com.github.zengfr.easymodbus4j.common.util.ScheduledUtil;
import com.github.zengfr.easymodbus4j.example.processor.ExampleModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.handle.impl.ModbusMasterResponseHandler;
import com.github.zengfr.easymodbus4j.handler.ModbusResponseHandler;
import com.github.zengfr.easymodbus4j.processor.ModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.sender.ChannelSender;
import com.github.zengfr.easymodbus4j.sender.ChannelSenderFactory;
import io.netty.channel.Channel;
public class Example3 {
private static ModbusClient4TcpMaster modbusClient;
public static void main(String[] args) throws Exception {
initClient();
scheduleToSendData();
//1\ ChannelSender to send data to machine
//2\ ExampleModbusMasterResponseProcessor to receive resp data.
}
private static void initClient() throws Exception {
String host="123.145.167.189";
int port=502;
long sleep=3000;
short transactionIdentifierOffset=0;
ModbusConfs.MASTER_SHOW_DEBUG_LOG = true;
ModbusMasterResponseProcessor masterProcessor=new ExampleModbusMasterResponseProcessor(transactionIdentifierOffset);
ModbusResponseHandler responseHandler = new ModbusMasterResponseHandler(masterProcessor);;
modbusClient = ModbusClientTcpFactory.getInstance().createClient4Master(host, port, responseHandler);
Thread.sleep(sleep);
}
private static void scheduleToSendData() {
Runnable runnable = () ->{
ConsoleUtil.clearConsole(true);
Channel channel = modbusClient.getChannel();
if(channel==null||(!channel.isActive())||!channel.isOpen()||!channel.isWritable())
return;
ChannelSender sender = ChannelSenderFactory.getInstance().get(channel);
//short unitIdentifier=1;
//ChannelSender sender2 =new ChannelSender(channel, unitIdentifier);
int startAddress=0;
int quantityOfCoils=4;
try {
sender.readCoilsAsync(startAddress, quantityOfCoils);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
int sleep=1000;
ScheduledUtil.getInstance().scheduleAtFixedRate(runnable, sleep * 5);
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/example3/Example4.java
================================================
package com.github.zengfr.easymodbus4j.example3;
import java.util.Collection;
import com.github.zengfr.easymodbus4j.ModbusConfs;
import com.github.zengfr.easymodbus4j.common.util.ConsoleUtil;
import com.github.zengfr.easymodbus4j.common.util.ScheduledUtil;
import com.github.zengfr.easymodbus4j.example.processor.ExampleModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.handle.impl.ModbusMasterResponseHandler;
import com.github.zengfr.easymodbus4j.handler.ModbusResponseHandler;
import com.github.zengfr.easymodbus4j.processor.ModbusMasterResponseProcessor;
import com.github.zengfr.easymodbus4j.sender.ChannelSender;
import com.github.zengfr.easymodbus4j.sender.ChannelSenderFactory;
import com.github.zengfr.easymodbus4j.server.ModbusServer4TcpMaster;
import com.github.zengfr.easymodbus4j.server.ModbusServerTcpFactory;
import io.netty.channel.Channel;
public class Example4 {
private static ModbusServer4TcpMaster modbusServer;
public static void main(String[] args) throws Exception {
initServer();
scheduleToSendData();
// 1\ ChannelSender to send data to machine
// 2\ ExampleModbusMasterResponseProcessor to receive resp data.
}
private static void initServer() throws Exception {
int port = 502;
long sleep = 3000;
short transactionIdentifierOffset = 0;
ModbusConfs.MASTER_SHOW_DEBUG_LOG = true;
ModbusMasterResponseProcessor masterProcessor = new ExampleModbusMasterResponseProcessor(
transactionIdentifierOffset);
ModbusResponseHandler responseHandler = new ModbusMasterResponseHandler(masterProcessor);
;
modbusServer = ModbusServerTcpFactory.getInstance().createServer4Master(port, responseHandler);
Thread.sleep(sleep);
}
private static void scheduleToSendData() {
Runnable runnable = () -> {
ConsoleUtil.clearConsole(true);
Collection channels = modbusServer.getChannels();
for (Channel channel : channels) {
if (channel == null || (!channel.isActive()) || !channel.isOpen() || !channel.isWritable())
return;
ChannelSender sender = ChannelSenderFactory.getInstance().get(channel);
// short unitIdentifier=1;
// ChannelSender sender2 =new ChannelSender(channel, unitIdentifier);
int startAddress = 0;
int quantityOfCoils = 4;
try {
sender.readCoilsAsync(startAddress, quantityOfCoils);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
int sleep = 1000;
ScheduledUtil.getInstance().scheduleAtFixedRate(runnable, sleep * 5);
}
}
================================================
FILE: easymodbus4j-example/src/main/java/com/github/zengfr/easymodbus4j/main/Example.java
================================================
package com.github.zengfr.easymodbus4j.main;
import com.github.zengfr.easymodbus4j.example.ModbusConsoleApp;
/**
* @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
* https://github.com/zengfr/easymodbus4j
*/
public class Example {
public static void main(String[] args) throws Exception {
if (args == null || args.length <= 0)
args = new String[] { "" };
String[] argsArray = args[0].split("[,;|]");
ModbusConsoleApp.initAndStart(argsArray);
}
}
================================================
FILE: easymodbus4j-example/src/main/resources/autoSend.txt
================================================
#function|address|values|#function autoSend every time for sleep time end when autoSend=T
readCoilsAsync|81|1
readHoldingRegistersAsync|33|17
readInputRegisters|49|18
readDiscreteInputs|65|16
writeSingleCoil|17|F
writeSingleRegister|18|22
writeMultipleCoils|25|T,F,T,F,T,T
writeMultipleRegisters|24|1,3,5,7,14
#writeSingleCoil|19|T
#writeSingleRegister|97|33
================================================
FILE: easymodbus4j-example/src/main/resources/logback.xml
================================================
%d{HH:mm:ss.SSS}|%-5level|%thread|%logger{64}-%msg%n
127.0.0.14561true127.0.0.17071channeldefaultDEBUGlog/debug-%d{yyyy-MM-dd}-%i-${channel}.log
20MB312GBtrue%d{HH:mm:ss.SSS}|%-5level|%thread|%logger{64}-%msg%n
channeldefaultINFOACCEPTDENYlog/info-%d{yyyy-MM-dd}-%i-${channel}.log
20MB312GBtrue%d{HH:mm:ss.SSS}|%-5level|%thread|%logger{64}-%msg%n
channeldefaultWARNlog/warn-%d{yyyy-MM-dd}-%i-${channel}.log
20MB31%d{HH:mm:ss.SSS}|%-5level|%thread|%logger{64}-%msg%n
0512true0512true0512true
================================================
FILE: easymodbus4j-example/src/main/resources/readme.txt
================================================

# easymodbus4j
easymodbus4j是一个高性能和易用的 Modbus 协议的 Java 实现,基于 Netty 开发,可用于 Modbus协议的Java客户端和服务器开发.
easymodbus4j
A high-performance and ease-of-use implementation of the Modbus protocol written in Java netty support for modbus 8 mode client/server and master/slave.