Commit 1c3cf716 authored by wanghao's avatar wanghao

1 使用 modbus4j + juc 实现 读取老化柜和老化层状态--测试中

parent 5179d8fe
package com.zehong.web.task;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.zehong.framework.modbus4j.Modbus4jUtils;
import com.zehong.system.domain.TEquipmentInfo;
import com.zehong.system.domain.modbus.ModbusDeviceData;
import com.zehong.system.service.ITEquipmentInfoService;
import com.zehong.web.controller.equipment.EquipmentDataCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
/**
* @author lenovo
* @date 2025/6/9
* @description 老化柜巡查 + 老化层断电检测
*/
@Component("agingCabinetInspectionAndPowerCheckTask")
public class AgingCabinetInspectionAndPowerCheckTask {
private static final Logger log = LoggerFactory.getLogger(AgingCabinetInspectionAndPowerCheckTask.class);
private final ExecutorService executor = Executors.newFixedThreadPool(10);
@Resource
private ITEquipmentInfoService tEquipmentInfoService;
/**
* 五分钟一次
* 1.老化柜、标定柜巡查
* 2.老化层断电
* 这种方式先注释掉
// for (TEquipmentInfo equipmentInfo : equipmentInfos) {
// Future<Map<Integer, Object>> future = executor.submit(new ModbusTcpTask(equipmentInfo, registerOffset));
// futures.add(future);
// }
// List<ModbusDeviceData> results = new ArrayList<>();
//
// for (int i = 0; i < futures.size(); i++) {
// Map<Integer, Object> data = futures.get(i).get();
// ModbusDeviceData deviceData = new ModbusDeviceData();
// deviceData.setDeviceId(equipmentInfos.get(i).getfEquipmentId().toString());
// deviceData.setRegisterValues(data.entrySet().stream()
// .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString())));
// results.add(deviceData);
// }
*/
public void ryCheck() {
List<String> type = new ArrayList<>();
type.add("1");
type.add("2");
List<TEquipmentInfo> equipmentInfos = tEquipmentInfoService.selectTEquipmentList(type);
try {
if (equipmentInfos.size() == 0) {
log.error("设备列表查询结果为空");
throw new Exception("无设备信息!");
}
// 10 层
// List<Integer> registerOffset = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
//
// List<CompletableFuture<ModbusDeviceData>> futures = equipmentInfos.stream().map(equipmentInfo -> CompletableFuture.supplyAsync(() -> {
// ModbusMaster master = null;
// try {
// master = Modbus4jUtils.getMaster(equipmentInfo.getfIp(), equipmentInfo.getfPort());
// Map<Integer, Object> integerObjectMap = Modbus4jUtils.batchReadAgingCabinet(master, registerOffset);
// // 构造结果对象
// ModbusDeviceData deviceData = new ModbusDeviceData();
// deviceData.setDeviceId(equipmentInfo.getfEquipmentId().toString());
// deviceData.setRegisterValues(integerObjectMap.entrySet().stream()
// .collect(Collectors.toMap(
// Map.Entry::getKey,
// e -> e.getValue() != null ? e.getValue().toString() : "NULL"
// )));
//
// return deviceData;
//
// } catch (ModbusInitException e) {
//
// // 初始化失败
// Map<Integer, String> errorMap = new HashMap<>();
//
// ModbusDeviceData deviceData = new ModbusDeviceData();
// deviceData.setDeviceId("");
// deviceData.setRegisterValues(errorMap);
//
// return deviceData;
// } catch (ModbusTransportException | ErrorResponseException e) {
// // 返回错误信息
// Map<Integer, String> errorMap = new HashMap<>();
// registerOffset.forEach(offset -> errorMap.put(offset, "ERROR: " + e.getMessage()));
//
// ModbusDeviceData deviceData = new ModbusDeviceData();
// deviceData.setDeviceId(equipmentInfo.getfEquipmentId().toString());
// deviceData.setRegisterValues(errorMap);
//
// return deviceData;
// } finally {
// if (master != null) {
// master.destroy();
// }
// }
// }, executor)).collect(Collectors.toList());
//
// // 等待所有任务完成并收集结果
// CompletableFuture<List<ModbusDeviceData>> listCompletableFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
// .thenApply(v -> futures.stream()
// .map(CompletableFuture::join)
// .collect(Collectors.toList()));
//
// DeferredResult<List<ModbusDeviceData>> deferredResult = new DeferredResult<>();
//
// listCompletableFuture.whenComplete((result, ex) -> {
// if (ex != null) {
// deferredResult.setErrorResult(Collections.singletonList(createErrorData(ex)));
// } else {
// deferredResult.setResult(result);
// }
// });
} catch (Exception e) {
e.printStackTrace();
}
}
private ModbusDeviceData createErrorData(Throwable ex) {
ModbusDeviceData errorData = new ModbusDeviceData();
errorData.setDeviceId("error");
errorData.setRegisterValues(Collections.singletonMap(0, "系统错误:" + ex.getMessage()));
return errorData;
}
}
......@@ -118,6 +118,12 @@
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- modbus4j-->
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
......
package com.zehong.framework.modbus4j;
import java.util.Map;
/**
* @author lenovo
* @date 2025/6/9
* @description TODO
*/
public class ModbusDeviceData {
private String deviceId;
private Map<Integer, String> registerValues; // key: 寄存器地址, value: 读取结果
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Map<Integer, String> getRegisterValues() {
return registerValues;
}
public void setRegisterValues(Map<Integer, String> registerValues) {
this.registerValues = registerValues;
}
}
package com.zehong.framework.modbus4j;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.zehong.system.domain.TEquipmentInfo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* @author lenovo
* @date 2025/6/9
* @description 读取数据多线程封装
*/
public class ModbusTcpTask implements Callable<Map<Integer, Object>> {
private final TEquipmentInfo equipmentInfo;
private final List<Integer> registerOffsets;
public ModbusTcpTask(TEquipmentInfo equipmentInfo, List<Integer> registerOffset) {
this.equipmentInfo = equipmentInfo;
this.registerOffsets = registerOffset;
}
@Override
public Map<Integer, Object> call(){
ModbusMaster master = null;
try {
master = Modbus4jUtils.getMaster(equipmentInfo.getfIp(), equipmentInfo.getfPort());
return Modbus4jUtils.batchReadAgingCabinet(master,registerOffsets);
} catch (ModbusInitException e) {
Map<Integer, Object> errorMap = new HashMap<>();
errorMap.put(1,-1);
return errorMap;
} catch (Exception e) {
Map<Integer, Object> errorMap = new HashMap<>();
registerOffsets.forEach(offset -> errorMap.put(offset, "ERROR: " + e.getMessage()));
return errorMap;
} finally {
if (master != null) {
master.destroy();
}
}
}
}
package com.zehong.system.domain.modbus;
import java.util.Map;
/**
* @author lenovo
* @date 2025/6/9
* @description TODO
*/
public class ModbusDeviceData {
private String deviceId;
private Map<Integer, String> registerValues; // key: 寄存器地址, value: 读取结果
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Map<Integer, String> getRegisterValues() {
return registerValues;
}
public void setRegisterValues(Map<Integer, String> registerValues) {
this.registerValues = registerValues;
}
}
package com.zehong.system.service;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.zehong.system.domain.TEquipmentInfo;
import com.zehong.system.domain.modbus.ModbusDeviceData;
/**
* 生产设备信息Service接口
......@@ -35,6 +38,8 @@ public interface ITEquipmentInfoService
*/
public List<TEquipmentInfo> selectTEquipmentList(List<String> types);
CompletableFuture<List<ModbusDeviceData>> readAllDevicesRegistersAsync(List<Integer> registerOffsets);
/**
* 新增生产设备信息
*
......
package com.zehong.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.zehong.system.domain.modbus.ModbusDeviceData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zehong.system.mapper.TEquipmentInfoMapper;
......@@ -102,4 +106,23 @@ public class TEquipmentInfoServiceImpl implements ITEquipmentInfoService
{
return tEquipmentInfoMapper.deleteTEquipmentInfoById(fEquipmentId);
}
/**
* 批量查询设备寄存器数据
*
* @param registerOffsets 设备寄存器地址
* @return 设备寄存器数据
*/
@Override
public CompletableFuture<List<ModbusDeviceData>> readAllDevicesRegistersAsync(List<Integer> registerOffsets) {
List<String> type = new ArrayList<>();
type.add("1");
type.add("2");
List<TEquipmentInfo> tEquipmentInfos = tEquipmentInfoMapper.selectTEquipmentList(type);
return null;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment