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;
|
}
|
}
|
}
|
}
|
}
|