作者 钟来

优化终端bug

... ... @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig;
import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter;
import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite;
import com.zhonglai.luhui.device.modbus.terminal.modbus.ModbusMasterMessage;
import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.Message;
import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic;
import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService;
... ... @@ -30,16 +32,20 @@ public class PutTopic extends TopicFactoryAdapter {
JSONObject plcCommand = jsonObject.getJSONObject(key);
String id = key;
List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand);
Modbus4jWrite modbus4jWrite = null;
try {
new Modbus4jWrite(id).batchWrite(plcPoints,true);
modbus4jWrite = new Modbus4jWrite(id);
modbus4jWrite.batchWrite(plcPoints,true);
} catch (Exception e) {
if(null != modbus4jWrite)
{
ModbusMasterMessage.closeMaster(id); // 销毁旧连接
}
logger.error("写plc异常",e);
}
}
try {
JSONObject rJsonObject = new JSONObject();
rJsonObject.put("result",1);
mqttService.publish("PUT_REQ/"+topicDto.getTime(),rJsonObject.toJSONString());
mqttService.publish("PUT_REQ/"+topicDto.getTime(),JSONObject.toJSONString(new Message(1,"操作成功",jsonObject)));
} catch (MqttException e) {
logger.error("饭hi结果异常",e);
}
... ...
... ... @@ -5,6 +5,7 @@ import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig;
import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter;
import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jRead;
import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite;
import com.zhonglai.luhui.device.modbus.terminal.modbus.ModbusMasterMessage;
import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic;
import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService;
... ... @@ -33,11 +34,17 @@ public class ReadTopic extends TopicFactoryAdapter {
String plcCommand = jsonObject.getString(key);
String id = key;
List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand);
Modbus4jRead modbus4jRead = null;
try {
Map<String, Object> map = new Modbus4jRead(id).batchRead(plcPoints,true);
modbus4jRead = new Modbus4jRead(id);
Map<String, Object> map = modbus4jRead.batchRead(plcPoints,true);
rJsonObject.put(key, map);
} catch (Exception e) {
logger.error("读plc异常",e);
if(null != modbus4jRead)
{
ModbusMasterMessage.closeMaster(id); // 销毁旧连接
}
return;
}
}
... ...
... ... @@ -9,6 +9,9 @@ import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
import com.zhonglai.luhui.device.modbus.terminal.task.CollectPlcDataTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.HashMap;
... ... @@ -24,10 +27,12 @@ import java.util.Map;
*/
public class Modbus4jRead {
private ModbusMaster master;
private static final Logger logger = LoggerFactory.getLogger(Modbus4jRead.class);
private String id;
public Modbus4jRead(String id) throws Exception {
this.master = ModbusMasterMessage.createMaster(id);
this.id = id;
}
/**
... ... @@ -61,7 +66,13 @@ public class Modbus4jRead {
batch.setContiguousRequests(false);
// 发送批量请求
BatchResults<String> results = master.send(batch);
BatchResults<String> results = null;
try {
results = ModbusMasterMessage.getMaster( id).send(batch);
} catch (Exception e) {
logger.error("批量读取点位异常", e);
return null;
}
// 转换成 JSON 对象
Map<String, Object> jsonMap = new HashMap<>();
... ...
... ... @@ -30,11 +30,11 @@ import java.util.List;
*
*/
public class Modbus4jWrite {
static Log log = LogFactory.getLog(Modbus4jWrite.class);
private ModbusMaster master;
private static Log log = LogFactory.getLog(Modbus4jWrite.class);
private String id;
public Modbus4jWrite(String id) throws Exception {
this.master = ModbusMasterMessage.createMaster(id);
this.id = id;
}
... ... @@ -116,7 +116,12 @@ public class Modbus4jWrite {
}
// 设置值
master.setValue(locator, value);
try {
ModbusMasterMessage.getMaster(id).setValue(locator, value);
} catch (Exception e) {
log.error("写入失败",e);
return;
}
log.info("写入成功: " + point.getName() + " = " + point.getValue());
}
... ... @@ -129,11 +134,4 @@ public class Modbus4jWrite {
writePoint(plcPoint, zeroBasedAddress);
}
}
public boolean isConnected() {
return master.isConnected();
}
public void close() {
master.destroy();
}
}
\ No newline at end of file
... ...
... ... @@ -35,7 +35,7 @@ public class ModbusMasterMessage {
/**
* 创建或获取 ModbusMaster (线程安全)
*/
public static ModbusMaster createMaster(String id) throws Exception {
public static ModbusMaster getMaster(String id) throws Exception {
ModbusMaster master = masterCache.get(id);
if (master != null && master.isConnected()) {
return master;
... ... @@ -58,7 +58,7 @@ public class ModbusMasterMessage {
// 创建新 master
ModbusMaster newMaster = selectMaster(id);
// newMaster.setIoLog(new MyIOLog(new File("logs/modbus-" + id + ".log")));
newMaster.setIoLog(new MyIOLog(new File("/app/logs/modbus-" + id + ".log")));
newMaster.init();
masterCache.put(id, newMaster);
... ...
... ... @@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
public class CollectPlcDataTask {
protected static final Logger logger = LoggerFactory.getLogger(CollectPlcDataTask.class);
private static final int maxDataLenth = 30;
private static final int maxDataLenth = 100;
public void collect(MqttService mqttService) {
ScheduledThreadPool.scheduler.scheduleAtFixedRate(() -> {
try {
... ... @@ -51,44 +51,49 @@ public class CollectPlcDataTask {
}
}
private void pubMqttData(MqttService mqttService, String plcId,CachPlcConfig cachPlcConfig) throws Exception
{
private void pubMqttData(MqttService mqttService, String plcId, CachPlcConfig cachPlcConfig) throws Exception {
Map<String, PlcPoint> map = cachPlcConfig.getPlcMap();
List<PlcPoint> plcPoints = new ArrayList<>();
int dataLenth = 1 ;
for (String system : map.keySet())
{
PlcPoint plcPoint = map.get(system);
int count = 0;
for (PlcPoint plcPoint : map.values()) {
plcPoints.add(plcPoint);
dataLenth++;
if (dataLenth == maxDataLenth)
{
if(!subMqttData(mqttService, plcId, plcPoints))
{
plcPoints.clear();
break;
count++;
if (count == maxDataLenth) {
boolean success = subMqttData(mqttService, plcId, plcPoints);
System.out.println("plc " + plcId + " 发送数据 " + plcPoints.size() + " 条");
if (!success) {
// 如果失败,可以选择重试或者丢弃,但不应该 break 掉后续数据
System.err.println("plc " + plcId + " 数据发送失败,本批次丢弃");
}
System.out.println("plc "+plcId+" 发送数据 "+plcPoints.size()+" 条,等待1s接着发送");
dataLenth = 1;
plcPoints.clear();
// 重置计数器和列表
count = 0;
plcPoints = new ArrayList<>();
try {
Thread.sleep(1000l);
Thread.sleep(1000L); // 控制发送速率
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 正确的中断处理
throw new RuntimeException(e);
}
}
}
if (plcPoints.size() > 0)
{
subMqttData(mqttService, plcId, plcPoints);
System.out.println("plc "+plcId+" 发送数据 "+plcPoints.size()+" 条");
// 处理剩余未满一批的数据
if (!plcPoints.isEmpty()) {
boolean success = subMqttData(mqttService, plcId, plcPoints);
logger.info("plc " + plcId + " 发送数据 " + plcPoints.size() + " 条");
if (!success) {
logger.info("plc " + plcId + " 数据发送失败,本批次丢弃");
}
}
}
private boolean subMqttData(MqttService mqttService, String plcId, List<PlcPoint> plcPoints)
{
//通知
... ...