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; @Setter private Consumer eventConsumer; @Setter private Consumer 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:{}", ip, port, readerType, readerLogOn_Off); reader = new CReader(ip, port, readerType, readerLogOn_Off); int conn = reader.Connect(); if (conn != 0) { log.error("连接UF3设备失败,返回码={}", conn); return; } log.info("UF3 Reader设备连接成功:{}:{}", ip, props.getPort()); //0x00关闭蜂鸣器,0x01打开蜂鸣器 reader.SetBeepNotification(0x00); ReaderParameter param = new ReaderParameter(); try { param.SetAntenna(0x09); 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()); } log.info("已停止并断开UF3设备连接"); } } public boolean isOnline() { return reader != null; } @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"); } } }