From 3b1b756f1a619e60b2243d28817c39e0a7a0cb0c Mon Sep 17 00:00:00 2001
From: senzhi <10983298651@qq.com>
Date: Wed, 21 Jan 2026 14:20:58 +0800
Subject: [PATCH] fix:修改项目为组件

---
 src/main/java/com/eternal/rfid/service/UF3RFIDReader.java |  282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 282 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/eternal/rfid/service/UF3RFIDReader.java b/src/main/java/com/eternal/rfid/service/UF3RFIDReader.java
new file mode 100644
index 0000000..cc125dc
--- /dev/null
+++ b/src/main/java/com/eternal/rfid/service/UF3RFIDReader.java
@@ -0,0 +1,282 @@
+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<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:{}", 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");
+        }
+    }
+}

--
Gitblit v1.9.3