作者 钟来

优化终端bug

@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject; @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject;
4 import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig; 4 import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig;
5 import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter; 5 import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter;
6 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite; 6 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite;
  7 +import com.zhonglai.luhui.device.modbus.terminal.modbus.ModbusMasterMessage;
  8 +import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.Message;
7 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint; 9 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
8 import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic; 10 import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic;
9 import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService; 11 import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService;
@@ -30,16 +32,20 @@ public class PutTopic extends TopicFactoryAdapter { @@ -30,16 +32,20 @@ public class PutTopic extends TopicFactoryAdapter {
30 JSONObject plcCommand = jsonObject.getJSONObject(key); 32 JSONObject plcCommand = jsonObject.getJSONObject(key);
31 String id = key; 33 String id = key;
32 List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand); 34 List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand);
  35 + Modbus4jWrite modbus4jWrite = null;
33 try { 36 try {
34 - new Modbus4jWrite(id).batchWrite(plcPoints,true); 37 + modbus4jWrite = new Modbus4jWrite(id);
  38 + modbus4jWrite.batchWrite(plcPoints,true);
35 } catch (Exception e) { 39 } catch (Exception e) {
  40 + if(null != modbus4jWrite)
  41 + {
  42 + ModbusMasterMessage.closeMaster(id); // 销毁旧连接
  43 + }
36 logger.error("写plc异常",e); 44 logger.error("写plc异常",e);
37 } 45 }
38 } 46 }
39 try { 47 try {
40 - JSONObject rJsonObject = new JSONObject();  
41 - rJsonObject.put("result",1);  
42 - mqttService.publish("PUT_REQ/"+topicDto.getTime(),rJsonObject.toJSONString()); 48 + mqttService.publish("PUT_REQ/"+topicDto.getTime(),JSONObject.toJSONString(new Message(1,"操作成功",jsonObject)));
43 } catch (MqttException e) { 49 } catch (MqttException e) {
44 logger.error("饭hi结果异常",e); 50 logger.error("饭hi结果异常",e);
45 } 51 }
@@ -5,6 +5,7 @@ import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig; @@ -5,6 +5,7 @@ import com.zhonglai.luhui.device.modbus.terminal.config.InitPlcConfig;
5 import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter; 5 import com.zhonglai.luhui.device.modbus.terminal.data.TopicFactoryAdapter;
6 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jRead; 6 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jRead;
7 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite; 7 import com.zhonglai.luhui.device.modbus.terminal.modbus.Modbus4jWrite;
  8 +import com.zhonglai.luhui.device.modbus.terminal.modbus.ModbusMasterMessage;
8 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint; 9 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
9 import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic; 10 import com.zhonglai.luhui.device.mqtt.terminal.jar.dto.Topic;
10 import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService; 11 import com.zhonglai.luhui.device.mqtt.terminal.jar.mqtt.MqttService;
@@ -33,11 +34,17 @@ public class ReadTopic extends TopicFactoryAdapter { @@ -33,11 +34,17 @@ public class ReadTopic extends TopicFactoryAdapter {
33 String plcCommand = jsonObject.getString(key); 34 String plcCommand = jsonObject.getString(key);
34 String id = key; 35 String id = key;
35 List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand); 36 List<PlcPoint> plcPoints = getPlcPoints(id, plcCommand);
  37 + Modbus4jRead modbus4jRead = null;
36 try { 38 try {
37 - Map<String, Object> map = new Modbus4jRead(id).batchRead(plcPoints,true); 39 + modbus4jRead = new Modbus4jRead(id);
  40 + Map<String, Object> map = modbus4jRead.batchRead(plcPoints,true);
38 rJsonObject.put(key, map); 41 rJsonObject.put(key, map);
39 } catch (Exception e) { 42 } catch (Exception e) {
40 logger.error("读plc异常",e); 43 logger.error("读plc异常",e);
  44 + if(null != modbus4jRead)
  45 + {
  46 + ModbusMasterMessage.closeMaster(id); // 销毁旧连接
  47 + }
41 return; 48 return;
42 } 49 }
43 } 50 }
@@ -9,6 +9,9 @@ import com.serotonin.modbus4j.exception.ModbusInitException; @@ -9,6 +9,9 @@ import com.serotonin.modbus4j.exception.ModbusInitException;
9 import com.serotonin.modbus4j.exception.ModbusTransportException; 9 import com.serotonin.modbus4j.exception.ModbusTransportException;
10 import com.serotonin.modbus4j.locator.BaseLocator; 10 import com.serotonin.modbus4j.locator.BaseLocator;
11 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint; 11 import com.zhonglai.luhui.device.modbus.terminal.modbus.dto.PlcPoint;
  12 +import com.zhonglai.luhui.device.modbus.terminal.task.CollectPlcDataTask;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
