6.3 KiB
6.3 KiB
RFIDManager 实现方案
概述
当前项目中的RFID功能通过__RFID_CARD宏控制,该宏通过条件编译启用或禁用RFID相关代码。这种方法在可维护性、测试和运行时灵活性方面存在局限。为了解决这些问题,我们建议引入RFIDManager类,该类封装所有RFID操作,提供更清洁、更模块化的设计。
RFIDManager将处理RFID初始化、数据读取和验证,仅通过QT信号通知外部卡片检测事件,让外部组件(如InkJetPrinter)负责具体的处理逻辑,替换代码库中分散的#ifdef __RFID_CARD块。
目标
- 封装:将RFID逻辑集中到一个类中。
- 运行时控制:允许在运行时而不是编译时启用/禁用RFID功能。
- 可维护性:通过移除预处理器指令简化代码。
- 可扩展性:更容易添加新RFID功能或修改现有功能。
- 测试:无需重新编译即可对RFID组件进行单元测试。
类设计
RFIDManager 类
class RFIDManager : public QObject {
Q_OBJECT
public:
RFIDManager(QObject* parent = nullptr);
~RFIDManager();
// 初始化
bool initialize();
// 主处理循环(定期调用,例如每300ms)
void processRFID();
// 启用/禁用RFID功能
void setEnabled(bool enabled);
bool isEnabled() const;
// 配置
void setValidationDelay(int seconds); // 例如,5秒用于卡片稳定性
void setSerialPort(const QString& port); // 例如,"/dev/ttyAS1"
void setBaudRate(int baudRate); // 例如,9600
// 数据访问
QString getLastCardData() const;
bool isCardPresent() const;
signals:
// 通知外部卡片检测到
void cardDetected(QString cardType); // cardType: 'A', 'B', 'C' 等
private:
// 私有方法
void readRFIDData();
void validateCardPresence();
// 成员变量
bool m_enabled;
int m_validationDelay; // 以秒为单位
QString m_serialPort;
int m_baudRate;
QString m_lastCardData;
bool m_cardPresent;
int m_stableCount; // 验证延迟计数器
QString m_previousCardData; // 检测卡片变化
// 依赖项(内部注入或创建)
DevOp* m_devOp; // 用于串口通信
};
关键方法
initialize():设置串口通信并初始化参数。固定串口名为"/dev/ttyAS1",比特率9600等processRFID():主方法,在定时器循环中调用。读取数据、验证卡片存在,如果验证通过则发射cardDetected信号。setEnabled(bool):RFID功能的运行时切换。setValidationDelay(int):配置卡片验证延迟(例如,5秒)。readRFIDData():与DevOp接口读取串口数据。validateCardPresence():通过计数连续稳定读取实现延迟逻辑,如果延迟满足则发射信号。
集成计划
步骤1:创建RFIDManager类
- 在项目源目录中创建
RFIDManager.h和RFIDManager.cpp。 - 按照上述大纲实现类。
步骤2:在InkJetPrinter.cpp中替换宏使用
- 在
InkJetPrinter.cpp中移除#ifdef __RFID_CARD块。 - 将
RFIDManager实例添加为成员变量。 - 在构造函数中初始化
RFIDManager,并连接信号到槽函数。 - 在
timerHandler()中,将RFID逻辑替换为调用rfidManager.processRFID()。 - 添加槽函数(如
onCardDetected(QString cardType))来处理卡片检测逻辑,包括显示对话框和更新参数。
在InkJetPrinter.cpp中的示例更改:
// 在构造函数中
rfidManager = new RFIDManager(this);
connect(rfidManager, &RFIDManager::cardDetected, this, &InkJetPrinter::onCardDetected);
// 在timerHandler中
if (rfidManager->isEnabled()) {
rfidManager->processRFID();
}
// 新增槽函数
void InkJetPrinter::onCardDetected(QString cardType) {
// 处理卡片逻辑:显示对话框、更新SysPara等
if (cardType == "A") {
// 处理墨卡
} else if (cardType == "B") {
// 处理维护卡
} else if (cardType == "C") {
// 处理其他卡
}
}
步骤3:更新DevOp.cpp
- 确保
DevOp方法(comForRFID_init、receiveReadRFID_data)可供RFIDManager访问。 - 可能使
DevOp成为单例,或通过依赖注入将其传递给RFIDManager。
步骤4:更新SysPara.h
- 确保
RFIDPara_t可供RFIDManager访问以进行参数更新。
步骤5:配置
- 将RFID设置添加到配置文件或UI中,允许运行时更改启用/禁用和设置延迟。
步骤6:移除宏
- 完全集成后,从
myinclude.h中移除__RFID_CARD宏并清理任何剩余的条件代码。
验证延迟实现
为了防止误操作,实现5秒延迟:
- 跟踪具有相同卡片数据的连续读取。
- 仅在~17次稳定读取后发射
cardDetected信号(300ms * 17 ≈ 5.1秒)。 - 如果卡片数据变化或消失,则重置计数器。
void RFIDManager::validateCardPresence() {
QString currentData = readRFIDData();
if (currentData == m_previousCardData && !currentData.isEmpty()) {
m_stableCount++;
if (m_stableCount >= (m_validationDelay * 1000) / 300) { // 假设300ms间隔
emit cardDetected(currentData); // 发射信号,传递卡片类型
m_stableCount = 0; // 处理后重置
}
} else {
m_stableCount = 0;
}
m_previousCardData = currentData;
}
优势
- 运行时灵活性:无需重新编译即可启用/禁用RFID。
- 更清洁的代码:逻辑中无预处理器指令混乱。
- 更好的测试:为单元测试模拟
RFIDManager。 - 模块化:更容易扩展或修改RFID功能。
- 错误处理:RFID操作的集中错误处理。
潜在挑战
- 依赖注入:确保
DevOp和SysPara正确注入或可访问。 - 线程安全:如果从定时器调用
processRFID(),确保线程安全。 - 向后兼容性:彻底测试以确保功能无回归。
测试计划
RFIDManager方法的单元测试。- 与
InkJetPrinter的集成测试。 - 使用实际RFID硬件的手动测试,以验证延迟和检测。
时间表
- 第1周:设计并实现
RFIDManager类。 - 第2周:集成到
InkJetPrinter.cpp并测试。 - 第3周:更新配置并移除宏。
- 第4周:全面测试和文档。
此方案为将RFID功能重构为更可维护和灵活的系统提供了坚实基础。