|
@@ -0,0 +1,264 @@
|
|
|
+/**
|
|
|
+ * Copyright (C), 2022-05-23
|
|
|
+ * FileName: ModbusTaxk
|
|
|
+ * Author: wanglongda
|
|
|
+ * Date: 2022/5/23 17:14
|
|
|
+ * Description: modbus定时任务
|
|
|
+ */
|
|
|
+package me.zhengjie.modules.quartz.task;/**
|
|
|
+ * Created Name: wanglongda
|
|
|
+ * Created Time: 2022/5/23 17:14
|
|
|
+ * Description: iot-ykt
|
|
|
+ */
|
|
|
+
|
|
|
+import com.digitalpetri.modbus.codec.Modbus;
|
|
|
+import com.digitalpetri.modbus.master.ModbusTcpMaster;
|
|
|
+import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
|
|
|
+import com.digitalpetri.modbus.requests.ReadCoilsRequest;
|
|
|
+import com.digitalpetri.modbus.requests.ReadDiscreteInputsRequest;
|
|
|
+import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
|
|
|
+import com.digitalpetri.modbus.requests.ReadInputRegistersRequest;
|
|
|
+import com.digitalpetri.modbus.responses.ReadCoilsResponse;
|
|
|
+import com.digitalpetri.modbus.responses.ReadDiscreteInputsResponse;
|
|
|
+import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
|
|
|
+import com.digitalpetri.modbus.responses.ReadInputRegistersResponse;
|
|
|
+import io.netty.buffer.ByteBuf;
|
|
|
+import io.netty.util.ReferenceCountUtil;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import me.zhengjie.modules.dm.modbus.channel.domain.DmModbusChannel;
|
|
|
+import me.zhengjie.modules.dm.modbus.data.domain.DmModbusData;
|
|
|
+import me.zhengjie.modules.dm.modbus.device.domain.DmModbusDevice;
|
|
|
+import me.zhengjie.modules.dm.modbus.drive.domain.DmModbusDrive;
|
|
|
+import me.zhengjie.modules.dm.modbus.drive.service.DmModbusDriveService;
|
|
|
+import me.zhengjie.modules.dm.modbus.drive.service.dto.DmModbusDriveDto;
|
|
|
+import me.zhengjie.modules.dm.modbus.group.domain.DmModbusGroup;
|
|
|
+import me.zhengjie.modules.system.repository.UserRepository;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.bind.annotation.InitBinder;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import javax.annotation.PreDestroy;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <功能简要> <br>
|
|
|
+ * <modbus定时任务>
|
|
|
+ *
|
|
|
+ * @Author wanglongda
|
|
|
+ * @createTime 2022/5/23 17:14
|
|
|
+ * @Version 1.0.0
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class ModbusTask {
|
|
|
+
|
|
|
+ private final DmModbusDriveService dmModbusDriveService;
|
|
|
+ @Value("${modbusUrl}")
|
|
|
+ private String modbusUrl; // modbus默认地址
|
|
|
+ private final int modbusPort = 502; // modbus默认端口号
|
|
|
+ private final int modbusSalveId = 1; //modbus默认从机地址
|
|
|
+ private static ModbusTcpMaster master;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取TCP协议的Master
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ if (master == null) {
|
|
|
+ // 创建配置
|
|
|
+ ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder(modbusUrl).setPort(modbusPort).build();
|
|
|
+ master = new ModbusTcpMaster(config);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void gainModbusData(){
|
|
|
+
|
|
|
+ try {
|
|
|
+ /**
|
|
|
+ * 根据sql查询所有总集合
|
|
|
+ */
|
|
|
+ List<DmModbusDriveDto> dmModbusDriveDtos = dmModbusDriveService.queryAll(null);
|
|
|
+ //进行遍历
|
|
|
+ dmModbusDriveDtos.forEach(drive->{
|
|
|
+ /**
|
|
|
+ * 获取所有的信道集合 channels.size>0 进行遍历
|
|
|
+ */
|
|
|
+ Set<DmModbusChannel> channels = drive.getChannels();
|
|
|
+ if (!channels.isEmpty()){
|
|
|
+ channels.forEach(channel->{
|
|
|
+ /**
|
|
|
+ * 获取信道下的所有设备集合 dmModbusDevice.size>0 进行遍历
|
|
|
+ */
|
|
|
+ Set<DmModbusDevice> dmModbusDevice = channel.getDmModbusDevice();
|
|
|
+ if (!dmModbusDevice.isEmpty()){
|
|
|
+ dmModbusDevice.forEach(device->{
|
|
|
+ /**
|
|
|
+ * 获取设备下的所有分组 dmModbusGroup.size>0 进行遍历
|
|
|
+ */
|
|
|
+ Set<DmModbusGroup> dmModbusGroup = device.getDmModbusGroup();
|
|
|
+ if (!dmModbusGroup.isEmpty()){
|
|
|
+ dmModbusGroup.forEach(group->{
|
|
|
+ /**
|
|
|
+ * 获取分组下的所有所有数据 dmModbusData.size>0 进行遍历
|
|
|
+ */
|
|
|
+ List<DmModbusData> dmModbusData = group.getDmModbusData();
|
|
|
+ if (!dmModbusData.isEmpty()){
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ log.info(dmModbusDriveDtos.toString());
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("modbus获取失败,失败原因:{}",e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /***
|
|
|
+ * 释放资源
|
|
|
+ */
|
|
|
+ @PreDestroy
|
|
|
+ public void release() {
|
|
|
+ if (master != null) {
|
|
|
+ master.disconnect();
|
|
|
+ }
|
|
|
+ Modbus.releaseSharedResources();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取Coils开关量
|
|
|
+ *
|
|
|
+ * @param address
|
|
|
+ * 寄存器开始地址
|
|
|
+ * @param quantity
|
|
|
+ * 数量
|
|
|
+ * @param unitId
|
|
|
+ * ID
|
|
|
+ * @return 读取值
|
|
|
+ * @throws InterruptedException
|
|
|
+ * 异常
|
|
|
+ * @throws ExecutionException
|
|
|
+ * 异常
|
|
|
+ */
|
|
|
+ public Boolean readCoils(int address, int quantity, int unitId)
|
|
|
+ throws InterruptedException, ExecutionException {
|
|
|
+ Boolean result = null;
|
|
|
+ CompletableFuture<ReadCoilsResponse> future = master.sendRequest(new ReadCoilsRequest(address, quantity),
|
|
|
+ unitId);
|
|
|
+ ReadCoilsResponse readCoilsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
|
|
|
+ if (readCoilsResponse != null) {
|
|
|
+ ByteBuf buf = readCoilsResponse.getCoilStatus();
|
|
|
+ result = buf.readBoolean();
|
|
|
+ ReferenceCountUtil.release(readCoilsResponse);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取readDiscreteInputs开关量
|
|
|
+ *
|
|
|
+ * @param address
|
|
|
+ * 寄存器开始地址
|
|
|
+ * @param quantity
|
|
|
+ * 数量
|
|
|
+ * @param unitId
|
|
|
+ * ID
|
|
|
+ * @return 读取值
|
|
|
+ * @throws InterruptedException
|
|
|
+ * 异常
|
|
|
+ * @throws ExecutionException
|
|
|
+ * 异常
|
|
|
+ */
|
|
|
+ public Boolean readDiscreteInputs(int address, int quantity, int unitId)
|
|
|
+ throws InterruptedException, ExecutionException {
|
|
|
+ Boolean result = null;
|
|
|
+ CompletableFuture<ReadDiscreteInputsResponse> future = master
|
|
|
+ .sendRequest(new ReadDiscreteInputsRequest(address, quantity), unitId);
|
|
|
+ ReadDiscreteInputsResponse discreteInputsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
|
|
|
+ if (discreteInputsResponse != null) {
|
|
|
+ ByteBuf buf = discreteInputsResponse.getInputStatus();
|
|
|
+ result = buf.readBoolean();
|
|
|
+ ReferenceCountUtil.release(discreteInputsResponse);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取HoldingRegister数据
|
|
|
+ *
|
|
|
+ * @param address
|
|
|
+ * 寄存器地址
|
|
|
+ * @param quantity
|
|
|
+ * 寄存器数量
|
|
|
+ * @param unitId
|
|
|
+ * id
|
|
|
+ * @return 读取结果
|
|
|
+ * @throws InterruptedException
|
|
|
+ * 异常
|
|
|
+ * @throws ExecutionException
|
|
|
+ * 异常
|
|
|
+ */
|
|
|
+ public static Number readHoldingRegisters(int address, int quantity, int unitId)
|
|
|
+ throws InterruptedException, ExecutionException {
|
|
|
+ Number result = null;
|
|
|
+ CompletableFuture<ReadHoldingRegistersResponse> future = master
|
|
|
+ .sendRequest(new ReadHoldingRegistersRequest(address, quantity), unitId);
|
|
|
+ ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
|
|
|
+ if (readHoldingRegistersResponse != null) {
|
|
|
+ ByteBuf buf = readHoldingRegistersResponse.getRegisters();
|
|
|
+ result = buf.readFloat();
|
|
|
+ ReferenceCountUtil.release(readHoldingRegistersResponse);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取InputRegisters模拟量数据
|
|
|
+ *
|
|
|
+ * @param address
|
|
|
+ * 寄存器开始地址
|
|
|
+ * @param quantity
|
|
|
+ * 数量
|
|
|
+ * @param unitId
|
|
|
+ * ID
|
|
|
+ * @return 读取值
|
|
|
+ * @throws InterruptedException
|
|
|
+ * 异常
|
|
|
+ * @throws ExecutionException
|
|
|
+ * 异常
|
|
|
+ */
|
|
|
+ public static Number readInputRegisters(int address, int quantity, int unitId)
|
|
|
+ throws InterruptedException, ExecutionException {
|
|
|
+ Number result = null;
|
|
|
+ CompletableFuture<ReadInputRegistersResponse> future = master
|
|
|
+ .sendRequest(new ReadInputRegistersRequest(address, quantity), unitId);
|
|
|
+ ReadInputRegistersResponse readInputRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
|
|
|
+ if (readInputRegistersResponse != null) {
|
|
|
+ ByteBuf buf = readInputRegistersResponse.getRegisters();
|
|
|
+ result = buf.readDouble();
|
|
|
+ ReferenceCountUtil.release(readInputRegistersResponse);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|