12 15
13 import java.io.File; 16 import java.io.File;
14 import java.util.HashMap; 17 import java.util.HashMap;
@@ -24,10 +27,12 @@ import java.util.Map; @@ -24,10 +27,12 @@ import java.util.Map;
24 */ 27 */
25 public class Modbus4jRead { 28 public class Modbus4jRead {
26 29
27 - private ModbusMaster master; 30 + private static final Logger logger = LoggerFactory.getLogger(Modbus4jRead.class);
  31 +
  32 + private String id;
28 33
29 public Modbus4jRead(String id) throws Exception { 34 public Modbus4jRead(String id) throws Exception {
30 - this.master = ModbusMasterMessage.createMaster(id); 35 + this.id = id;
31 } 36 }
32 37
33 /** 38 /**
@@ -61,7 +66,13 @@ public class Modbus4jRead { @@ -61,7 +66,13 @@ public class Modbus4jRead {
61 batch.setContiguousRequests(false); 66 batch.setContiguousRequests(false);
62 67
63 // 发送批量请求 68 // 发送批量请求
64 - BatchResults<String> results = master.send(batch); 69 + BatchResults<String> results = null;
  70 + try {
  71 + results = ModbusMasterMessage.getMaster( id).send(batch);
  72 + } catch (Exception e) {
  73 + logger.error("批量读取点位异常", e);
  74 + return null;
  75 + }
65 76
66 // 转换成 JSON 对象 77 // 转换成 JSON 对象
67 Map<String, Object> jsonMap = new HashMap<>(); 78 Map<String, Object> jsonMap = new HashMap<>();
@@ -30,11 +30,11 @@ import java.util.List; @@ -30,11 +30,11 @@ import java.util.List;
30 * 30 *
31 */ 31 */
32 public class Modbus4jWrite { 32 public class Modbus4jWrite {
33 - static Log log = LogFactory.getLog(Modbus4jWrite.class);  
34 - private ModbusMaster master; 33 + private static Log log = LogFactory.getLog(Modbus4jWrite.class);
  34 + private String id;
35 35
36 public Modbus4jWrite(String id) throws Exception { 36 public Modbus4jWrite(String id) throws Exception {
37 - this.master = ModbusMasterMessage.createMaster(id); 37 + this.id = id;
38 } 38 }
39 39
40 40
@@ -116,7 +116,12 @@ public class Modbus4jWrite { @@ -116,7 +116,12 @@ public class Modbus4jWrite {
116 } 116 }
117 117
118 // 设置值 118 // 设置值
119 - master.setValue(locator, value); 119 + try {
  120 + ModbusMasterMessage.getMaster(id).setValue(locator, value);
  121 + } catch (Exception e) {
  122 + log.error("写入失败",e);
  123 + return;
  124 + }
120 log.info("写入成功: " + point.getName() + " = " + point.getValue()); 125 log.info("写入成功: " + point.getName() + " = " + point.getValue());
121 } 126 }
122 127
@@ -129,11 +134,4 @@ public class Modbus4jWrite { @@ -129,11 +134,4 @@ public class Modbus4jWrite {
129 writePoint(plcPoint, zeroBasedAddress); 134 writePoint(plcPoint, zeroBasedAddress);
130 } 135 }
131 } 136 }
132 -  
133 - public boolean isConnected() {  
134 - return master.isConnected();  
135 - }  
136 - public void close() {  
137 - master.destroy();  
138 - }  
139 } 137 }
@@ -35,7 +35,7 @@ public class ModbusMasterMessage { @@ -35,7 +35,7 @@ public class ModbusMasterMessage {
35 /** 35 /**
36 * 创建或获取 ModbusMaster (线程安全) 36 * 创建或获取 ModbusMaster (线程安全)
37 */ 37 */
38 - public static ModbusMaster createMaster(String id) throws Exception { 38 + public static ModbusMaster getMaster(String id) throws Exception {
39 ModbusMaster master = masterCache.get(id); 39 ModbusMaster master = masterCache.get(id);
40 if (master != null && master.isConnected()) { 40 if (master != null && master.isConnected()) {
41 return master; 41 return master;
@@ -58,7 +58,7 @@ public class ModbusMasterMessage { @@ -58,7 +58,7 @@ public class ModbusMasterMessage {
58 58
59 // 创建新 master 59 // 创建新 master
60 ModbusMaster newMaster = selectMaster(id); 60 ModbusMaster newMaster = selectMaster(id);
61 -// newMaster.setIoLog(new MyIOLog(new File("logs/modbus-" + id + ".log"))); 61 + newMaster.setIoLog(new MyIOLog(new File("/app/logs/modbus-" + id + ".log")));
62 newMaster.init(); 62 newMaster.init();
63 63
64 masterCache.put(id, newMaster); 64 masterCache.put(id, newMaster);
@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit; @@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
24 public class CollectPlcDataTask { 24 public class CollectPlcDataTask {
25 protected static final Logger logger = LoggerFactory.getLogger(CollectPlcDataTask.class); 25 protected static final Logger logger = LoggerFactory.getLogger(CollectPlcDataTask.class);
26 26
27 - private static final int maxDataLenth = 30; 27 + private static final int maxDataLenth = 100;
28 public void collect(MqttService mqttService) { 28 public void collect(MqttService mqttService) {
29 ScheduledThreadPool.scheduler.scheduleAtFixedRate(() -> { 29 ScheduledThreadPool.scheduler.scheduleAtFixedRate(() -> {
30 try { 30 try {
@@ -51,44 +51,49 @@ public class CollectPlcDataTask { @@ -51,44 +51,49 @@ public class CollectPlcDataTask {
51 } 51 }
52 } 52 }
53 53
54 - private void pubMqttData(MqttService mqttService, String plcId,CachPlcConfig cachPlcConfig) throws Exception  
55 - { 54 + private void pubMqttData(MqttService mqttService, String plcId, CachPlcConfig cachPlcConfig) throws Exception {
56 Map<String, PlcPoint> map = cachPlcConfig.getPlcMap(); 55 Map<String, PlcPoint> map = cachPlcConfig.getPlcMap();
57 56
58 List<PlcPoint> plcPoints = new ArrayList<>(); 57 List<PlcPoint> plcPoints = new ArrayList<>();
59 58
60 - int dataLenth = 1 ;  
61 - for (String system : map.keySet())  
62 - {  
63 - PlcPoint plcPoint = map.get(system); 59 + int count = 0;
  60 + for (PlcPoint plcPoint : map.values()) {
64 plcPoints.add(plcPoint); 61 plcPoints.add(plcPoint);
65 - dataLenth++;  
66 - if (dataLenth == maxDataLenth)  
67 - {  
68 - if(!subMqttData(mqttService, plcId, plcPoints))  
69 - {  
70 - plcPoints.clear();  
71 - break; 62 + count++;
  63 +
  64 + if (count == maxDataLenth) {
  65 + boolean success = subMqttData(mqttService, plcId, plcPoints);
  66 + System.out.println("plc " + plcId + " 发送数据 " + plcPoints.size() + " 条");
  67 +
  68 + if (!success) {
  69 + // 如果失败,可以选择重试或者丢弃,但不应该 break 掉后续数据
  70 + System.err.println("plc " + plcId + " 数据发送失败,本批次丢弃");
72 } 71 }
73 - System.out.println("plc "+plcId+" 发送数据 "+plcPoints.size()+" 条,等待1s接着发送");  
74 - dataLenth = 1;  
75 - plcPoints.clear(); 72 +
  73 + // 重置计数器和列表
  74 + count = 0;
76 plcPoints = new ArrayList<>(); 75 plcPoints = new ArrayList<>();
  76 +
77 try { 77 try {
78 - Thread.sleep(1000l); 78 + Thread.sleep(1000L); // 控制发送速率
79 } catch (InterruptedException e) { 79 } catch (InterruptedException e) {
  80 + Thread.currentThread().interrupt(); // 正确的中断处理
80 throw new RuntimeException(e); 81 throw new RuntimeException(e);
81 } 82 }
82 } 83 }
83 } 84 }
84 85
85 - if (plcPoints.size() > 0)  
86 - {  
87 - subMqttData(mqttService, plcId, plcPoints);  
88 - System.out.println("plc "+plcId+" 发送数据 "+plcPoints.size()+" 条"); 86 + // 处理剩余未满一批的数据
  87 + if (!plcPoints.isEmpty()) {
  88 + boolean success = subMqttData(mqttService, plcId, plcPoints);
  89 + logger.info("plc " + plcId + " 发送数据 " + plcPoints.size() + " 条");
  90 + if (!success) {
  91 + logger.info("plc " + plcId + " 数据发送失败,本批次丢弃");
  92 + }
89 } 93 }
90 } 94 }
91 95
  96 +
92 private boolean subMqttData(MqttService mqttService, String plcId, List<PlcPoint> plcPoints) 97 private boolean subMqttData(MqttService mqttService, String plcId, List<PlcPoint> plcPoints)
93 { 98 {
94 //通知 99 //通知