package com.zy.core.thread; import com.alibaba.fastjson.JSONObject; import com.core.common.Cools; import com.core.common.DateUtils; import com.zy.core.Slave; import com.zy.core.ThreadHandler; import com.zy.core.cache.OutputQueue; import com.rfid.uhf288.Device; import com.zy.utils.News; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.Date; /** * RFID读写器线程 * 基于UHF288设备,支持串口和网络连接 * Created by chen.lin on 2026/01/10 */ @Data @Slf4j public class RFIDThread implements Runnable, ThreadHandler { private Slave slave; private StringBuffer rfid = new StringBuffer(); private String lastRfid = ""; private Device reader; private int portHandle = -1; private byte[] comAddr = new byte[1]; private boolean isConnected = false; private String connectionType = ""; // "COM" 或 "NET" // 连接参数 private Integer comPort; // 串口号(如果使用串口) private Byte baudRate; // 波特率(如果使用串口) private String ipAddress; // IP地址(如果使用网络) private Integer netPort; // 网络端口(如果使用网络) public RFIDThread(Slave slave) { this.slave = slave; try { reader = new Device(); comAddr[0] = (byte)255; // 默认地址0xFF } catch (Exception e) { log.error("RFID设备初始化失败", e); } } public String getRfid() { return rfid.toString(); } public void setRfid(String rfid) { this.rfid.delete(0, this.rfid.length()); this.rfid.append(rfid); if(!Cools.isEmpty(rfid) && !lastRfid.equals(rfid)) { News.info("RFID"+" - 1"+" - {}号RFID读写器,检索数据:{}", slave.getId(), this.rfid); lastRfid = rfid; JSONObject jsonObject = new JSONObject(); jsonObject.put("time", DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F)); jsonObject.put("rfid", rfid); if (OutputQueue.RFID.size() >= 32) { OutputQueue.RFID.poll(); } OutputQueue.RFID.offer(jsonObject); } } @Override public boolean connect() { if (isConnected) { log.warn("RFID设备已连接,无需重复连接"); return true; } boolean result = false; try { // 优先尝试网络连接(如果配置了IP) if (!Cools.isEmpty(slave.getIp()) && slave.getPort() != null) { result = connectNetwork(slave.getIp(), slave.getPort()); if (result) { connectionType = "NET"; JSONObject connMsg = new JSONObject(); connMsg.put("time", DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F)); connMsg.put("message", MessageFormat.format("RFID网络连接成功 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort())); OutputQueue.RFID.offer(connMsg); log.info("RFID网络连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); return true; } } // 如果网络连接失败,尝试串口连接 // 注意:串口连接需要额外的配置参数(串口号和波特率) // 这里假设可以通过某种方式获取,或者使用默认值 if (comPort == null) { comPort = 3; // 默认COM3 } if (baudRate == null) { baudRate = (byte)3; // 默认57600bps } result = connectComPort(comPort, baudRate); if (result) { connectionType = "COM"; JSONObject connMsg = new JSONObject(); connMsg.put("time", DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F)); connMsg.put("message", MessageFormat.format("RFID串口连接成功 ===>> [id:{0}] [port:COM{1}] [baud:{2}]", slave.getId(), comPort, getBaudRateName(baudRate))); OutputQueue.RFID.offer(connMsg); log.info("RFID串口连接成功 ===>> [id:{}] [port:COM{}] [baud:{}]", slave.getId(), comPort, getBaudRateName(baudRate)); return true; } } catch (Exception e) { log.error("RFID连接失败", e); JSONObject connMsg = new JSONObject(); connMsg.put("time", DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F)); connMsg.put("message", MessageFormat.format("RFID连接失败!!! ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort())); OutputQueue.RFID.offer(connMsg); } return false; } /** * 串口连接 */ private boolean connectComPort(int port, byte baud) { try { int[] portHandleArray = new int[1]; int result = reader.OpenComPort(port, comAddr, baud, portHandleArray); if (result == 0) { portHandle = portHandleArray[0]; isConnected = true; return true; } else { log.error("RFID串口连接失败,错误码: {}", result); return false; } } catch (Exception e) { log.error("RFID串口连接异常", e); return false; } } /** * 网络连接 */ private boolean connectNetwork(String ipAddr, int port) { try { int[] portHandleArray = new int[1]; int result = reader.OpenNetPort(port, ipAddr, comAddr, portHandleArray); if (result == 0) { portHandle = portHandleArray[0]; isConnected = true; return true; } else { log.error("RFID网络连接失败,错误码: {}", result); return false; } } catch (Exception e) { log.error("RFID网络连接异常", e); return false; } } /** * 读取RFID标签 */ private void readTags() { if (!isConnected || portHandle < 0) { return; } try { byte qValue = 4; // Q值,推荐4 byte session = 0; // Session值,推荐0 byte scanTime = 10; // 扫描时间,10*100ms=1秒 byte maskMem = 2; // EPC区 byte[] maskAdr = new byte[2]; byte maskLen = 0; byte[] maskData = new byte[256]; byte maskFlag = 0; // 不使用掩码 byte adrTID = 0; byte lenTID = 6; byte tidFlag = 0; // 0-读取EPC,1-读取TID byte target = 0; byte inAnt = (byte)0x81; byte fastFlag = 0; byte[] pEPCList = new byte[20000]; byte[] ant = new byte[1]; int[] totallen = new int[1]; int[] cardNum = new int[1]; // 清空数组 java.util.Arrays.fill(pEPCList, (byte)0); totallen[0] = 0; cardNum[0] = 0; int result = reader.Inventory_G2(comAddr, qValue, session, maskMem, maskAdr, maskLen, maskData, maskFlag, adrTID, lenTID, tidFlag, target, inAnt, scanTime, fastFlag, pEPCList, ant, totallen, cardNum, portHandle); // 解析标签数据 if (cardNum[0] > 0 && totallen[0] > 0) { int offset = 0; for (int i = 0; i < cardNum[0]; i++) { if (offset + 1 >= totallen[0]) break; byte epcLen = pEPCList[offset]; offset++; if (offset + epcLen > totallen[0]) break; byte[] epcBytes = new byte[epcLen]; System.arraycopy(pEPCList, offset, epcBytes, 0, epcLen); offset += epcLen; // RSSI和天线信息 byte rssi = 0; byte antenna = 0; if (offset < totallen[0]) { rssi = pEPCList[offset]; offset++; } if (offset < totallen[0]) { antenna = pEPCList[offset]; offset++; } String epcHex = bytesToHex(epcBytes); // 只取EPC的一部分(类似参考项目中的处理方式) if (epcHex.length() >= 24) { epcHex = epcHex.substring(14, 24); } setRfid(epcHex); // 只处理第一个标签 break; } } } catch (Exception e) { log.error("RFID读取标签异常", e); } } /** * 字节数组转十六进制字符串 */ private String bytesToHex(byte[] bytes) { if (bytes == null) return ""; StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b & 0xFF)); } return sb.toString(); } /** * 获取波特率名称 */ private String getBaudRateName(byte baud) { String[] names = {"9600", "19200", "38400", "57600", "115200", "230400", "460800", "921600"}; int index = baud & 0xFF; if (index >= 0 && index < names.length) { return names[index]; } return String.valueOf(baud); } @Override public void close() { if (isConnected && portHandle >= 0) { try { if ("COM".equals(connectionType)) { reader.CloseSpecComPort(portHandle); } else if ("NET".equals(connectionType)) { reader.CloseNetPort(portHandle); } isConnected = false; portHandle = -1; connectionType = ""; log.info("RFID连接已关闭 ===>> [id:{}]", slave.getId()); } catch (Exception e) { log.error("RFID关闭连接异常", e); } } } @Override public void run() { connect(); while (true) { try { if (isConnected) { readTags(); } else { // 如果未连接,尝试重连 connect(); } Thread.sleep(300); } catch (Exception e) { log.error("RFID线程运行异常", e); try { Thread.sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } } }