package com.chinaztt.mes.docx.handler; import com.fazecast.jSerialComm.SerialPort; import com.fazecast.jSerialComm.SerialPortDataListener; import com.fazecast.jSerialComm.SerialPortEvent; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @Slf4j @Component public class SerialPortListener { // 串口核心对象 private static SerialPort serialPort; // 定义缓冲区,暂存零散数据 private static final StringBuilder dataBuffer = new StringBuilder(); // 定义数据结束标志 private static final String END_MARK = "g"; public List dataList = new ArrayList<>(6); private static final int MAX_COUNT = 6; @Value("${serialPort.listenName}") public String listenName; // 标记监听是否运行 private volatile boolean isListening = false; public void serialPortDataListener(){ // 双重校验锁,避免重复启动 if (isListening) { log.warn("串口 {} 监听已启动,无需重复执行", listenName); return; } synchronized (this) { if (isListening) { return; } isListening = true; } // 2. 选择目标串口 String targetPortName = listenName; serialPort = SerialPort.getCommPort(targetPortName); // 3. 配置串口参数(需与设备端一致) serialPort.setBaudRate(9600); // 波特率 serialPort.setNumDataBits(8); // 数据位 serialPort.setNumStopBits(1); // 停止位 serialPort.setParity(SerialPort.NO_PARITY); // 校验位(无校验) serialPort.setFlowControl(SerialPort.NO_PARITY); // 关闭流控 serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1000, 0); // 读取超时 // 4. 打开串口 if (serialPort.openPort()) { log.info("串口打开成功:{}",targetPortName); } else { log.error("串口打开失败!请检查串口是否被占用或名称是否正确"); isListening = false; return; } // 5. 注册串口数据监听器(异步读取,避免阻塞主线程) try { serialPort.addDataListener(new SerialPortDataListener() { // 指定监听的事件类型:数据可用时触发 @Override public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; } // 数据可用时的处理逻辑 @Override public void serialEvent(SerialPortEvent event) { if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) { // 读取缓冲区中的所有字节 byte[] buffer = new byte[serialPort.bytesAvailable()]; int readBytes = serialPort.readBytes(buffer, buffer.length); if (readBytes > 0) { // 把本次收到的零散数据转成字符串,追加到缓冲区 String received = new String(buffer, 0, readBytes, StandardCharsets.UTF_8); dataBuffer.append(received); // 检查缓冲区是否包含“结束标志”,循环处理所有完整数据 int endIndex = dataBuffer.indexOf(END_MARK); while (endIndex != -1) { // 提取“开头到结束标志”的完整数据 String completeData = dataBuffer.substring(0, endIndex).replace(" ", "").replace("\n",""); // 打印/处理合并后的完整数据 double parseDouble = Double.parseDouble(completeData); log.info("接收到的数据-->{}",parseDouble); if(dataList.size()