package com.eternal.rfid.service;
|
|
import com.eternal.event.RfidReadEvent;
|
import com.eternal.monitor.vo.DeviceStatusVo;
|
import com.rfid.CReader;
|
import com.rfid.ReadTag;
|
import com.rfid.ReaderParameter;
|
import com.rfid.TagCallback;
|
import lombok.Getter;
|
import lombok.Setter;
|
import lombok.extern.slf4j.Slf4j;
|
import com.eternal.rfid.params.UF3ReaderConfig;
|
import org.springframework.context.ApplicationEvent;
|
|
import java.util.function.Consumer;
|
|
@Slf4j
|
public class UF3RFIDReader implements TagCallback {
|
@Getter
|
private final String readerKey;
|
|
@Getter
|
private final String readerTypeKey;
|
|
@Getter
|
private final String[] antennasKey;
|
|
@Getter
|
private final String antennaTypeKey;
|
|
@Getter
|
private int index;
|
|
private UF3ReaderConfig props;
|
private CReader reader;
|
|
@Getter
|
private String ip;
|
private int port;
|
private int readerType;
|
private int readerLogOn_Off;
|
private String mode;
|
private boolean isConnect = false;
|
|
@Setter
|
private Consumer<ApplicationEvent> eventConsumer;
|
|
@Setter
|
private Consumer<DeviceStatusVo> updateDeviceStatusConsumer;
|
|
public UF3RFIDReader(String readerKey, String readerTypeKey, String[] antennasKey, String antennaTypeKey) {
|
this.readerKey = readerKey;
|
this.readerTypeKey = readerTypeKey;
|
this.antennasKey = antennasKey;
|
this.antennaTypeKey = antennaTypeKey;
|
}
|
|
public void init(int index, UF3ReaderConfig params) {
|
this.index = index;
|
this.ip = params.getIp();
|
this.port = params.getPort();
|
this.readerType = params.getReadType();
|
this.readerLogOn_Off = params.getReadLogOn_Off();
|
this.mode = params.getMode();
|
this.props = params;
|
}
|
|
|
public void start() {
|
log.info("ip:{},port:{},readerType:{},log:{}", this.ip, this.port, this.readerType, this.readerLogOn_Off);
|
reader = new CReader(ip, port, readerType, readerLogOn_Off);
|
int conn = reader.Connect();
|
if (conn != 0) {
|
log.error("连接UF3设备失败,返回码={}", conn);
|
this.isConnect = false;
|
return;
|
}
|
log.info("UF3 Reader设备连接成功:{}:{}", ip, props.getPort());
|
this.isConnect = true;
|
//0x00关闭蜂鸣器,0x01打开蜂鸣器
|
reader.SetBeepNotification(0x00);
|
|
ReaderParameter param = new ReaderParameter();
|
try {
|
param.SetAntenna(0x09);
|
param.SetSession(0);
|
param.SetReadType(0);
|
reader.SetInventoryParameter(param);
|
} catch (Exception e) {
|
log.warn("设置读参数时发生异常:{}", e.getMessage());
|
}
|
|
applyPowerConfig();
|
|
reader.SetCallBack(this);
|
startRead();
|
}
|
|
public void startRead() {
|
int start = reader.StartRead();
|
if (start != 0) {
|
log.error("开启读失败,返回码={}", start);
|
} else {
|
getAntennaPowers();
|
log.info("读流程已开启");
|
}
|
}
|
|
public void stopRead() {
|
if (reader != null) {
|
try {
|
reader.StopRead();
|
} catch (Exception e) {
|
log.warn("停止读过程异常:{}", e.getMessage());
|
}
|
}
|
}
|
|
public void disconnectReader() {
|
if (reader != null) {
|
|
try {
|
reader.DisConnect();
|
} catch (Exception e) {
|
log.warn("断开连接异常:{}", e.getMessage());
|
}
|
this.isConnect = false;
|
log.info("已停止并断开UF3设备连接");
|
}
|
}
|
|
public boolean isOnline() {
|
return reader != null && isConnect;
|
}
|
|
@Override
|
public void tagCallback(ReadTag tag) {
|
if (tag == null) {
|
return;
|
}
|
String memoryData = "";
|
if (mode.equals("user")) {
|
memoryData = readDataByEpcMask(tag.epcId, (byte) 3, (byte) 0000, (byte) 32, "00000000");
|
} else if (mode.equals("tid")) {
|
memoryData = readDataByEpcMask(tag.epcId, (byte) 2, (byte) 0000, (byte) 32, "00000000");
|
}
|
long timeInReader = System.currentTimeMillis();
|
long timeInPc = System.currentTimeMillis();
|
int ant = tag.antId;
|
String epc = tag.epcId;
|
float rssi = tag.rssi;
|
double phase = 0;
|
int doppler = 0;
|
|
RfidReadEvent rfidReadEvent = null;
|
if (mode.equals("tid")) {
|
rfidReadEvent = new RfidReadEvent(this, timeInReader, timeInPc, ant, epc, rssi, phase, doppler, 0L, 0, "", memoryData);
|
} else if (mode.equals("user")) {
|
rfidReadEvent = new RfidReadEvent(this, timeInReader, timeInPc, ant, epc, rssi, phase, doppler, 0L, 0, memoryData, "");
|
} else {
|
rfidReadEvent = new RfidReadEvent(this, timeInReader, timeInPc, ant, epc, rssi, phase, doppler, 0L, 0, "", "");
|
}
|
|
publishEvent(rfidReadEvent);
|
|
if (props.isRfidReaderReadLog()) {
|
log.info("标签: ip={} epc={} mem={} rssi={} ant={}",
|
tag.ipAddr, tag.epcId, tag.memId, tag.rssi, tag.antId);
|
if (!memoryData.isEmpty()) {
|
log.info("readDataByEpcMask 数据:{}", memoryData);
|
}
|
}
|
}
|
|
@Override
|
public void StopReadCallback() {
|
log.info("设备已停止读回调");
|
}
|
|
private void applyPowerConfig() {
|
String[] powers = props.getAntennasPower().split(",");
|
if (powers != null && powers.length >= 4) {
|
byte[] byAnt = new byte[4];
|
for (int i = 0; i < 4; i++) {
|
int p = Integer.parseInt(powers[i]);
|
if (p < 0) p = 0;
|
if (p > 33) p = 33;
|
byAnt[i] = (byte) p;
|
}
|
int ret = reader.SetRfPowerByAnt(byAnt);
|
if (ret == 0) {
|
log.info("已设置四天线功率: A1={} A2={} A3={} A4={}", byAnt[0] & 0xFF, byAnt[1] & 0xFF, byAnt[2] & 0xFF, byAnt[3] & 0xFF);
|
} else {
|
log.warn("按天线设置功率失败,返回码={}", ret);
|
}
|
}
|
}
|
|
/**
|
* EPC掩码读取
|
*
|
* @param epc EPC数据 (Mask)
|
* @param memBank 存储区 (0:Reserved, 1:EPC, 2:TID, 3:User)
|
* @param startAddr 起始地址 (Word) 起始地址都是从 0000 开始
|
* @param length 读取长度 (Word)
|
* @param password 访问密码 (8位16进制字符串)
|
* @return 读取到的数据
|
*/
|
public String readDataByEpcMask(String epc, byte memBank, byte startAddr, byte length, String password) {
|
if (reader == null) {
|
log.error("Reader未初始化");
|
return null;
|
}
|
try {
|
// 注意:调用此方法可能需要先停止自动读(StartRead),取决于SDK实现。
|
// 如果是在Inventory过程中调用,可能会失败或阻塞。
|
String data = reader.ReadDataByEPC(epc, memBank, startAddr, length, password);
|
// log.info("EPC掩码读取结果: epc={} mem={} addr={} len={} data={}", epc, memBank, startAddr, length, data);
|
return data;
|
} catch (Exception e) {
|
log.error("EPC掩码读取异常", e);
|
return null;
|
}
|
}
|
|
/**
|
* TID掩码读取
|
*
|
* @param tid TID数据 (Mask)
|
* @param memBank 存储区 (0:Reserved, 1:EPC, 2:TID, 3:User)
|
* @param startAddr 起始地址 (Word)
|
* @param length 读取长度 (Word)
|
* @param password 访问密码 (8位16进制字符串)
|
* @return 读取到的数据
|
*/
|
public String readDataByTidMask(String tid, byte memBank, byte startAddr, byte length, String password) {
|
if (reader == null) {
|
log.error("Reader未初始化");
|
return null;
|
}
|
try {
|
String data = reader.ReadDataByTID(tid, memBank, startAddr, length, password);
|
log.info("TID掩码读取结果: tid={} mem={} addr={} len={} data={}", tid, memBank, startAddr, length, data);
|
return data;
|
} catch (Exception e) {
|
log.error("TID掩码读取异常", e);
|
return null;
|
}
|
}
|
|
public int[] getAntennaPowers() {
|
if (reader == null) {
|
log.error("Reader未初始化");
|
return null;
|
}
|
byte[] byAnt = new byte[4];
|
int ret = reader.GetRfPowerByAnt(byAnt);
|
if (ret != 0) {
|
log.warn("查询天线功率失败,返回码={}", ret);
|
return null;
|
}
|
int[] powers = new int[4];
|
for (int i = 0; i < 4; i++) {
|
powers[i] = byAnt[i] & 0xFF;
|
}
|
log.info("当前四天线功率: A1={} A2={} A3={} A4={}", powers[0], powers[1], powers[2], powers[3]);
|
return powers;
|
}
|
|
private void publishEvent(ApplicationEvent event) {
|
if (eventConsumer != null) {
|
eventConsumer.accept(event);
|
} else {
|
log.error("{}", "No eventConsumer");
|
}
|
}
|
|
protected void updateDeviceStatus(DeviceStatusVo deviceStatusVo) {
|
if (updateDeviceStatusConsumer != null) {
|
updateDeviceStatusConsumer.accept(deviceStatusVo);
|
} else {
|
log.warn("updateDeviceStatusConsumer is null");
|
}
|
}
|
}
|